MEGATRON

How this is built

Stack, data wiring, and how to point the panel at live Airtable.

currently: LIVE AIRTABLE

What you're looking at

The MEGATRON control panel — the command center for LVE's autonomous cold-outreach pipeline. MEGATRON discovers trade shows, scores them (timing → exhibitor count → warehouse proximity), scrapes and enriches every exhibitor into a scored lead, runs a 5-email sequence in Megan's voice, and detects replies and booked calls. The Attribution view traces that whole funnel; every win is tagged source: MEGATRON and traceable to its show and campaign.

Stack

Next.js 14 (App Router, server components) · Tailwind with a custom token system · Recharts for trends · Geist for UI, Geist Mono for every number. Light monochrome throughout: white surfaces, zinc hairlines, black reserved for emphasis — a booked call is the only solid-black element on any screen.

Data flows through one server-side module (lib/data.ts): live Airtable when a key is present, rich deterministic seed data otherwise. The API routes /api/shows, /api/exhibitors and /api/config keep the same response contract as the production panel.

Pointing it at live Airtable

One env var flips the whole panel from seed to live. Nothing else changes:

# Vercel → Project → Settings → Environment Variables
AIRTABLE_API_KEY=pat_xxx        # required — a read-scoped personal access token
AIRTABLE_BASE_ID=appccQu8ED41C4Som   # optional, this is the default

# table overrides (optional, these are the defaults)
AIRTABLE_SHOWS_TABLE=tblSlCLJDY4m5QKz3
AIRTABLE_LEADS_TABLE=tblnde3kiJD6dgyDL

The reader paginates the full tables server-side (the key never reaches the browser), caches for 60s, and binds to the exact production field names — Show Key, Outreach, Score Breakdown, Brand File, etc. If Airtable is unreachable it falls back to seed rather than rendering a dead panel.

One approximation in live mode: the trend chart buckets events by each lead's Updated timestamp (Airtable stores status, not an event log). Seed mode simulates a precise send/reply/book log. For exact live trends, point a small webhook at Smartlead/Calendly events — the production panel already receives both.

The funnel, mapped to data

Shows discovered      all SHOWS rows
Shows active          Pipeline Status = "Active"
Exhibitors scraped    all LEADS rows
Reachable leads       Score > 0        (no reachable contact → hard-gated to 0)
In outreach           Outreach ∈ {Queued, Sent, Replied, Booked}
Sent                  Outreach ∈ {Sent, Replied, Booked}
Replied ★             Outreach ∈ {Replied, Booked}
Booked  ★★            Outreach = "Booked"
Drop-off              Outreach ∈ {Bounced, Suppressed}

Per-show attribution groups leads by Show Key and counts wins — that's the ROI-by-show table on the dashboard.

Deploy notes

This is a standalone preview deployment — deliberately separate from the production control-panel project, whose webhook endpoints (/api/calendly-webhook, /api/smartlead-webhook) a running pipeline depends on. To migrate this UI into production: copy app/, components/ and lib/ over, keep the existing webhook + mutate routes untouched, and carry the tailwind.config.ts + globals.css token system.

Design system, briefly

Monochrome engineering-paper: white surfaces with zinc hairline borders (--floor → --booth → --booth-2), registration ticks crossing card corners, ink in four gray steps. Color is rationed to meaning — green and red exist only as deltas and failure states; conversion is carried by black: Replied takes the ink outline, Booked is the one solid-black chip in the interface. Charts render in textures (slatted bars, dashed lines) instead of hues. Numbers are always mono and tabular so nothing shifts as data updates.