Portfolio · Case Study
Designed and built a production-grade CRM to replace HubSpot for a specialty retail brand — delivered in weeks using agentic AI development tooling throughout. The platform manages brands, retailers, and deal relationships through a configurable Kanban pipeline. An AI activity intelligence layer surfaces unlogged Gmail emails and Calendar meetings, pre-matched to stores and contacts. Field Notes — a companion mobile web app — lets field reps speak a note after a store visit; self-hosted Whisper STT and Claude Haiku extract structured activities and write them directly to the CRM. The CRM, analytics portal, and Field Notes share one PostgreSQL database with deliberate ownership contracts and separate Alembic migration tables.
Three apps share one PostgreSQL database. The Portal is the identity authority — it owns users, roles, and brands. The CRM reads those tables but never writes them. Field Notes authenticates via the same shared JWT secret and writes activities back through the CRM API. This deliberate shared-database architecture keeps reporting coherent without cross-app API calls for data that belongs to one layer.
alembic_version_crm for the CRM, alembic_version for the Portal. Neither migrates the other's tables.
Field Notes is built for speed in the field — a rep finishes a store visit and speaks a 10-second note. Whisper runs self-hosted on EC2 to avoid latency from cloud STT APIs. Claude Haiku extracts structured fields in a single forced tool call. The fuzzy vocab layer handles real-world speech errors: 'Marloe' becomes 'Marlowe & Co.', 'the edits' becomes 'The Edit'.
tool_choice: {type: tool, name: emit_structured_note}) — guarantees structured output every time; no prompt parsing.
Transcription + extraction + write: ~3–6s total · dominated by Whisper STT



A voice-first companion app: a rep speaks a note after a store visit and it lands in the CRM as a structured activity — no typing, no app-switching, and it works offline.
A one-screen sales performance review across every brand and retailer — the questions a head of sales actually asks, answered from live pipeline data.
A drag-and-drop Kanban of every deal across every stage — the working surface where reps move pipeline forward.
A chronological feed of every email, meeting, call, and note across the team — the system of record for what actually got done.
Every email and meeting on a record is summarized by Claude — a rolling account narrative plus per-thread recaps — so a rep walks into any conversation already caught up.
Unlogged Gmail and Calendar items are surfaced and context-matched to the right brand, retailer, contact, and deal — logging an activity becomes one click.
Every brand-to-retailer deal in one filterable view — distribution coverage at a glance.