A production teardown of a Lovable-style weekend app, focused on the failure modes that appear when the first real users arrive.
The Monday failure is predictable. A weekend app built in Lovable has a clean form, a Supabase table, a model call, maybe a Stripe button, and enough polish to make the builder trust it. Then a second user signs in and sees a row they should not see. Or an Edge Function accepts a client-controlled user ID. Or the model fails after the database write and the UI reports success anyway.
This teardown keeps the article because it is the tangible version of the pivot. The production-readiness checklist tells readers what the gate is. This piece shows how a real builder would inspect one generated app without pretending the tool is the problem. Lovable's security documentation now includes built-in security scans, API key protection, database access checks, dependency audits, and security views. Supabase's current docs say RLS must be enabled for exposed schemas and distinguish publishable keys from secret keys. Those are useful rails, but rails do not prove the app's business logic is safe.
The review should feel adversarial without being theatrical. Do not ask whether the app is clever. Ask whether the main workflow completes for a non-admin user, whether data access is scoped, whether every external call leaves a trace, and whether the failure copy tells the truth.
Owner-only testing hides the most common generated-app failure.
A generated app usually works for its creator. That proves almost nothing about production. The owner account often bypasses the policy problem because the owner created every row, owns every project, and has every token in their local environment. The first serious teardown creates a second account and runs the workflow from that account with no elevated privileges.
The second-user pass should test reads, writes, updates, deletes, storage, and any API route that touches user data. In Supabase, RLS controls row access while grants control role access. Both need to be intentional. A table with RLS disabled in an exposed schema is a launch blocker. A policy that checks auth.uid() on reads but not writes is another. Storage needs the same treatment because public file URLs often escape the mental model people have for database rows.
The reviewer should not stop at schema inspection. Open the app in a browser, perform the primary action, capture the trace, then try to fetch or mutate another user's data. If the app uses Edge Functions, inspect whether the function trusts client-supplied ownership fields. If it uses a model to choose an action, inspect whether the server revalidates the action before writing. The model can suggest. The server has to enforce.
The owner and a non-owner account expose policy bugs that a solo happy path will not catch.
A browser run plus server trace proves what happened when the workflow touched model, function, and database boundaries.
Publishable keys are designed for clients. Secret or service-role credentials belong on the server only.
| Area | What to inspect | Blocker if |
|---|---|---|
| Authentication | Owner and non-owner workflow with separate sessions | The second user can see, edit, or trigger owner data |
| Database | RLS enabled, policies scoped, grants paired with policy intent | Any exposed table lacks RLS or relies on UI filtering |
| Functions | Server revalidates identity and action permissions | Client-provided IDs decide ownership or authority |
| Model output | Output is validated before storage or side effects | The model can write arbitrary fields or commands |
| Recovery | Failed provider call preserves user work | The UI reports success after partial failure |
Security views find classes of risk. The teardown maps them to user harm.
Lovable's security view is useful because it gives builders a place to see scanner findings instead of pretending generated code is safe by default. The mistake is treating a green scanner state as a product decision. A scanner can flag exposed keys, dependencies, or obvious data-access issues. It cannot know that a draft invoice should be invisible to a contractor, that a workflow should never email a customer twice, or that a failed import must keep the original file.
That is why the teardown pairs scanner output with workflow evidence. For every finding, ask which user action it touches and what harm follows. A missing RLS policy on a table that stores public templates is different from a missing RLS policy on customer financial data. A dependency warning in an unused path is different from a vulnerable package in an upload handler. The goal is not to lower the count. The goal is to remove paths where a normal user can create damage.
This is also where generated apps need explicit business rules. If the prompt says 'users can manage their projects,' the code still needs an ownership rule. If the UI hides an admin action, the server still needs an authorization check. If the model labels a record as safe, the application still needs deterministic validation for the fields that drive side effects.
The app worked for my owner account
The table is hidden behind the UI
The tool has security scans
The model picked the right action in testing
A non-owner completed the workflow without crossing data boundaries
RLS, grants, storage policies, and functions enforce the rule server-side
Scanner findings are mapped to actual user harm and closure evidence
Model suggestions are revalidated before writes or external actions
Run the owner workflow and save the trace.
Run the same workflow as a non-owner user.
Try to read, update, and delete another user's rows directly through exposed APIs.
Confirm browser bundles contain no secret or service-role credentials.
Inspect Edge Functions for client-controlled ownership and action fields.
Force the model call to fail after a database write and inspect the user state.
Attach every scanner finding to a workflow, data object, or accepted risk note.
Close P0 findings before launch, even if the UI looks done.
Use the browser first. If the main path cannot complete without developer help, the rest of the review becomes theoretical.
Move from UI to API to database. Test whether the app enforces ownership and authorization when the client stops behaving politely.
Rank by harm: data exposure, irreversible writes, invisible failures, then quality gaps. Do not mix polish with blockers.
Readers need to see the production lens applied to an app shape they recognize.
The article is viable because it gives the site a recurring format. The production checklist can feel abstract until a reader sees it pointed at a familiar object: a weekend app with generated screens, Supabase, model calls, and a launch button. That is the most common reader context for this pivot.
The article should not claim that a specific submitted app failed unless that app exists and the owner approved publication. That would be fake experience. The stronger version is a repeatable teardown method. It tells readers what evidence to send, what will be inspected, and how findings will be ranked. When real submissions arrive, future teardowns can use the same rubric without rewriting the rules each time.
The limitation is scope. This teardown does not replace penetration testing, code review, or legal review. It is a first production screen for small AI apps. That is enough value for the launch corpus because it moves the reader from 'my generated app works' to 'my generated app has evidence'.
Should a Lovable app be rebuilt before production?
Not automatically. Rebuild only when the generated structure blocks required policy, testing, observability, or deployment controls. Many apps need targeted hardening before they need a rewrite.
What is the fastest way to find data-boundary bugs?
Create a second user, run the main workflow, and try to access the first user's records through every exposed path: UI, API, storage, and serverless functions.
Can built-in security scans replace review?
No. Scans are useful inputs. The product review still has to map findings to business rules, user harm, and retest evidence.