Case Study

Cleaner CRM

Two prompts. Two UAT passes. Three days. Fable did the rest.

A full cleaning-business CRM: owner back office, cleaner field app, and a public booking funnel with real Stripe payments, live on UAT. I two-shotted it: a 110-word prompt on July 7, one sentence for the customer side a day later. Claude Fable 5 orchestrated 172 subagents through the rest. Measured across the conversation, I typed 3,923 characters; the agent wrote just over a million.

2
Prompts by John
21
Stories Shipped
143
BDD Criteria
0.4%
Characters Typed by John

What is Cleaner CRM?

A Phoenix LiveView CRM for residential cleaning businesses, scoped by agent-run research into Jobber, Housecall Pro, and Maidily. Three personas: the owner runs the business, the cleaner works the day from a mobile field app, and the customer quotes, books, and pays without ever creating a password. Every story cites a research finding.

Stripe

Payment Element card capture, card-on-file charges, payment links, signed webhooks with replay protection

Twilio

SMS reminders with per-job failure isolation and email fallback

Resend

Magic links, portal invitations, review requests

Oban

Reminder scans, review scheduling, recurring-visit materialization

Kamal + Hetzner

Health-checked container swaps, SSM-bootstrapped secrets

Wallaby

Five headless-Chrome journey tests codifying the QA runs

Key Features

  • Recurring plans with series-wide conflict detection and per-visit overrides
  • Weekly dispatch board with reassignment and acknowledged schedule-change alerts
  • Quotes and invoicing off an owner-configured rate card, Stripe card-on-file
  • Public instant-quote calculator and online booking at /book, no login required
  • Magic-link client portal: proof-of-work photos, policy-gated reschedule, pay and tip
  • Cleaner field app: day view, room-by-room checklists with photo proof, live earnings
  • Timesheets with hourly and piece-rate pay, payroll CSV export
  • Photo-proof quality scorecards, review engine, append-only audit trail
  • Role-gated routing: cleaners physically cannot reach office data

User Stories

Every story that drove this build, complete and unexcerpted: persona, Three Amigos rules with full given-when-then scenarios, acceptance criteria, and resolved questions, exported straight from the harness database. All 21 passed browser-level QA.

21
Stories
143
Acceptance Criteria
21
With Three Amigos

Open Source Repository

The repo is public, full build transcripts included: 194 raw session files under .code_my_spec/conversations, synced by a pre-commit hook. Every failure in this teardown is in there. This case study was mined from those transcripts.

View on GitHub
Elixir / Phoenix
Language
331 (0 failures)
Tests
5
Wallaby Journeys
194 files
Transcripts Committed

The Dev Story

The Good, The Bad, and The Ugly

One 110-word prompt to a green BDD suite in 4 hours 12 minutes. Overnight, browser QA filed 35 issues and dispatched its own fixers while I slept. Day two: I spotted the missing customer persona at demo time and commissioned it in one sentence. Day three: live UAT, real Stripe, and a stranger from Reddit stress-testing it. Plenty broke along the way.

  • 110-word prompt to a green BDD suite in 4h12m: research, 2 personas, 15 stories, ~100 spex, 146 tests
  • Research agents corrected my own brief: the competitor I named does not exist; they identified the real one
  • Browser QA ran itself: 35 issues filed, fixed, and re-verified agent to agent; a critical authz hole fixed in 8 minutes
  • QA caught what specs could not: a dropdown that no-opped in real browsers, a cleaner who could export the company's payroll, a booking dated 2020
  • The missing customer side went from one sentence to a QA'd public booking funnel in 2.5 hours
  • The real Stripe sandbox caught a Live-adapter bug on the first charge; cassette tests caught a webhook replay vulnerability
  • Guardrails held: agents escalated instead of routing around permission blocks, and confessed their own messes unprompted
  • Fable orchestrated 172 subagents; I typed 0.4% of the characters (3,923 vs 1,027,791)

Three days. Two prompts: 110 words to start, one sentence for the customer side. Twenty-one stories across three personas, 143 BDD spex, 331 tests, real Stripe payments, and a live UAT. Two UAT passes, one donated by a stranger on Reddit. I typed 0.4 percent of the characters; Claude Fable 5 orchestrated 172 subagents through the rest. That's the loop that ships.