All case studies
Portfolio demoMay 9, 2026

AI Lead Qualification and CRM Dispatch Platform

Inbound forms route through an OpenAI-backed qualifier that returns a typed score, signals matrix, estimated ARR, and a tier-appropriate follow-up email — then a deterministic dispatcher fans the lead out to HubSpot, Salesforce, Slack, and email with a full audit trail.
Next.js 16
React 19
shadcn/ui
Tailwind v4
Prisma
SQLite
OpenAI structured outputs
Zod
Recharts
Vercel

Business outcome. Sales teams stop spending half their morning triaging junk inbound. The qualifier scores every lead, captures the reasoning, and routes the strong ones into the CRM within seconds of form submission — with the audit trail your compliance and revops teams need. Hot leads see a Salesforce + Slack + HubSpot + email fan-out; cold leads land in self-serve nurture; the AE only sees what's worth their time.

Built for inbound-heavy B2B teams whose AEs lose hours to triage, whose sales ops keeps meaning to wire up an AI scorer, and whose finance team needs every routing decision logged.

Pipeline

Scroll to zoom · click-drag to pan · double-click to reset.

What's built

  • AI qualifier with structured outputs. OpenAI gpt-4o-mini, response_format: { type: "json_schema", strict: true }, so the API guarantees the response matches the schema. Zod is a second-line check against tampered or stale fields.
  • Ten-field extraction, not five. Score + confidence (0 to 1), 2 to 4 sentence audit-trail reasoning, urgency, recommended action, tags, a structured signals matrix across six categories (fit / budget / intent / urgency / authority / risk) where every claim ties to a quoted phrase, est. ARR anchored on size × budget, and a tone-matched follow-up email draft per tier.
  • Deterministic stub fallback. Same shape, derived from keyword heuristics over budget/size/urgency. Activates when OPENAI_API_KEY is unset or the call fails, so the dashboard always has data to render and the form never blocks on the AI.
  • Tier-driven CRM dispatch. Each integration adapter exports { shouldFire, deliver }. Hot fans out to Salesforce + Slack + HubSpot + email; Warm to HubSpot + nurture; Cold to self-serve. Every step writes a delivered | skipped | failed entry to the lead's integration log.
  • Auditable lead detail. Score + confidence + urgency + est. ARR header, "Why this score" reasoning, signals matrix with category icons and strength dots, AI-drafted follow-up with copy + mailto buttons, full activity timeline, status select, and rep notes.
  • Insights without recomputation. The AI insights page narrates pre-aggregated metrics (tag counts, service mix, industry conversion, MoM score delta) and never recomputes them. Same boundary as the qualifier: the LLM explains, the database calculates.
  • Single ingest entry point. lib/pipeline.ts:ingestLead is called by the public-form server action; any future REST or webhook endpoint hits the same function, so qualification + dispatch behave identically across channels.

Tradeoffs

  • Structured outputs over json_object. The API enforces the schema instead of just "valid JSON". Costs a few tokens of latency in negotiation, removes a class of failure modes, and lets the schema document itself for future model upgrades.
  • Stub fallback that mirrors shape. The demo never blocks on the model, but a quietly-stubbed lead is only distinguishable in the UI by the "Heuristic stub" badge. Watch aiSource, not pipeline uptime.
  • SQLite + JSON-encoded array columns. Zero-config for a demo. lib/db/lead.ts:hydrateLead is the single boundary that parses the JSON strings; consumers see real arrays. Swap to Postgres + native arrays when productionizing, and the application boundary doesn't move.
  • Mock CRM adapters with realistic logs. Each adapter records what it would have sent. The contract (IntegrationLogEntry) is what real adapters would return, so dashboards keep working when deliver() actually hits HubSpot/Salesforce/Slack APIs.

Live demo →