I build with AI tools every day and I run software they helped write in production, with real users and real money moving through it. The tools are good. The demo genuinely works, the happy path is solid, and most of what they generate is code I would have written myself on a normal day.
Production does not test the happy path. It tests the layer the builders skip, and it teaches the same handful of lessons so reliably that I turned them into a checklist. If you shipped something with Lovable, Bolt, Replit, v0, or a similar tool and people are actually using it, this is the layer worth an afternoon.
If you are on Supabase, open your tables and confirm row-level security is actually on, then test it with a second account that should not see the first account's data. The anon key sitting in your JavaScript bundle is fine by design. With RLS off, that same key is effectively a master key, and anyone who views your page source can pull every row in the table in about a minute. Firebase has the same shape of problem: development-stage rules tend to allow public reads, and they survive into production because nothing visibly breaks. Nothing visibly breaking is the theme of this entire list, by the way. Every item here fails silently until the day it does not.
Build your app, then search the shipped JavaScript for anything that starts with sk_live, and for your database service-role key. If either one is in the bundle, it is public now, no matter where you originally typed it. Rotate it, move it server-side, and treat the old one as leaked, because it is. AI builders will happily wire a key wherever it makes the feature work fastest, and the browser bundle makes it work fastest of all.
Check the site URL and the redirect allowlist in your auth provider against your live domain. The single most common finding I see is the preview domain, or localhost, still sitting in that list weeks after launch. The symptom is new users confirming their email and landing somewhere broken or stale, which looks like churn and is actually a two-minute settings fix.
If you take payments through Stripe, confirm your webhook endpoint verifies signatures. An endpoint that accepts any POST can be told a payment succeeded when it never did, and it will believe it. While you are in there, check the webhook URL points at production and the prices in your checkout match your pricing page, because those drift apart quietly as you iterate. HTTPS enforced, headers set, cookie flags right. A production crash should notify a human instead of rendering a white screen for a weekend. And a backup that has never been restored is a hope, not a backup. Test one restore before you need it.
I published the full checklist I work from, free, no email gate, at groundcrew.pricepilot.cloud/checklist.html. I also turned it into a small service called Ground Crew: I run the audit on your live app, reproduce every finding by hand before I write it down, and deliver fixes as pull requests at a flat price if you want them. The audit itself is free while I am testing whether founders will pay for the upkeep afterward.
If you run the checklist on your own app and find something I missed, I genuinely want to hear about it. The list gets better every time production teaches somebody a new lesson. Mark