saascode

What it took to build a sales CRM in one night

One overnight run, 6.2 hours on the line: 884 files, 85 pages, 66 tables — and the five things that fought back. The measured build record of a complete sales CRM.

builds · aug 04, 2026 · 4 min read · product: Prospera

A sales rep on a headset call with a prospect, moving a deal card across Prospera's pipeline board on her monitor in a small B2B company's open-plan sales office

Prospera is a lean sales CRM — a kanban pipeline as the home screen, an AI copilot that surfaces the one concrete next action per deal, contacts, sequences, lead scoring, a report builder. This is what it took to build it.

The line started at 2:10 AM UTC on July 12 and shipped at 9:06 AM the same morning. Six point two hours of machine time, fourteen phases, no human in the loop between credentials and the finished tag.

The numbers

  • 884 files written under src/
  • 85 pages, 285 routes (pages + API)
  • 66 database tables, every one behind row-level security
  • 56 migrations, applied in order, idempotent
  • 6.2 hours on the line, end to end

The wall-clock split tells you where the work actually lives: the backend phase took 63 minutes to lay down the API surface. The frontend phase took 191 minutes — a swarm of parallel builders, each owning a slice of the 85 pages. QA ran 21 minutes of type-checking, linting, and hardcoded-string hunting. A debug pass walked the sitemap and tested routes for 15 minutes. The skin phase applied the design system in 24.

What fought back

A build that reports zero friction is a build that isn't being watched. Five things fought back, and all five are in the record:

  1. The template's default tenancy survived one config step too long. Prospera is a single-business CRM, but the base ships multi-org by default. A role-layer gate caught the mismatch before it shipped — the fix was one line, but the point is the gate existed.
  2. The seed referenced a table that doesn't exist. The event registry looks like a database table from the docs; it's actually code. The seed step failed loud, the section was dropped, and event registration moved to the backend phase where it belonged.
  3. Postgres validates function bodies at CREATE. A visibility helper referenced two tables that were created later in the same migration. The DDL got reordered — tables first, helper second, policies third.
  4. The typed database client rejected multi-line query constants. Every select constant got flattened to a single-line literal. Tedious, mechanical, caught at compile time.
  5. Three "New" buttons led nowhere. The create screens for contacts, companies, and deals existed as APIs but not as routes — the kind of wiring gap a human clicks into on day one. QA logged it; the debug phase wired it.

What shipped

A complete CRM: pipeline board, contact and company records with a polymorphic activity timeline, tasks, reusable email templates, multi-step sequences with reply-stop detection, rules-plus-AI lead scoring, a custom report builder, embeddable lead-capture forms — with billing, i18n, rate limiting, and an admin panel that were part of the platform before the first Prospera-specific line was written.

See Prospera →

end
What it took to build a sales CRM in one night — saascode