Use caseCustom software
Taking a vibe-coded app to production: secure data, reliable billing, maintainable code
An audit and hardening path for Lovable, Bolt and v0 apps with paying users: Supabase RLS, leaked keys, Stripe webhooks, tests and a keep-or-rebuild call.
A blueprint, not a client story. The business described is illustrative; the architecture, integrations and trade-offs are real, and this is how I would build it. By Ergini, .
The short version
A fixed-scope engagement that takes an app built with Lovable, Bolt, v0 or Replit from 'works in the demo' to safe for paying users. I audit the Supabase row-level security policies, secrets, data model and Stripe billing, fix whatever exposes data or money first, then add tests on the flows that earn money, migrations, backups, error tracking and a GitHub-to-Vercel pipeline. A coding agent speeds up the reading and drafting; I review every change, and the founder decides what is kept or rebuilt.
- Best for
- Founders with paying users on an app generated in Lovable, Bolt, v0 or Replit, and no engineer who has read the code.
- Connects to
- Lovable, Bolt or v0, Supabase, Stripe, Vercel, GitHub, Sentry
- The AI does
- A coding agent reads the generated codebase end to end, maps every table, policy and endpoint, and drafts tests and fixes on a branch.
- People do
- I verify every finding and review every change before it merges; the founder decides what is kept, refactored or rebuilt, and when production changes.
- Built as
- MVP Development, usually $5K - $22K
Three hundred accounts on an app nobody has read
Say you run a scheduling and invoicing app for small cleaning companies, built over one winter in Lovable. Supabase holds the data: companies, their customers' addresses and key-safe codes, job schedules, invoices. Stripe Checkout sells a monthly plan, and 300 accounts pay for it. You are not a developer, and until now you have not needed one.
The week looks different now. Each prompt to the builder fixes one screen and quietly changes another, and the credits go on asking for the same fix a third time. Stripe shows a customer charged twice for one upgrade, and another who paid but still sees the trial banner. A franchise with 40 locations wants to sign, and its IT team has sent a security questionnaire whose first question is who can read which data. You cannot answer it, because you have never seen the code.
None of this means the app is bad. Generated code is usually a reasonable first draft: the screens work and users like them. What it lacks is the part a demo never shows: rules about who may read which rows, billing that survives retries, a safe way to change code, and a backup someone has actually restored. Fiverr's Business Trends Index recorded a 61% rise in demand for vibe coding help, comparing November 2025 to April 2026 with the six months before. Building got easier. The part after building did not.
What a generated codebase usually hides
Each of these is invisible in a demo and obvious once someone looks. They are the first things I check, in this order.
Row-level security that is off, or on and meaningless
Supabase serves your tables to the browser through its public API, and the anon key that unlocks it ships in every copy of your front end, by design. RLS policies are all that stands between that key and your data. Generated apps often leave RLS off on some tables, or add a policy whose condition is simply true. Worse is a policy that trusts a role column users can edit themselves.
A secret key in the browser bundle
The service-role key and Stripe or OpenAI secret keys sometimes end up in client-side variables because that made a feature work. Anything prefixed VITE_ or NEXT_PUBLIC_ is readable in the browser's developer tools. A key deleted from the code still sits in the git history, so the fix is rotation, with the call moved into an edge function.
Access granted on the success page
Checkout redirects to a success page, and that page flips the account to paid. Users who close the tab early pay and get nothing; if the page never checks the session with Stripe, anyone who opens the URL gets the plan free. Access should follow signed webhook events such as checkout.session.completed and customer.subscription.deleted.
Webhooks processed twice
Stripe can deliver an event more than once, and in live mode it retries a failed delivery for up to three days. The fix is a table of processed event IDs with a unique constraint: insert first, act only if the insert succeeded, in one transaction. Events also arrive out of order, so the handler reads the current subscription from Stripe instead of trusting the event's copy.
No migrations, and one database for everything
The schema was edited in the dashboard and by the builder, so no file describes it, and Vercel previews use the production database. Test clicks create real rows, and schema changes meet paying users first. The fix is a baseline migration pulled with the Supabase CLI, a staging project, and separate environment variables for previews.
An AI feature with no limits
An edge function calling OpenAI with no check on who calls or how often lets one script spend a month's budget in an afternoon, and a crafted message can pull out the bot's instructions or, with unscoped retrieval, other accounts' records. Per-account caps and the prompt injection patterns close it. For EU users, Article 50 of the AI Act also requires saying it is an AI, since 2 August 2026.
An audit's first afternoon, in tool calls
The first day is mostly checks that produce evidence rather than opinions, here on the cleaning-company app above.
Audit day one, illustrative project
- list_tables(schema: "public", show: "rls")14 tables / row-level security off on 3: jobs, job_notes, invoices_archive
- probe_rls(table: "customers", as: "test user B", key: "anon")2,418 rows returned from 297 other companies / policy condition: true
- scan_bundle(site: "production", patterns: "secret key formats")OpenAI key found in assets/index-3f9c.js, set through VITE_OPENAI_KEY
- scan_git_history(tool: "gitleaks")Stripe secret key committed 11 Feb, deleted 12 Feb, still in history
- reconcile_billing(source: "stripe", days: 30)412 checkouts / 9 accounts upgraded twice / 3 paying accounts still flagged as trial
- check_recovery(project: "production")daily backups on / no restore ever tested / no staging project
Ergini · Slack, to the founder
Two things today, before anything else. Anyone signed in can read every company's customers, key-safe codes included, so I am shipping a policy fix with a test this evening and nothing else. And the OpenAI and Stripe keys are exposed, so let's rotate them together at 18:00. Everything else waits for the written report.
- Policy fix merged behind a probe test. Keys rotated. API logs kept for the founder's GDPR assessment.
How the engagement runs, and where the coding agent is allowed
The model here is a coding agent that reads and drafts. It never holds production credentials, and nothing it writes reaches users without tests and my review. After Replit's AI agent deleted a live production database during a code freeze in 2025, that is a rule, not a preference.
01 Trigger · GitHub, Supabase, Vercel, Stripe
Read-only access first
The GitHub repository or an export from the builder, Supabase and Vercel as a team member, and a Stripe restricted key that can only read. The first pass changes nothing.
02 AI model · Claude Code on a local clone
Map the codebase
Claude Code reads every route, component, edge function and SQL file and drafts an inventory: which tables each screen touches, where the browser queries Supabase directly, where money and personal data move. I check the map against the running app.
03 Plain code · gitleaks, npm audit, Supabase advisors
Run the checks that produce evidence
Secret scanning over the full git history, a scan of the built bundle, a dependency audit, Supabase's security advisor, and RLS probes that sign in as two test users and try to read each other's rows.
04 Decision
Rank each finding by what it can cost
Severity follows fixed rules, not how alarming a summary sounds.
- Personal data readable across accounts, or a secret key exposed then fixed the same day behind a test, keys rotated
- Money at risk: duplicate grants, access without payment then first week of stabilization
- Slows change: no tests, no migrations, tangled components then the keep, refactor or rebuild list
05 Person
The founder decides what to keep
A written report gives each finding with its evidence, fix and effort. You decide per area what is kept, refactored or rebuilt, and can stop after the audit.
06 Plain code · GitHub Actions, Supabase CLI, Sentry
Stabilize before anything else changes
Playwright tests on signup, checkout and the core workflow, RLS probes in CI, a baseline migration, a staging project, Sentry, and one real restore from backup. The agent drafts much of it; I review every line.
07 System · Stripe, Supabase edge functions, Vercel
Harden what production will face
Signature-checked, idempotent Stripe webhooks with a nightly reconciliation, rate limits on signup, login and AI endpoints, and the auth edge cases: email changes, password resets, redirect URLs that allow any domain.
08 Result
Hand over something you own
The pipeline, a runbook for incidents and restores, a note on which parts are safe to keep prompting, and every credential in your accounts, not mine.
Shipping a change, before and after the pipeline
The builder stays useful. What changes is the path from an idea to a paying user's screen.
Prompt and publish
- A prompt changes the screen you asked about, and sometimes files you did not
- Publishing sends it straight to the production site and the production database
- Schema changes happen in the dashboard, with no record of what changed
- Customers find the bugs and report them by email, days later
- Undoing means asking the builder to revert and hoping it remembers how
With a pipeline
- Every change arrives as a pull request, whether it came from the builder, the agent or a person
- A Vercel preview runs it against the staging database with seeded test accounts
- CI runs the RLS probes, the payment tests and a migration dry run before merge is allowed
- Sentry reports the first production error with the user and the release attached
- Undoing is Vercel's instant rollback to the previous build
Keep, refactor or rebuild, part by part
The honest answer is rarely 'rebuild everything'. Each part gets its own verdict.
| Part of the app | Usually kept when | Rebuilt when |
|---|---|---|
| Screens and components | They render correctly and the logic behind them is thin | Business rules live inside React components and are copied across pages |
| Data model | Tables map cleanly to accounts, users and the core objects | It cannot represent teams, several locations or roles without workarounds |
| Access policies | Every table has a policy tied to the account, and the probes pass | Policies are missing, allow everything, or trust data the user can edit |
| Billing | Checkout and the portal are Stripe's own, and access follows webhooks | Access is set on the success page, or plan logic is spread through the front end |
| Edge functions | Each one checks who is calling and handles failures | They use the service-role key for everything and trust the request body |
| The AI feature, if any | Calls go through a server with per-account limits | The key is in the browser, or retrieval is not scoped to the account |
Who writes the fixes, who checks them, who decides
The coding agent makes reading and drafting faster. It never decides what is safe.
The AI model
Map routes, tables, queries and policies
Reading tens of thousands of generated lines quickly is where a coding agent earns its keep.
Draft tests and first-pass fixes on a branch
Drafts are cheap. A test the agent weakened to make it pass is exactly what review looks for.
Plain code
Secret scans, bundle scans and RLS probes
Evidence is binary: the key is in the bundle or it is not, user B can read the row or cannot.
CI gates on every pull request
Tests, type checks and a migration dry run decide what merges, whoever wrote the change.
Nightly Stripe reconciliation
Compares who has paid with who has access, and alerts on any mismatch in either direction.
A person
Review every change before it merges
Code from the builder or the agent gets the same review as a junior developer's pull request.
Decide keep, refactor or rebuild per part
It is the founder's roadmap and money; the report supplies evidence, not the decision.
Decide whether an exposure must be reported
Under GDPR that is a legal judgment with a clock on it, taken by the founder with advice.
Keep prompting, pay for a rebuild, or audit first?
If the app has a handful of users, no payments and no personal data worth stealing, keep iterating in Lovable, Bolt or v0. A founder who can prompt screens into shape should not pay a developer to do it more slowly. If an audit comes back clean, the advice is the same, plus a few tests on the parts that matter.
A full rebuild by an agency or a hired team makes sense when the product has proven itself and the generated code is the wrong foundation: a data model that cannot represent teams, or rules smeared across hundreds of components. Your current app is then the best specification anyone could write. What a rebuild quote rarely says is which half of the app was fine.
For most founders with paying users, the cheapest way to decide is a senior audit first. It fixes the dangerous findings in the first days and turns 'is my app okay?' into a list with evidence, severity and effort, which you can hand to me, to an agency or to a future hire. The trade-offs between builders and custom code are laid out in no-code vs custom MVP, and the stack I harden towards is the one in the SaaS MVP tech stack.
How you would know it is working
A blueprint has no results to report, so here is what I would measure from the first week instead, on your own data.
- Cross-account probe results
- RLS probes passing in CI, one per table holding account data, with zero reads across accounts. Binary per table, which is the point.
- Payment and access mismatches
- From the nightly Stripe reconciliation: paying accounts without access and unpaid accounts with it. Both should stay at zero.
- Errors on the money paths
- Sentry errors per day on signup, checkout and the core workflow, from the day it is installed.
- Change failure rate
- Deploys that need a hotfix or rollback. If it does not fall once the pipeline exists, the tests cover the wrong things.
- Restore time
- How long a full restore takes in a drill, measured before handover and then quarterly.
What a build like this costs
This is built as MVP Development, which runs $5K - $60K overall. A build like this one usually lands in the lean MVP tier: $5K - $22K, 2-6 weeks. The first working version runs on your real data well before the end of that window.
What it costs to run
Mostly the platforms you already pay for: Supabase, Vercel, Stripe's transaction fees and error tracking on a small plan. A staging project and point-in-time recovery add a modest monthly amount on Supabase, worth it once customer data is at stake. If the app calls a model, per-account caps keep that bill in line with paying usage.
What moves the price
- How much of the data model and the access policies must be redesigned rather than patched
- Billing complexity: one plan, or seats, trials, coupons, EU VAT and usage-based pricing
- Whether the backend can stay, or must first move off the builder's own hosting and database
- Whether an AI feature needs caps, scoped retrieval and an Article 50 disclosure
- How many roles and integrations need tests before anything can safely change
Who this is for
- Non-technical founders with paying users on an app built in Lovable, Bolt, v0, Replit or Base44
- Founders facing a customer's security questionnaire or an investor's technical due diligence
- Small teams where every prompt to the builder now fixes one thing and breaks another
- Apps on Stripe subscriptions where support has seen double charges or paid accounts without access
Questions people ask about this
Is my Lovable app production ready?
It can be, but you only know after someone checks. The screens Lovable generates are usually fine; what no builder can know is your rules, which live in Supabase policies, webhooks and edge functions. A quick first test: sign in as one test user and try to read another user's rows with the public anon key. Supabase's security advisor flags tables with RLS switched off, but only per-table probes prove a policy is correct.
Can AI fix AI-generated code?
Partly. A coding agent such as Claude Code reads a generated codebase quickly, finds the pattern behind a bug and drafts tests and fixes. It does not know what your app is supposed to allow, and it will sometimes make a failing test pass by changing the test. So I use it for speed, never unsupervised: every change goes through a pull request I review, against tests that encode your rules.
I built the whole app with AI and feel stuck. Do I have to start over?
Usually not. Generated screens are often fine to keep; the parts worth rebuilding are the ones that hold rules, such as the data model, access policies and billing. Starting over also throws away every bug your users already found and you already fixed. Feeling stuck mostly means nobody can change the code safely, and tests plus a pipeline fix that without a rewrite. The audit says, part by part, what to keep.
Can I keep building in Lovable after a developer hardens the code?
Yes, with rules. Lovable syncs with GitHub in both directions, so a prompt can rewrite a file a developer fixed. I split ownership: the builder keeps screens and components, while policies, migrations, webhooks and edge functions sit behind CI tests that fail if a regenerated file weakens them. You keep the speed of prompting and lose the ability to break the rules silently.
How much does it cost to make a vibe-coded app production ready?
It depends on what the audit finds, which is why the audit comes first and is fixed in scope. Stabilization and hardening usually sit at the lean end of MVP development, because the product already exists; redesigning billing or the data model costs more. The price block on this page shows the range, and the first call is free.
Sources