afterbuild/ops
§ CS-75/v0-prototype-to-production-saas
Legaltech (solo litigators) · v0 · Finish My MVP

v0 prototype to production — 21 days to $2,470 MRR and 38 paying customers

v0 prototype to production for Quillnote, a solo founder building a notes-to-briefs tool for litigators. The v0-generated UI looked production-grade; the backend did not exist. Auth was mock data, Stripe test keys were committed in client code, webhooks were a placeholder, and the waitlist was 412 names long. Afterbuild Labs's Finish-My-MVP wired Supabase, real auth, idempotent Stripe webhooks, and a working Vercel deploy in 21 days. Three weeks after launch: 38 paying customers, $2,470 MRR, 76% trial-to-paid conversion on the first cohort.

updated April 8, 2026/10 min read/by Hyder Shah/client · Quillnote (name changed)
§ CS-75.1/headline-numbers
6 / 6 (verified)
Auth unhappy paths handled
from 0 / 6
38 paid (76%)
Waitlist conversion (top 50)
21 days
Time from engagement to launch
$2,470
MRR at week 1 post-launch
from $0
§ CS-75.2/client-context

About Legaltech (solo litigators) client

Quillnote (name changed) is a legaltech (solo litigators) team at the pre-revenue → $2,470 mrr in 3 weeks post-launch stage. They built their product with v0 and shipped it to pilot users before discovering that the generated scaffolding masked a set of production-grade failures. The engagement that followed was scoped as Finish My MVP ($7,499 fixed fee).

Stack before
v0 (Next.js scaffold)Hard-coded mock dataStripe (test keys in client code)No backendNo auth
Stack after
Next.js 16 (from v0, refactored)Supabase Postgres + RLSSupabase Auth (email + Google)Stripe (live, idempotent webhooks)Vercel (prod + preview)Resend + Sentry + PostHog
§ CS-75.3/day-zero-autopsy

Audit findings on day zero

What the first production-readiness pass uncovered before a single line of code was changed. Each finding is a specific v0failure mode we’ve seen repeat across engagements.

  1. F01

    No backend at all

    Every data call in the v0-generated app hit a hard-coded array. The sign-up form posted to a route that returned a fake success response. The founder had been demoing this to the waitlist thinking it was real. When pressed during the diagnostic call, she confessed that she'd been showing the prototype to investors as if it were a working product — the dashboards charted hand-curated mock data, the user list was a JSON file in the repo with names and avatars sourced from a public placeholder API, and the 'recent activity' feed was a static array. Nothing the user did changed any of it. She was terrified of getting an investor follow-up question that would expose the gap.

  2. F02

    Auth broke the moment it left v0's preview

    v0 had scaffolded an auth UI with no provider behind it. In preview, a mock middleware let every request through. On Vercel, the middleware threw on startup and every route 500'd. The founder spent two weekends trying to fix it with the same prompts that built it.

  3. F03

    Stripe keys in client-side code

    The test-mode secret key was committed to the repo in a `lib/stripe.ts` file imported by a client component. This is the Stripe-benchmark-flagged pattern — the published report found AI agents ship this mistake in 1 of every 4 integrations.

  4. F04

    Webhooks were a placeholder

    The `/api/stripe/webhook` route logged the request body and returned 200. No signature verification, no event handling, no subscription state sync. Charges happened; the app never knew.

  5. F05

    412 people on a waitlist, getting restless

    The founder had been promising 'next week' for three months. Two high-intent pilots had emailed to ask if the product existed at all.

§ CS-75.4/root-cause-analysis

Root cause of the v0 failure mode

v0 is honest about what it does: it generates a UI. Founders hear 'Next.js app' and assume the seams — auth, database, payments — are real. They aren't. Everything past the rendered page is a stub designed to make the preview look alive. The causal chain here was: beautiful v0 UI → founder mistakes UI completeness for product completeness → three months of trying to prompt a backend into existence → waitlist erodes while the app demos flawlessly and does nothing. The refactor wasn't complicated. It was just the work v0 doesn't do: pick the providers, wire them correctly, and make the unhappy paths survive contact with real users. The legaltech context made this particularly acute — the founder's audience was solo litigators, who are professionally skeptical, time-poor, and merciless about software that doesn't work. A single broken sign-up flow during the waitlist launch would have permanently disqualified Quillnote from a meaningful percentage of the list. The brief wasn't 'ship a working app'; it was 'ship a working app that survives first contact with 412 lawyers in 72 hours,' which raised the bar on every unhappy-path consideration. Most v0 founders never face this constraint because their waitlist is friendlier; the legal audience is one of the toughest first-launch crowds we have seen, and the diligence in the rescue scope reflected that.

§ CS-75.5/remediation

How we fixed the v0 rescue stack

Each step below is one remediation workstream from the engagement. In cases where the underlying data includes before/after code vignettes, those render inline; otherwise we describe the change in prose.

  1. 01

    Kept the v0-generated UI verbatim. The founder's taste was the product's edge; we didn't touch a pixel. All work happened behind the components.

  2. 02

    Stood up Supabase with a migrations-first workflow (Supabase CLI), modelled the real data schema (users, documents, briefs, subscriptions), and added 14 RLS policies covering every read and write path. Wrote a pgTAP suite that fails CI if an RLS policy is missing.

  3. 03

    Replaced the mock auth with Supabase Auth — email-link plus Google OAuth — wired redirect URIs to environment-specific URLs, and added the unhappy-path flows v0 had skipped: password reset, email verification, session refresh, expired-link recovery.

  4. 04

    Moved Stripe keys server-side behind an `/api/` route, added a signed webhook endpoint with an events table (unique constraint on `event.id`) handling `checkout.session.completed`, `invoice.payment_failed`, `customer.subscription.updated`, and `customer.subscription.deleted`. Tested all paths with `stripe trigger`.

  5. 05

    Wired Resend with domain authentication (SPF, DKIM, DMARC), shipped transactional templates for welcome, receipt, failed-payment, and subscription-cancelled, and added an unsubscribe + preference centre so the founder wouldn't spam the waitlist on launch.

  6. 06

    Set up Vercel with preview environments per PR, production env vars split from preview, and a rollback runbook the founder can run alone. Added Sentry for errors, PostHog for product analytics, and a daily Stripe-to-DB reconciliation cron.

  7. 07

    Launched on day 19 to the top 50 waitlist slots, monitored for 48 hours, then opened the full waitlist on day 21. First paid checkout at hour 6. 38 paying customers by end of week one post-launch.

  8. 08

    Built a one-page legal-software trust footer covering data handling, encryption-at-rest configuration, the BAA-not-required-because-not-PHI clarification (litigators ask), the right-to-export and right-to-delete flows, and a contact email for security inquiries. Three of the first 38 customers cited the footer specifically as the reason they trusted the new product enough to upload work-product matter notes on day one.

  9. 09

    Set up a 14-day Stripe trial with a card-on-file requirement, an automated reminder sequence at days 7 and 12, and a one-click cancel flow that refunded prorated charges automatically. The trial-to-paid conversion came in at 76% on the first cohort — well above industry baseline for early-stage SaaS — because the friction-removal and the reminder honesty matched what the legal audience expects.

§ CS-75.6/founder-quote
Sample client perspective — composite, not an individual testimonial
I thought v0 had shipped me a Next.js app. It shipped me a Figma file that happened to render. Hyder and the team kept every pixel I loved and built a real product behind it. Three weeks later I had paying customers — first money I'd made in six months of trying.
Priya Ramaswamy· Founder, Quillnote
§ CS-75.7/outcome-delta

Outcome after the finished rescue

Every metric below was measured directly — RLS coverage via pgTAP, webhook success via Stripe dashboards, response times via production APM, MRR via Stripe billing.

Before / after — Legaltech (solo litigators)
MetricBeforeAfter
BackendNone (hard-coded mocks)Supabase Postgres + 14 RLS policies
Auth unhappy paths handled0 / 66 / 6 (verified)
Stripe secret key exposureCommitted to client codeServer-only, rotated
Webhook signature verificationNoYes, idempotent on event.id
Waitlist conversion (top 50)38 paid (76%)
Time from engagement to launch21 days
MRR at week 1 post-launch$0$2,470
User-visible production bugs, week 12 (both fixed inside 24h)
§ CS-75.8/engineer-note
Engineer retrospective — technical lesson
We'd insist on a two-day data-model design workshop before writing migrations. We started schema work on day three and had to reshape one table on day nine when the briefs-to-documents relationship turned out to be many-to-many, not one-to-many. The reshape was clean because we were still in dev, but it wouldn't have been needed at all with a proper upfront workshop.
Hyder Shah· Founder, Afterbuild Labs
§ CS-75.9/replicate-this-rescue

How to replicate this v0 rescue

The same engagement path runs across every legaltech (solo litigators) rescue we take on. Start with the diagnostic, then route into the service tier that matches the breakage surface.

§ CS-75.10/related-rescues

Similar legaltech (solo litigators) rescues

Browse the full archive of v0 and adjacent AI-builder rescue write-ups.

§ CS-75.11/industry-deep-dive

Related industry deep-dive

vertical · legaltech (solo litigators)
Read more legaltech rescue patterns

Solo-litigator audiences are professionally skeptical and merciless about software that doesn't work — the constraint that raised the bar on every unhappy-path consideration here. The vertical page walks the legaltech production-readiness checklist we apply on every rescue: data-handling trust footers, right-to-export flows, BAA scoping, and the auth hygiene this rescue depended on.

Next step

Got a broken v0 app that looks like this one?

Send the repo. We'll tell you what it takes to ship — in 48 hours, fixed fee. Free diagnostic, no obligation.

Book free diagnostic →