
An AI-built app usually breaks with real users in five places: who can see which data (access control), secret keys shipped to the browser, payments that don't match what the app records, errors nobody sees, and data with no backup or migration path. A demo exercises none of them. Real users exercise all of them in the first week.
Picture the week after launch. The app you built in a weekend with Lovable, Bolt, Cursor or Claude Code has its first hundred sign-ups. Then one customer emails a screenshot of another customer's invoice. A Stripe payment went through, but the account still says "Free". And the error log you never set up would have told you about both two days ago.
None of this means the tool was the wrong choice. AI coding tools are very good at the visible part of a product: screens, flows, a working database. The parts that only matter once strangers use the app are the ones they leave for you to decide, and in a demo nobody asks.
This is a follow-up to Why Projects Built With Claude or Codex Stall Before Launch. That post covers why the last stretch gets slow. This one is the checklist for the moment you have real users.
Why does an app that works in the demo break with real users?
A demo has one user who knows the happy path; production has many users who don't. In a demo you are logged in as yourself, you click the buttons in order, and you never look at someone else's data. Real users sign up twice, paste emoji into forms, open two tabs, cancel payments halfway and share links.
The underlying issue is that an AI coding tool builds what you ask for. "Add a dashboard that shows invoices" produces a dashboard that shows invoices. It doesn't produce a rule that says only the owner's invoices, unless you asked for that or the tool's defaults happen to include it.
The OWASP Top 10 for 2025 puts Broken Access Control at A01 and Security Misconfiguration at A02. These are the two most common categories of web application risk, and they are exactly the two that a quick build skips.
Can other users see data they shouldn't?
This is the most serious failure, and it is often invisible until someone reports it. Many AI app builders use Supabase or another hosted Postgres database. The browser talks to the database directly, and Row-Level Security (RLS) policies decide which rows each user may read or write.
Supabase's documentation is explicit: enable RLS on every table in an exposed schema. A table without it is readable and writable by any role that has been granted access to it, which can include signed-out visitors.

This is not theoretical. CVE-2025-48757, published on 30 May 2025, describes insufficient RLS policies in sites generated with Lovable up to 15 April 2025. It says these let unauthenticated attackers read or write arbitrary tables. Lovable disputes the record and says each customer is responsible for protecting their own app's data. Either way the lesson for an app owner is the same: whoever is responsible, the data is yours to protect.
What to check
RLS is enabled on every table the app exposes, including the ones you added late.
Each table has policies for select, insert, update and delete, and each is tested while logged in as a second, ordinary user.
Admin-only screens are protected on the server or database side, not just hidden in the interface.
Storage buckets (uploads, invoices, avatars) have their own access rules.
Are secret keys exposed in the browser?
Any key the browser can read, anyone can read. AI tools sometimes put a powerful key in front-end code because it makes the feature work immediately.
Supabase's docs say never to use a secret key in the browser. The service role bypasses RLS entirely and must stay server-side. The same applies to OpenAI or Anthropic API keys, Stripe secret keys and email-provider keys. A key in the browser lets anyone spend your credits or send email in your name.
What to check
Search the built front-end bundle, not just the source, for strings that look like keys.
Move every call that needs a secret into a server function (an edge function, API route or backend).
Rotate any key that has ever been in client code or a public repository. Deleting it from the code doesn't make it secret again.
Do payments and subscriptions match what the app records?
Payments break quietly: the money arrives, but the app doesn't know. Stripe and most payment providers report what happened through webhooks, messages they send to your server after a payment succeeds, fails, renews or is disputed.

Stripe's webhook documentation covers three points that demos usually skip:
Verify the signature. Every event carries a Stripe-Signature header. Without checking it, anyone who finds the endpoint can mark an account as paid.
Expect duplicates. Stripe may deliver the same event more than once, so store the processed event IDs and ignore repeats.
Expect retries. If your endpoint fails, Stripe retries with exponential backoff for up to three days in live mode. Your code has to cope with events that arrive late and out of order.
What to check
Subscription status in your database is updated from webhooks, not from the success page the user lands on.
Cancelled, failed and refunded payments change access, not just successful ones.
There is a way to reconcile Stripe's records with your database when they disagree.
Will you know when something fails?
If the only error report is a customer email, you will hear about a fraction of the failures, and late. OWASP's 2025 list names Security Logging and Alerting Failures (A09) and a new category, Mishandling of Exceptional Conditions (A10). Both are about what happens when things go wrong.
AI-generated code often catches an error and carries on, or shows a blank screen. That keeps the demo smooth and makes production problems invisible.
What to check
Front-end and back-end errors go to one place (an error-tracking service or structured logs) with an alert for new error types.
Failed background jobs, webhooks and emails are recorded and can be retried.
Users see a clear message and a next step instead of a blank screen.
Can you change the app without losing data?
The first version's database is usually shaped by the first prompt. Within weeks you need to rename a field, split a table or add a required column, and real user data is already in it.
What to check
Database changes are made through migrations kept in the repository, not by editing tables by hand in a dashboard.
Automatic backups are on, and you have restored one at least once to confirm it works.
There are separate environments, at least a staging copy, so changes are tested before users see them.
Production-readiness checklist for an AI-built app
Use this as a first pass before inviting users beyond friends and family:
RLS (or equivalent access rules) enabled and tested as a second user on every table and storage bucket.
No secret keys in the front-end bundle. Exposed keys rotated.
Payment webhooks verified by signature, deduplicated by event ID and driving subscription status.
Sign-up, password reset and email verification tested end to end, including edge cases such as duplicate emails.
Errors captured centrally, with alerts.
Migrations in version control, backups on and a restore tested.
A staging environment for changes.
Basic rate limiting on sign-up, login and any endpoint that costs money (AI calls, email, SMS).
If several of these fail, it doesn't mean the app has to be thrown away. Usually the screens and most of the logic can stay, and the work is in the layers underneath.
How we approach it at Vizio AI
When a founder brings us an app built with an AI tool, we don't start by rewriting it. We read the codebase and the database first. We test access as different users, look for exposed keys, and trace one payment from checkout to database. That shows which parts are sound and which parts are holding up the launch.
From there the plan is usually narrower than people expect: fix access rules, move secrets server-side, rebuild the payment flow around webhooks, and add monitoring and migrations. Then the product can take real users. This is the work behind our Finish your build offer at the Venture Studio. If you are still deciding what to build, Why Product Discovery Should Happen Before Development is the better starting point.
Sources
NVD, CVE-2025-48757: https://nvd.nist.gov/vuln/detail/CVE-2025-48757
Supabase Docs, Row Level Security: https://supabase.com/docs/guides/database/postgres/row-level-security
Stripe Docs, Receive Stripe events in your webhook endpoint: https://docs.stripe.com/webhooks
OWASP Top 10:2025: https://top10.owasp.org/2025











