AZ
All writing
3 min read

Building to a written spec instead of a vibe

nextjsspec-drivenmongodbproduct
Part of the projectChekkaA Nigerian professional car-inspection platform — a Next.js 16 monolith built on the Managerenta conventions, with a locked-report integrity model and a live inspection feed.View project

Chekka's whole pitch — "before you buy, Chekka" — is that an independent professional inspects a used car so the buyer doesn't have to gamble. When the product is trust, you can't improvise the definition of "verified" halfway through the build. So Chekka started from a written specification.

A real spec, honestly sized

The spec (Chekka_Core_Features.md) is about 4,728 words across 596 lines — twelve numbered core features plus a "Tech Stack & Code Conventions" section. It isn't enormous; it's dense and structured, and its most useful trick is that it ships the code skeleton the build then follows verbatim. The route-handler shape and the Mongoose model conventions are written into the spec itself, so "spec" and "scaffold" are the same document, and the build follows a contract instead of rediscovering scope in code review. (One correction worth making plainly: an internal brief called this a "37k-word" spec — the verified count is 4.7k. Precision is the point of a spec; it should extend to describing the spec.)

Descended from the reference architecture

The spec doesn't invent conventions — it inherits them. Chekka is explicitly "built on the same conventions as managerenta-client" (README line 5): the same server-only src/server/ triad, the same withApiHandler(withAuth(...)) route skeleton, the same pre/post("aggregate") hooks, databaseResponseTimeHistogram timers, select:false soft-delete, and model memoization. The infrastructure is deliberately unsurprising so the surprise budget can go entirely to the domain.

The domain is a lifecycle

The core entity is inspections, and its status field is a one-directional state machine: submitted → assigned → (declined) → scheduled → in_progress → report_processing → completed. Each transition stamps its own timestamp (assignedAt, acceptedAt, startedAt, reportDeadline, completedAt, reportLockedAt), and dashboards bucket off the status — declined is intentionally excluded from every bucket. Assigning an inspector at creation stamps assignedAt and jumps straight to assigned; pricing is computed server-side from an admin-tunable siteConfig plus a flat urgent surcharge, never trusted from the client.

Report integrity is the product

A report a buyer paid to trust must be immutable once filed, and its numbers must be the server's, not the client's. On submit, Chekka recomputes the summary counts from the checklist item statuses across all four sections and refuses to touch a locked report:

if (current.reportLockedAt) throw ErrReportLocked;
const all = [...report.exterior, ...report.interior, ...report.mechanical, ...report.roadTest];
const summary = { ...report.summary,
  passed:  all.filter((i) => i.status === "good").length,
  minor:   all.filter((i) => i.status === "minor").length,
  serious: all.filter((i) => i.status === "serious").length };
if (lock) { patch.status = "completed"; patch.reportLockedAt = new Date(); patch.completedAt = new Date(); }

Locking flips the status to completed, stamps the lock/complete timestamps, publishes a report_filed event to the admin live feed over Redis pub/sub, and notifies the buyer. Sharing a finished report is then a read-only, self-expiring capability: a uuidv4() nonce maps to the inspection id in Redis under a 7-day TTL, so the link grants unauthenticated read access to one report and the inspection id never appears in the URL.

Why the spec paid off

Report integrity, S3-backed photo evidence (an append-only collection with a race-safe photoCount), and a booking flow that schedules real humans are the three things that carry the product; everything else is plumbing in service of them. Because those three were pinned in writing before the first route existed, the build could be aggressive about the plumbing and careful about the trust — which is the correct place to spend care in a product that sells verification. The delivery leaned on 15 Playwright specs across booking, the inspection flow, photo upload, the live feed and share links; the thinner unit story (no Vitest here) is itself an honest line in the ledger.

Back to the projectChekkaSee the full case study and related write-ups.View project