cd /news/ai-agents/how-to-stop-ai-from-wiping-your-app-… · home › topics › ai-agents › article
[ARTICLE · art-155898] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

How to Stop AI From Wiping Your App's Database: A 7-Step Backup and Safe-Changes Guide for Vibe Coders

A developer published a seven-step guide for protecting production databases from AI coding agents, covering controlled backups, restore verification, a separate development database, and settings that keep agents away from production. The guide uses Supabase CLI dump and psql restore commands, with notes for Lovable Cloud and Replit, and stresses that Git cannot recover lost user data.

by read7 min views5 publishedOct 23, 2026

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.

plan column to profiles". drop table or truncate. Here is what the official docs say, as of October 2026:

db dump command and maintain off-site backups." Three gotchas apply almost everywhere:

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
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"

Then keep it out of Git, because these files contain your users' data:

chmod +x backup.sh
echo "backups/" >> .gitignore

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"

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;

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.

myapp-dev and myapp-prod. Your local .env points at dev. Production keys live only in your hosting dashboard (Vercel, Netlify, and so on). Supabase also offers a local database (supabase start) and paid Branching. 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:

supabase migration new add_plan_to_profiles

supabase db reset

supabase migration list

supabase db push --dry-run

supabase db push

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

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

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

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 *)"
    ]
  }
}

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.

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. 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, 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.

db reset while linked to production.--linked it wipes the remote database. Today:

backup.sh (or Lovable's export) and add backups/ to .gitignore. This week:

db push --dry-run, and back up before every push. 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.

── more in #ai-agents 4 stories · sorted by recency
── more on @supabase 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-stop-ai-from-…] indexed:0 read:7min 2026-10-23 · —