The vibe-code rescue checklist
Check the things that lose money, data or trust first: secret keys in the browser, missing access rules, payments that rely on the success page, and errors nobody sees. Then check mobile layout, accessibility, speed and whether you own the code and accounts. Most items can be tested without reading code.
Why it matters
AI app builders make it easy to get something on screen. They don't make it easy to see what is missing behind the screen, because nothing you prompted for is visibly broken. The gaps are in the things nobody asked for: who can read which rows, what happens when a payment fails, what the app does on a slow phone.
This is the checklist I work through on an AI-built app before I recommend anything. It is ordered by harm. The first groups cover what can leak data or lose money. The later ones cover what makes the app hard to use or hard to change.
You can run most of it yourself in an afternoon. If you would rather work on paper, a PDF version of this checklist is available to download on this page.
How to use it
Go through each group and tick only what you have actually tested, not what you believe is true. "I think the keys are on the server" is an unticked box.
You will need:
- Two test accounts with different roles, or at least two ordinary users.
- A private browser window, so you can be both at once.
- Your phone, on mobile data.
- Stripe in test mode and a Stripe test card, if you take payments.
- Access to the database dashboard (often Supabase) and the hosting dashboard.
Write down every unticked item with one line on what you saw. That list is the brief for whoever fixes it, including you.
The checklist
1. Secrets and access
- No secret keys in front-end code. Search the loaded JavaScript in the browser's developer tools for sk_live, sb_secret, service_role, secret and your AI provider's key prefix.
- No secret keys in the Git history. Committed .env files count, even if deleted later.
- Every table in the public schema has Row Level Security switched on (Supabase).
- Every table with Row Level Security has policies that limit rows to their owner or role.
- Admin pages check the user's role on the server, not just by hiding the link.
- Any key that was ever exposed has been rotated, not just removed.
This group matters most. Supabase's docs are direct about it: the publishable key is designed to be public, so Row Level Security on every table is what protects your data, and the secret key bypasses every policy, so it must never be in a browser or source control. You can find tables without Row Level Security in the Supabase SQL editor:
-- Tables in the public schema with Row Level Security switched off
select tablename
from pg_tables
where schemaname = 'public' and rowsecurity = false;A typical owner-only policy, from Supabase's own docs, looks like this:
create policy "Users can view their own profile."
on profiles for select
to authenticated
using ( (select auth.uid()) = user_id );There is more on this in vibe coding security risks and exposed API keys in AI code.
2. Auth and accounts
- User A cannot see user B's records by pasting the URL of one into their own session.
- Logged-out visitors are redirected away from every private page, including deep links.
- Password reset emails arrive and link to the live domain, not a preview URL.
- Email confirmation works, and unconfirmed users can't reach paid features.
- Sessions survive a page refresh and expire when they should.
- Deleting an account deletes or anonymises that user's data.
The two-account test is the quickest way to catch the most serious bug on this list. Log in as user A, copy the URL of one of their records, then open it as user B in a private window. If B can see it, stop and fix that before anything else. Fixing auth in an AI-built app covers what usually causes it.
3. Data
- You can explain every table in one sentence.
- Each record has one clear owner, and relationships are links between tables, not copied text.
- Unique things (emails, usernames, slugs) are enforced as unique in the database, not only in the form.
- Money is stored in whole pence or a decimal type, not as a floating-point number.
- Backups exist, and you know how to restore one.
- There is a separate database for development, so testing never touches real users.
Check backups before anything else changes. Supabase's docs list daily backups on paid plans and recommend that Free plan projects export their own data regularly. Fixing the database schema in an AI app goes deeper.
4. Payments
- Paid access is granted from a Stripe webhook, not from the success page loading.
- The webhook verifies Stripe's signature on every event.
- Processing the same event twice does not grant access or send emails twice.
- Failed renewals, cancellations and refunds each have a code path that changes the user's access.
- Test: pay with a test card, close the tab before the success page loads, and check the account still upgrades.
Stripe's webhook docs say to verify every event's signature, to expect the same event more than once, and not to rely on events arriving in order. An app that upgrades users when the success page loads breaks all three assumptions.
5. Errors and logging
- Every page has an error state. Switch off wifi and use the app to check.
- Every form shows a useful message for bad input and for a failed save.
- Every request checks for failure, including fetch responses and Supabase results.
- Crashes show a recovery screen, not a blank page.
- Errors are logged somewhere you look at, not only in the user's browser console.
MDN notes that a fetch request does not fail on a 404 or 500 response, and Supabase's docs say its client returns errors instead of throwing them. Both are easy to ignore by accident. Adding the error handling AI tools skip has the code.
6. Mobile and accessibility
- The whole main journey works on your phone, including sign-up and payment.
- No page scrolls sideways at 320px wide.
- Buttons and links are at least 24 by 24 pixels, and primary actions closer to 44.
- Body text has a contrast ratio of at least 4.5 to 1 against its background.
- You can finish the main task with only the keyboard: Tab, Enter and Escape.
- Every input has a visible label.
The numbers come from WCAG 2.2: 4.5 to 1 contrast for normal text, at least 24 by 24 CSS pixels for targets, and content that reflows at 320 pixels wide. Fixing broken mobile layouts in AI-generated UIs covers the Tailwind side, and making an AI-built app accessible the rest.
7. Speed
- The first useful screen appears within about 2.5 seconds on your phone over mobile data.
- Images are sized for where they appear, not uploaded at full camera resolution.
- Lists that can grow are paginated or limited, not loaded in full.
- Pages don't jump around as they load.
Google's Core Web Vitals call a page good when the largest content loads within 2.5 seconds, measured at the 75th percentile of visits. Why your AI-built app is slow explains the usual causes.
8. Code and ownership
- The code is in a Git repository owned by you or your company.
- The app can be installed and run locally from the README.
- The domain, hosting, database, Stripe and email accounts are all in your name.
- There are automated tests for at least sign-up, log-in and payment.
- One person or tool is the source of truth for code changes.
If you are handing the app over, how to hand a vibe-coded app to a developer turns this group into a full handover pack.
9. Before launch
- Privacy policy and terms exist and match what the app really collects.
- Transactional emails come from your own domain, not a default sender.
- Analytics records the events you need to judge the launch.
- You have tried the whole journey as a brand-new user, on a phone, on the live domain.
This last group is less about code and more about launch. It still belongs here, because it is where AI-built apps often ship with placeholders: a privacy policy generated before the product changed, emails sent from a default address that may land in spam, and no way to tell whether the launch worked. If you are planning a launch, GDPR for startups in the UK and the app launch checklist pick up where this list stops.
Common misses
These are the items people tick too quickly.
- Row Level Security switched on, with a policy that allows everything. The switch is green in the dashboard, but a policy like "any signed-in user can read all rows" means any account can download every row. Read the policies, don't just check they exist.
- Testing payments only with the happy path. The success page loading is not proof of payment. Close the tab, use a card that declines, and cancel a subscription.
- Rotating a key by deleting it from the code. If it was ever committed or sent to the browser, it needs a new value in the service's dashboard.
- Testing on a laptop with the window made narrow. It misses browser toolbars, touch, the on-screen keyboard and slow mobile data. Use a real phone.
- No restore test. A backup you have never restored is a hope, not a backup.
- Ticking boxes for things you were told. "The AI said it added validation" is not the same as trying to submit the form empty.
- Checking once and never again. Each new prompt can undo an earlier fix. A policy gets loosened to make a feature work, or a key moves back into the front end. Rerun the first two groups after any big change.
Next step
Count your unticked boxes in groups 1 to 4. If there are none, you are in better shape than many AI-built apps, and the rest can be fixed as you go. If there are several, fix those before inviting more users or spending on marketing.
If the list is long, the next question is whether to fix the app in place or start again: when to refactor vs rebuild a vibe-coded app helps with that, and what a vibe-code rescue costs in the UK helps with the budget. My guide to fixing a vibe-coded app explains why these failures happen in the first place.
The free vibe-code health check automates part of this list against your live URL. If you would rather have it done for you, a Rescue Sprint works through every group, fixes what is broken and leaves you with the list ticked, at a fixed price agreed after a technical assessment (from £750).
- Supabase docs: Understanding API keys, checked 10 November 2026
- Supabase docs: Row Level Security, checked 10 November 2026
- Supabase docs: Database backups, checked 10 November 2026
- Supabase docs: Handling errors in supabase-js, checked 10 November 2026
- Stripe docs: Receive Stripe events in your webhook endpoint, checked 10 November 2026
- MDN: Window fetch() method, checked 9 November 2026
- W3C: Understanding WCAG 2.2 Contrast (Minimum), checked 9 November 2026
- W3C: Understanding WCAG 2.2 Target Size (Minimum), checked 9 November 2026
- W3C: Understanding WCAG 2.2 Reflow, checked 9 November 2026
- web.dev: Web Vitals, checked 9 November 2026
The vibe-code rescue checklist, as a PDF
About 40 checks across auth, data, payments, errors, mobile and secrets, on two pages.
Questions founders ask
Can I run this checklist without being a developer?
Most of it, yes. Many items are tests you do in the browser with two accounts, a phone and a Stripe test card. A few, like checking Row Level Security, need access to the database dashboard but no coding.
Which items should I fix first?
Anything in the security, auth and payments groups. Those lose data or money. Layout, speed and code quality matter, but they rarely cause harm overnight.
Is there a printable version?
Yes. A PDF version of this checklist is available to download on this page, so you can print it and tick items off as you go.
How often should I run it?
Once before you invite real users, and again before any launch or paid campaign. After that, rerun the security and payments groups whenever you make a big change to sign-up, data or billing.

Ant
Product designer who builds MVPs, based in Nottingham. 10+ years designing digital products, and the only person at BlackFig. More about me