Portfolio · Case Study

Diego S.
Diego S.
AI Engineering Full-Stack Build Agentic Development Specialty Retail
Education
Florida International University
BS · Computer Science
Florida International University
MBA · Marketing & E-Commerce
Pennsylvania State University
Master of Applied Statistics
Available now
Live · in production
Expert-VettedExpert-Vetted
Top RatedTop Rated
100%Job Success
Case Study
AI-Powered
Sales CRM
AI-Powered CRM Build
Specialty Retail
Weeks
Concept to production
2
AI features built in
3
Apps on shared database
01 · 11
Project overview
Key project facts
Platform
AI-Powered CRM (Custom Build)
Industry
Fashion · Specialty Retail
Engagement type
Product Build · Full-Stack
Status
In production · walkthrough on request (NDA)
Scope
CRM · Field Notes · Portal Integration
Technical stack
Python FastAPI SQLAlchemy PostgreSQL Alembic React TypeScript Vite shadcn/ui Anthropic Claude Whisper STT Gmail API Google Calendar OAuth2 GitHub Actions EC2 AWS
Engagement summary

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.

Weeks
Concept to Production
FastAPI + React platform built with agentic AI development tooling throughout
2
AI Features in Production
Email thread summarization · Activity suggestions from Gmail + Calendar
3
Apps on One Database
CRM · Analytics Portal · Field Notes share PostgreSQL via ownership contracts
02 · 11
Technical Design · AI Sales CRM
Platform Architecture
Shared-Database Multi-App Platform
Clients
React SPA
Production · HTTPS
Field Notes Mobile
Voice capture · Mobile web (PWA)
Analytics Portal
identity + analytics
Gmail Add-on
inbox sidebar
API Layer
CRM API
FastAPI · EC2 · nginx
Field Notes API
FastAPI · port 9300
Portal API
identity authority
JWT Auth
HS256 shared secret
GitHub Actions CI/CD
S3 → SSM → systemd
CRM Services
CRM Service
contacts · pipeline
Pipeline Service
deal stages
Activity Service
log · feed
SQLAlchemy ORM Alembic migrations alembic_version_crm
AI Services
Activity Suggestions
Gmail · Calendar → Claude
Email Summarization
Anthropic claude-haiku-4-5
Field Notes Extract
emit_structured_note tool
External APIs
Gmail API
OAuth2 per-user · Fernet tokens
Google Calendar
meeting import
Anthropic Claude
Haiku · tool_use
Whisper STT
self-hosted EC2 · faster-whisper
AWS Secrets Mgr
DB credentials
Data
PostgreSQL (shared)
Shared DB · RDS · alembic_version_crm
Portal identity tables
users · user_roles · brands (read-only from CRM)
CRM tables
crm_* owned by CRM migrations
Field Notes vocab
store · contact name index
Technical Approach

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.

Key Architectural Decisions
Shared DB, separate Alembic version tablesalembic_version_crm for the CRM, alembic_version for the Portal. Neither migrates the other's tables.
Identity ownership contract — Portal owns users/brands; CRM deep-links to Portal admin rather than duplicating user management.
Per-user OAuth token encryption — Gmail/Calendar tokens stored with Fernet symmetric encryption, not in plaintext.
03 · 11
Technical Design · Field Notes
Voice-to-CRM Pipeline
Whisper · Claude Haiku · Fuzzy Match
1
Mobile Input
React PWA
Tap-to-record on mobile · MediaRecorder API · audio/webm · sends to /api/transcribe
PWA · mobile-first
~0ms
2
Transcription
Self-Hosted Whisper
faster-whisper on EC2 Docker · base.en model · returns plain text transcript
faster-whisper
~2–4s
3
AI Parsing
Claude Haiku 4.5
tool_choice forced: emit_structured_note · extracts: activity_type, store_name, contact_name, subject, body, category, corrected_brand_name
emit_structured_note
~800ms
Tool output fields
activity_type store_name contact_name corrected_brand_name subject body
4
Name Resolution
Vocab Corrector
SequenceMatcher fuzzy match at 0.80 cutoff · exact-then-fuzzy for stores and contacts · brand override if corrected_brand_name set
0.80 threshold
~5ms
5
Routing
New vs. Known Store
If store matched → resolve relationship_id · if no match → mark new_prospect=true → routes to /api/crm/prospects (atomic 3-way insert)
prospect or activity
~10ms
6
Persistence
CRM API
POST /api/crm/activities or /api/crm/prospects · JWT auth · returns activity_id · rep sees confirmation
REST · JWT
~50ms total
Why This Stack

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'.

Key Decisions
Forced tool_use (tool_choice: {type: tool, name: emit_structured_note}) — guarantees structured output every time; no prompt parsing.
Self-hosted Whisper on EC2 — avoids cloud STT round-trip latency and keeps audio data off third-party services.
0.80 fuzzy cutoff — catches common voice transcription errors without false-positive matches between unrelated store names.
End-to-End Latency

Transcription + extraction + write: ~3–6s total · dominated by Whisper STT

04 · 11
Field Notes home — brand select and tap-to-record
1 · Record
Field Notes verification — AI-extracted activity
2 · Verify
Field Notes confirmation — note saved to CRM
3 · Confirm
AI-Powered Sales CRM · Mobile Companion
Field Notes

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.

How it works
Voice capture on-site
Record right after a visit. Offline-safe — the note buffers and auto-uploads when the rep reconnects.
Self-hosted Whisper STT
Transcribed on a private EC2 instance running faster-whisper — audio never leaves the client’s own infrastructure.
Claude structured extraction
Claude Haiku’s emit_structured_note tool parses the transcript into store, contact, activity type, and body — fuzzy-matched to real CRM records.
One-tap write-back
The rep reviews the extraction and submits; it writes straight to the CRM via the Portal API, ready for the next report.
React · FastAPI · faster-whisper (self-hosted) · Anthropic Claude Haiku · Shared-JWT auth Figures illustrative
05 · 11
Performance dashboard — win rate, sales cycle, win/loss anatomy
01 / 06 AI-Powered Sales CRM · Deliverable
Performance
Dashboard

A one-screen sales performance review across every brand and retailer — the questions a head of sales actually asks, answered from live pipeline data.

What this screen does
Headline diagnostics
Win rate, average sales cycle, deals advanced, and doors opened — the four numbers at the top of the review.
Win & loss anatomy
Won-vs-lost split, ranked loss reasons, and a sales-cycle histogram showing how long deals really take to close.
Configurable review period
Slice by Last 30 / 90 / 365 days, QTD, YTD, or a custom range — every metric recomputes against the chosen window.
React · ECharts · FastAPI · PostgreSQL · Anthropic Claude Figures illustrative
06 · 11
Kanban pipeline board — deals by stage with weighted forecast
02 / 06 AI-Powered Sales CRM · Deliverable
Pipeline Board

A drag-and-drop Kanban of every deal across every stage — the working surface where reps move pipeline forward.

What this screen does
Stage columns at a glance
Every deal grouped by stage (Qualified, Contacted, In Discussion, Product Trial, Meeting, Closed Won / Lost) with running counts and pipeline value.
Deal cards
Each card shows the retailer-brand pair, deal size, and assigned owner.
Drag-and-drop stage moves
Moving a card across columns logs a stage-change activity on the deal automatically.
Slice by retailer, owner, or search
Multi-axis filters at the top narrow the board to any subset of the pipeline.
React · ECharts · FastAPI · PostgreSQL · Anthropic Claude Figures illustrative
07 · 11
Activity log — chronological emails, meetings, calls, and notes
03 / 06 AI-Powered Sales CRM · Deliverable
Activity Timeline

A chronological feed of every email, meeting, call, and note across the team — the system of record for what actually got done.

What this screen does
Channel filters
Note, Email, Meeting, Task, Call: focus the feed on one signal at a time, or roll it all up.
Quick-log bar
Capture a note, task, or call inline without leaving the page.
Time-window slicing
Today / 7d / 30d / 90d / All, plus source and owner filters.
Import from Gmail or Calendar
Pull existing email threads or meeting invites into the CRM as logged activities, with attribution.
React · ECharts · FastAPI · PostgreSQL · Anthropic Claude Figures illustrative
08 · 11
AI activity summary - rolling account narrative, key-moments timeline, and per-email recaps
04 / 06 AI-Powered Sales CRM · Deliverable
AI Activity Intelligence

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.

What this screen does
Account-level rollup
A living summary across all activity on a brand, retailer, or deal: what is in flight, what was decided, and who is involved.
Key-moments timeline
The relationship’s significant touchpoints, auto-anchored to dates — the whole story at a glance.
Per-email & per-thread recaps
Each message gets a one-line AI summary; long threads collapse into a single readable card.
Stale-aware & on demand
Summaries flag themselves when new activity lands and regenerate on demand.
React · FastAPI · PostgreSQL · Anthropic Claude Figures illustrative
09 · 11
AI-suggested relationships - unlogged inbox items matched to brand x retailer, contacts, and deals
05 / 06 AI-Powered Sales CRM · Deliverable
AI-Suggested Relationships

Unlogged Gmail and Calendar items are surfaced and context-matched to the right brand, retailer, contact, and deal — logging an activity becomes one click.

What this screen does
Inbox-to-CRM matching
Reads unlogged emails and meetings and proposes the brand × retailer relationship, store, and contacts they belong to.
Confidence-aware
Single-match items log in one click; ambiguous ones flag “also matches N more” for a quick review.
Bulk log
“Log all single-match” clears the high-confidence backlog in one action, each with its associations attached.
Thread-aware
Email threads collapse into one suggestion and log together.
React · FastAPI · PostgreSQL · Gmail + Calendar · Anthropic Claude Figures illustrative
10 · 11
Brand by retailer matrix — every deal in one filterable view
06 / 06 AI-Powered Sales CRM · Deliverable
Brand × Retailer
Matrix

Every brand-to-retailer deal in one filterable view — distribution coverage at a glance.

What this screen does
Every deal in one table
All deals listed with deal name, brand, stage, owner, amount, and last activity.
Multi-axis filters
Narrow by stage, owner, or free-text across deal, retailer, and brand names.
Drill into any deal
Click a row to open the deal record with full history and editable fields.
React · ECharts · FastAPI · PostgreSQL · Anthropic Claude Figures illustrative
11 · 11