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

Source: https://saascode.ai/inside/prospera-build-story · Published: 2026-08-04 · Section: builds · Product: Prospera (https://saascode.ai/products/prospera)

---
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 →](https://prospera.saascode.ai)**

## Related reading

- [Prospera: a pipeline-first sales CRM that keeps every deal moving](https://saascode.ai/inside/prospera-pipeline-first-sales-crm-keeps-deals-moving.md)
- [Prospera vs Pipedrive: Subscribing to a CRM or Launching One You Own](https://saascode.ai/inside/prospera-vs-pipedrive-subscription-or-owned-crm.md)
- [Sales CRM Options, Organized by Where the Next Action Comes From](https://saascode.ai/inside/sales-crm-options-by-next-action-source.md)
