What can be salvaged from AI-generated code
Pedro CunhaPublished on updated on 10 min read
In short
What breaks in an AI-built product isn't ugly code: it's the boundary. In the app we audited, all eight server endpoints accepted unauthenticated requests — payment endpoints included — and any user's private data was readable by everyone else. None of it required a rewrite: the client kept shipping with the same AI after the foundation was fixed.
Why vibe coding works at the start#
Vibe coding means building software by talking to an AI, with no engineering foundation underneath. The market likes to treat that as a sin. It isn't: it's the cheapest way anyone has ever had to find out whether people want your product.
The case behind this article is a good example. A gamified personal development platform — tasks, habits, goals, finances, leaderboard, coin shop — built by the founders themselves talking to an AI, with no technical team. By the time we were called in, the product had 1,312 active users, monthly, quarterly, half-yearly and lifetime plans being sold, more than 40 database tables and eight server functions. No software house ships that at the speed two founders shipped it by talking to an AI.
The problem shows up later, and not where people are looking.
What breaks as the product grows#
Intuition says the problem with AI-generated code is code quality: duplication, huge files, bad variable names. That exists — in the case above there was an 800-line file and the XP rule spread across five different places — but that's technical debt, not risk. Debt charges interest; risk charges everything at once.
Three things charge everything at once, and none of them is about aesthetics:
1. The boundary: who may call what. In the audited app, all eight server functions were configured not to require authentication. Payment functions included. Anyone who found the URL could send a request faking an approved purchase and grant themselves a lifetime subscription, credit unlimited coins or cancel someone else's subscription. One of them allowed deleting the system's historical records.
The same boundary was missing inside the database: tasks, habits, goals and the daily sleep, mood and productivity logs of any user could be read by any other — some of it without even being logged in. One table had a rule letting anyone create, edit and delete anyone else's records.
Note that none of these is a bug. The code did exactly what was asked. Nobody asked for "and reject anyone calling from outside" — and the AI doesn't ask.
2. The bill nobody is watching. The environment ran on the AI tool's own managed cloud: the most comfortable option, the most expensive and the least visible. There were daily charges that went unnoticed for days and credit purchased beyond actual consumption. Around R$2,000 a month for a product that, after moving to a proper managed database plus dedicated front-end hosting, went to around US$20 a month — now with automatic backups, which the previous setup didn't guarantee.
3. What happens the day something goes wrong. No automated tests, no error monitoring, no staging environment and no documentation. Changes went straight to production, on top of paying users; if a payment failed, nobody was notified; and the knowledge of how the platform worked existed in exactly one place — the conversation with the AI.
This is not an isolated case. Veracode tested more than 100 models and measured that 45% of generated code samples introduced OWASP Top 10 vulnerabilities, with the security pass rate stalled at around 55% — and the report's most uncomfortable conclusion is that increasing model size does not improve security. It's a systemic problem, not a matter of waiting for the next release.
How the X-ray is done#
The order of the audit is what separates a report that produces decisions from one that produces anxiety. Ours goes by consequence, not by taste:
- What causes direct loss — payments, subscriptions, credits, balances. A hole here is money leaving today.
- What leaks personal data — database access rules, sensitive data readable by third parties, access without authentication.
- What blocks growth — business rules on the client, no server layer to integrate through, scale limits already being paid for with features cut from the product.
- What is technical debt — duplication, large files, loose typing, missing tests. It matters. It comes last.
Every finding comes in the same shape, and that shape is half the value: severity · urgency · what is configured · the evidence in the code · the attack it enables · how it looks afterwards. A finding without evidence doesn't make the list. And the report must also say what not to do right now — in the case above, we said explicitly that the architecture without a dedicated server was adequate for that scale, and that replacing it before closing security and process would be spending money in the wrong place.
What is kept, what is moved, what is rebuilt#
| Layer | Typical verdict | Why |
|---|---|---|
| Interface and flows | keep | validated by paying users; rewriting throws away learning, not code |
| Data model | keep with adjustments | migrating data is expensive and risky, and the schema is usually more correct than it looks |
| Business rules in the front end | move | not deleted: relocated, from the browser to the server |
| Authentication and permissions | rebuild | this is where AI-generated code fails with the most consequence |
| Third-party integrations | rebuild | requires the server layer that doesn't exist |
| Infrastructure and deploy | change owner | leaving the cloud embedded in the tool is the fastest and cheapest win |
| Backups and staging | create | almost never exist |
| Documentation and automated tests | create | the knowledge lives in the AI conversation, not in the repository |
The table reads as one sentence: what the AI did well sits on top, and what has to change sits underneath. That's why a full rewrite is almost never justified — it destroys the good layer in order to fix the bad one.
The detail that only exists in AI-built apps#
This is the finding that appears in no article about vibe coding, and it's the most practical of them all.
Several AI tools' stacks install, by default, a service worker — the technology that lets the app behave like an installed application and open without a network. Great for experience. Terrible the day you change databases.
When we migrated the infrastructure, some of the most active users kept opening a version of the app frozen in their own device's cache — a version still pointing at the old database. They went on using the product and writing data, just in the wrong place. Nothing was lost: the records stayed in the old base and were recovered by script and merged into the new one. But the lesson is harsh and specific:
Migrating the database of an AI-generated app without handling the service worker leaves users writing to the wrong place — and you only find out when the first device's cache expires.
What works: putting the new version on a clean address (a subdomain no browser has ever visited, where no cache exists), redirecting the old address to it, and revoking the old database's public key so that any ghost app gets an error instead of writing in silence.
What you don't need to do#
This is the most important section, because it's where the market is confidently wrong.
You don't need to rewrite everything. The outcome of the case behind this article is the opposite: after the audit, the fixes and the migration, the client went back to evolving his own product with the same AI tool. What changed was what sat underneath.
You don't need to change tools or architecture on principle. An architecture with no server of its own — a front end talking directly to a managed database — is adequate for plenty of products, and it's what lets two founders reach a thousand users without a team. The trigger to change is scale and integration needs, not an engineer's taste.
It isn't the publishable key in the repository that will take you down. This is the most common technical mistake: finding a key in a committed file and declaring catastrophe. Supabase's documentation is explicit — the publishable key is "safe to expose online: web page, mobile or desktop app, GitHub actions, CLIs, source code", provided row level security is enabled on every table. The real security layer is the database access rule, not the secrecy of that key. Committing credentials is still bad practice — it survives in Git history, exposes the infrastructure and makes targeted attacks easier. It just isn't the emergency. The emergency is the secret key, which skips every access rule and must never leave the server.
You don't need to stop the product to fix the foundation. Stabilizing what's live and building the new foundation are parallel tracks. Fixes go in through branches and review, with the product still selling.
It isn't a style audit. Lint, formatting and duplication don't belong at the top of the list. If an audit arrives with refactoring on page one and an unprotected webhook on page ten, it's selling rework.
Frequently asked questions#
Will I have to throw away what the AI already built?#
Almost never. The interface, the flows and the data model are usually the product's most valuable asset, because they were validated by real paying users. What gets replaced sits underneath: where business rules run, who may call each endpoint, who pays for the infrastructure and whether backups exist. In the app we audited, the product stayed live during and after the fixes.
Can I keep using AI after the foundation is fixed?#
Yes, and it's the most common outcome when the fix is done properly. After the audit and the migration, the client went back to editing his own product with the same AI tool — the difference is he now does it with the code on his own account, a defined path between the working branch and production, and database access rules locked down.
How long does an audit of AI-generated code take?#
For an MVP-sized product already in production, about three weeks covers the audit plus applying the critical fixes. The audit itself takes days; what consumes time is fixing without taking the product offline. A finding that is pointed out but not repaired isn't an audit, it's a quote.
What access do you need?#
Code, database and the infrastructure dashboard — all three. Without the database you can't assess access rules, which are the real security layer in an architecture with no server of its own; without the infrastructure dashboard you can't assess cost, backups or environments. With only one of the three, the result is guesswork.
Is my AI-built MVP safe to hold customer data?#
Assume it isn't until someone verifies. In the AI-built products we see, the pattern is no terms of use and no privacy policy, personal data readable by any authenticated user, and no record of who accessed what. That isn't a coding failure: it's the absence of a decision about who may see what — and nobody asked the AI for it.
Sources#
- Veracode — 2025 GenAI Code Security Report — https://www.veracode.com/blog/genai-code-security-report/
- Veracode — Spring 2026 GenAI Code Security Update — https://www.veracode.com/blog/spring-2026-genai-code-security/
- Supabase — API Keys: Publishable vs Secret — https://supabase.com/docs/guides/api/api-keys
Next step#
The product in this article is real and still live: read the Sistema Forja case, the AI-built app we audited with 1,312 active users. If you built with AI and want to know what breaks before you scale, that's exactly what we do in vibe coding diagnostics.