20 October 2026 · 5 min read · BlitzHash Team · AI & Vibe Coding
Production checks for an AI-built app before you invite real users
A Lovable, Bolt, v0, Replit, or Cursor app can look finished in the preview and still fail the first time a stranger signs up on your domain. The failures are usually ordinary. A table is readable by anyone who has the public key. A secret sits in the browser bundle. Login returns to the preview host. Refreshing a signed-in page shows a 404. A backup job has never been restored, so nobody knows if it works.
This is the pass we run before we call an AI-built app ready for real users. It is the same list behind AI App Launch & Rescue. If you want a first look on your own, the production readiness score is twenty yes or no questions and a checklist.
Row Level Security is on, and a second user cannot read the first
Supabase exposes Postgres through an API. The anon key is meant to ship in the browser. That is safe only when Row Level Security is enabled and each policy says who can see a row. A policy written so that every row passes is not protection. It is a public table with extra steps.
Open every table the builder created. Profiles, messages, files, teams, and billing rows are the usual misses, including tables you did not design by hand. Turn RLS on. Write policies that compare the signed-in user to an owner column. Then sign in as a second test user and try to read, update, and delete the first user's rows through the API the app actually uses. The request should fail. Check related tables too. A profile policy can be right while a join still returns someone else's data.
Storage needs the same pass. A public bucket is reasonable for marketing images. It is the wrong place for invoices, identity documents, or customer uploads. Match the bucket rules to the table rules, and try a direct file URL while signed out.
Write down the tables you checked. A launch report that names them is more useful than a line that says the app was reviewed.
Secrets stay on the server
The public anon key belongs in the client. The service-role key does not. Neither do payment secrets, SMTP passwords, or private model tokens. Search the repository and the built JavaScript, not only the source you remember editing. Builders sometimes inline a key because a server function was awkward in the preview.
Move privileged calls to a server route, an Edge Function, or the host's secret store. Rotate every key that already shipped in a bundle. Deleting the line in the next commit is not enough. Old bundles stay cached, and old keys stay valid until you revoke them.
Read the logs as well. A helpful error handler can print a connection string the first time a query fails. Preview logs are easy to ignore once a custom domain is live.
Auth URLs match the domain people will use
Login often works in the builder and fails on your domain because the Site URL and the redirect allow-list still name localhost or the preview host. Set the production origin. Add the callback paths you use. Remove redirects you do not use. A wildcard wider than your domain is a bug.
Then send a real confirmation email and a real password reset. Click the links on a phone. Each link should land on your domain, finish the session, and show a signed-in screen. Default mail is fine for a demo. Production mail should leave through SMTP you control, from an address on your domain. Try an expired link and a link that was already used. The screen should explain what happened.
If the product has more than one environment, give each environment its own URL list. A preview deploy that sends people to production, or the other way around, is a support ticket waiting to happen.
A refresh must not 404
Many generated front ends work until someone refreshes a nested route or opens a shared link. The host looks for a file that is not there and returns 404. Fix that with a rewrite to the app entry, or with a real server route if the framework has one.
Walk the primary screens. Marketing home, sign-in, a signed-in page, a page with an id in the path, and the 404 you mean to show. Refresh each one. Open each one in a private window. If the app is Next.js, deploy the production build. Do not point the domain at a preview export and hope the host fills in the gaps.
This is also when environment variables disappear. The preview had them. The host does not. List every variable the app reads at build time and at runtime, and set them in the hosting project.
Payments, if the app charges
Test mode is not a launch. When the product takes payment, the server should verify the webhook signature and ignore a body that fails that check. The same event can arrive twice, so the handler has to tolerate a repeat without creating a second order. Place one live purchase on a card you control, confirm the app's record matches the payment dashboard, and refund it. Keep the secret on the server. The browser only gets the publishable key.
The SaaS and product engineering practice covers billing when the product is more than a single checkout. For a rescue, we still test the path that already exists. We do not turn a payment bug into a silent success.
Backups you have restored
A scheduled backup that nobody has restored is a hope. For a managed database, restore into a scratch project and read a row you recognize. For a database you host yourself, restore the dump onto a second database and sign in against it. Write down the command, how long it took, and who is allowed to run it.
Decide who hears about downtime. An inbox someone reads is a fine start. A monitor that emails a person who left the company is not. Managed infrastructure care is the monthly option when you want that watch kept for you. The launch should still leave you able to restore without us in the room.
Leave with a written checklist
None of these checks is a new feature. They are the difference between a demo and a system other people depend on. The report should say what was wrong, what changed, and how to deploy, roll back, and rotate a key. The repository should live in an account your company owns.
If you want the pass done against a written scope, start with a free technical assessment. You get the findings either way. You decide after that whether to hire the work.
