How to Stop AI From Wiping Your App's Database: A 7-Step Backup and Safe-Changes Guide for Vibe Coders
Your app has real users now. Their accounts, their saved work, maybe their payments all live in one database. And the same AI agent that builds your features can also run commands against that database. One bad command, like a migration that drops a table or a "reset" pointed at the wrong project,

Your app has real users now. Their accounts, their saved work, maybe their payments all live in one database. And the same AI agent that builds your features can also run commands against that database.
One bad command, like a migration that drops a table or a "reset" pointed at the wrong project, can erase data you cannot get back. Git can undo code mistakes. It cannot undo lost user data.
This guide fixes that in an afternoon: a backup you control, proof that it restores, a separate database for the AI to experiment on, and settings that keep your agent away from production. The examples use Supabase, which many Lovable, Bolt, v0, Cursor and Claude Code apps run on, with notes for Lovable Cloud and Replit.
Here is what the official docs say, as of October 2026:
Ask yourself: "If my database disappeared right now, what is the newest copy I could get back?" If the answer is "none" or "not sure", do Step 2 today.
On Supabase, use the CLI commands from Supabase's own backup-and-restore guide. You need the Supabase CLI and Docker Desktop installed (the CLI runs the dump inside Docker). Get the connection string from the Connect button on your project dashboard. Supabase recommends the Session pooler string by default.
Save this as backup.sh in your project folder:
#!/usr/bin/env bash # Backs up roles, schema and data into a dated folder. # Usage: DB_URL="your-session-pooler-connection-string"./backup.sh set -e STAMP = $( date +%Y-%m-%d_%H%M ) mkdir -p "backups/ $STAMP " supabase db dump --db-url " $DB_URL " -f "backups/ $STAMP /roles.sql" --role-only supabase db dump --db-url " $DB_URL " -f "backups/ $STAMP /schema.sql" supabase db dump --db-url " $DB_URL " -f "backups/ $STAMP /data.sql" --use-copy --data-only -x "storage.buckets_vectors" -x "storage.vector_indexes" echo "Backup saved in backups/ $STAMP " Enter fullscreen mode Exit fullscreen mode Then keep it out of Git, because these files contain your users' data:
chmod +x backup.sh echo "backups/" >>.gitignore Enter fullscreen mode Exit fullscreen mode The connection string contains your database password. Never paste it into a public repo, a screenshot, or an AI chat.
On Lovable Cloud, go to More > Database > Manage > Settings, click Export data, then Export and Start export. Lovable emails you when it is ready and saves it to your project's Storage. Download it and keep it somewhere outside Lovable, since its docs warn that removing the database deletes the export too. Download important Storage files separately from More > Storage.
On Supabase, create a new empty project to restore into. The Free plan allows 2 active projects, so this can be free. Install psql (the Supabase guide has instructions for Mac and Windows), then run the restore command from that guide, using the new project's connection string:
psql \ --single-transaction \ --variable ON_ERROR_STOP = 1 \ --file roles.sql \ --file schema.sql \ --command 'SET session_replication_role = replica' \ --file data.sql \ --dbname "PASTE-THE-NEW-PROJECT-CONNECTION-STRING" Enter fullscreen mode Exit fullscreen mode Run it from inside the dated backup folder. Then compare row counts for your most important tables in both projects, using the SQL editor. Replace the table names with your own ( profiles and projects are just examples):
select 'profiles' as table_name, count ( * ) from public. profiles union all select 'projects', count ( * ) from public. projects; Enter fullscreen mode Exit fullscreen mode If the numbers match, you have a real backup. If the restore errors out, the Supabase guide has a troubleshooting section (for example, for errors mentioning supabase_admin ), plus an extra key-copy step if you use Supabase Vault.
Now delete this test project, because it holds a full copy of real user data. Create a fresh one and restore only roles.sql and schema.sql (leave out the --command and data.sql lines). That empty copy becomes your dev database in Step 4.
The safest rule in this whole guide: the AI builds against a dev database, never against production.
Habit: before anything touches data, check which project ref is in your connection string or.env.
Raw SQL fired off by an AI leaves no record. Migration files give you something to read before anything runs. With the Supabase CLI:
# 1. Create a new, empty migration file supabase migration new add_plan_to_profiles # 2. Let the AI (or you) write the SQL into that file, then test it locally. # "db reset" here rebuilds your LOCAL database only. supabase db reset # 3. Compare local and remote migration history supabase migration list # 4. See exactly what would be applied, without applying it supabase db push --dry-run # 5. Only after a fresh backup (Step 2), apply it supabase db push Enter fullscreen mode Exit fullscreen mode Before step 5, read the migration file. You are not checking every line, just scanning for red-flag words:
drop table drop column truncate delete from... (with no where) alter column... type rename db reset --linked db push --include-all migration repair Enter fullscreen mode Exit fullscreen mode Two deserve a special warning. Supabase's CLI docs say db reset with --linked or --db-url runs a script that drops all user-created entities in the remote database. And if migration list shows lots of local migrations with no remote match, stop: a push may try to apply old files you did not expect. One r/Supabase post from April 2026 describes exactly that, an agent running db push that replayed old migrations, including DROP TABLE, against a live project.
For destructive changes, prefer an additive version: add the new column, copy the data, switch the app over, and remove the old column later, after a backup.
On Lovable Cloud, its docs say Lovable refuses changes like dropping or renaming a table or column, or changing a column's type, and adds to the database instead. That behavior is controlled by the agent permission Execute backward incompatible database migrations. Leave it at the default, or set it to Ask each time so you see the SQL first. Avoid Always allow.
Prompt rules shape what the AI tries. Settings decide what it can do. Use both.
Supabase MCP server. Supabase's docs offer two URL options: project_ref (limit it to one project) and read_only=true (run queries as a read-only Postgres user). Scope it to dev:
https://mcp.supabase.com/mcp?project_ref=YOUR_DEV_PROJECT_REF Enter fullscreen mode Exit fullscreen mode If the AI must look at production, use a separate read-only connection:
https://mcp.supabase.com/mcp?project_ref=YOUR_PROD_PROJECT_REF&read_only=true Enter fullscreen mode Exit fullscreen mode Claude Code. Add deny rules to.claude/settings.json in your project. Claude Code enforces these itself, whatever the model decides:
{ "permissions": { "deny": [ "Bash(supabase db push *)", "Bash(supabase db reset *)", "Bash(supabase link *)", "Bash(npx supabase db push *)", "Bash(npx supabase db reset *)", "Bash(psql *)" ] } } Enter fullscreen mode Exit fullscreen mode The npx lines matter: Claude Code's docs explain that a rule only matches the command as written. The same docs say deny rules are not a full security boundary, so the dev project and read-only MCP still matter.
Cursor. In Settings > Agents > Approvals & Execution, avoid Run Everything, which runs every command without approval. Auto-review or Allowlist are safer, but Cursor's docs say neither is a security boundary.
Everyone. Add these rules to your AGENTS.md, CLAUDE.md, or Cursor rules file:
Database safety rules: - Never run commands against the production database. - Never run: supabase db push, supabase db reset --linked, migration repair, or any DROP, TRUNCATE, or DELETE without a WHERE clause. - All schema changes go in a new file in supabase/migrations/. Stop after writing it and tell me what it does in plain English. - Flag anything that deletes data, drops or renames columns, or changes types. - Never ask me to paste database passwords or connection strings into chat. Enter fullscreen mode Exit fullscreen mode Step 7: Automate backups and schedule a restore drill Supabase Free: Supabase has an official guide, "Automated backups using GitHub Actions", with a workflow that runs the same three db dump commands every day at midnight (UTC, since GitHub schedules use UTC).
It reads the connection string from a GitHub secret named SUPABASE_DB_URL and commits the dump files. Supabase's guide warns: "Never backup your data to a public repository." Use a private repo dedicated to backups. Supabase Pro: daily backups are automatic.
Still export weekly, because deleting the project deletes its backups. Lovable Cloud: daily backups are automatic. Export before any big change, and download it.
Then add a monthly calendar reminder, "Restore drill": restore the latest backup into a throwaway project (Step 3), compare row counts, then delete it. On the Free plan's 2-project limit, pause your dev project first. It is the only way to know your backups still work.
To set up the workflow, paste this into your AI tool:
Read Supabase's guide "Automated backups using GitHub Actions" (supabase.com/docs/guides/deployment/ci/backups). Create the periodic backup workflow from that guide in.github/workflows/backup.yml, but trigger it only on schedule (daily) and workflow_dispatch, not on push or pull_request. Do not put any connection string in the file.
Tell me exactly which GitHub secret to create and confirm the repo must be private. Do not run anything. Enter fullscreen mode Exit fullscreen mode Common mistakes Trusting a backup you never restored.
Do the Step 3 test once and the monthly drill after that. Forgetting Storage files. Database backups do not include uploads.
Download them separately. Running db reset while linked to production. Locally it is harmless.
With --linked it wipes the remote database. Saving backups in a public repo. Backups contain emails and personal data.
Restoring to an old backup without exporting first. A restore erases everything after that point, so export the current state before you roll back. Your action summary Today:
None of this slows you down. It just means that the next time an AI agent gets too confident with your database, you lose a few minutes instead of your users' data.