Launch-readiness teardowns

The ways a vibe-coded SaaS leaks money — and the test for each

Every teardown takes one money-path failure an AI-built Next.js + Supabase app ships with, shows why it passes a casual look, and gives you a runnable red/green test you can stand behind before you sell.

Test Supabase RLS With Two Users

A page that shows only your rows is not proof the database rejects a direct request for someone else’s row. The two-account test every Supabase app needs before taking payments.

Read the teardown →

The Service-Role Key Bypasses Every RLS Policy You Wrote

You enabled RLS and tested it — then a server route used the service-role key, which skips RLS entirely, and handed user B user A’s row. Find and fix the bypass.

Read the teardown →

The NEXT_PUBLIC_ Prefix Can Ship Your Secret Keys to the Browser

The Supabase anon key belongs in the browser; the service-role key never does. One prefix or one Client Component can inline a secret into the bundle every visitor downloads.

Read the teardown →

Your Table RLS Doesn't Protect Your Files

Supabase Storage is a separate system from your tables. A public bucket or a too-broad storage policy serves private uploads to anyone — the RLS you wrote for your rows doesn't touch your files.

Read the teardown →

A Success URL Is Not Proof of Payment

A checkout success redirect proves a browser reached a URL — not that anyone paid. Why entitlement must come from a verified event, not a redirect.

Read the teardown →

Verify a Webhook Signature Before You Trust It

A webhook endpoint is a public URL anyone can POST to. Verify the HMAC over the raw body and compare in constant time before you grant access.

Read the teardown →

One Webhook, Five Deliveries, One Entitlement

A valid signature does not make your handler idempotent. Replay one signed order webhook five times — you should still grant access exactly once.

Read the teardown →

A Logged-In User Is Not an Authorized One

Your app checks that someone is signed in. The endpoints that refund, cancel, or upgrade an order need a second check — is this user allowed to touch this record? The access-control gap that lets one customer move another's money.

Read the teardown →

A Refund Should Turn Off Access. Does Yours?

You wired the webhook to grant access on payment. Does anything revoke it when the order is refunded or the subscription expires? The money path's return leg — the half AI-built apps forget, so a refunded customer keeps the product.

Read the teardown →

A Test-Mode Payment Should Not Unlock a Real Account

You built the checkout in test mode — the right way. But if production ships with test keys, your live checkout accepts the public test card and hands out the product for fake money. The test/live boundary check, with a runnable test.

Read the teardown →

A Checkout Should Not Trust the Price the Browser Sends

If the amount is in the request your page sends to create the payment, your customer sets the price — change 4900 to 50 and you're charging fifty cents. The server-owns-the-price fix for custom Stripe checkouts, with a runnable tamper test.

Read the teardown →

Your AI Endpoint Has No Auth — and Every Stranger's Request Is on Your Bill

Your /api/chat route calls OpenAI with your server-side key. No auth, no per-user cap, client-picked model — anyone loops it and your API bill pays. The gate + meter + cap fix, with a test that checks no paid call fired.

Read the teardown →

The money path, and how to use these teardowns

“The money path” is the narrow set of code between a stranger arriving and your app granting them paid access: which rows the database will hand out, which secrets your build ships to the browser, what your checkout treats as proof of payment, what your webhook does with the events that follow, and — for an AI app — which endpoints will spend your own money for a stranger. It is a small surface, but it is the one where a bug doesn't crash — it quietly leaks data, gives the product away, or bills the wrong person. AI coding tools are fluent on the happy path and skip these edges, which is why a vibe-coded app can pass every demo and still fail its first real customer.

The twelve teardowns above fall into five groups. Run the test in each against your own app before you charge:

Each teardown is a teaching model with an honest boundary — it shows the shape of the failure and the fix, not a certification; you run the test and keep the evidence. The free 20-point launch checklist is the fast pass across all four groups, and the ShipTested course walks the whole path lesson by lesson with a test you run against your own app and a go/no-go workbook.

Test all of these on your own app before you sell it.