# Review an AI-generated Supabase migration before deployment

> Check the target project, schema diff, existing data, RLS, staging result, and actual restore option before an agent-written migration reaches production.

Canonical HTML: https://canopyide.dev/guides/review-ai-generated-supabase-migration-before-deploy
Article date: 2026-09-28

An agent can produce valid SQL that is still wrong for your live database. Imagine a PR that adds an optional `archived_at` field to project notes. The SQL might run locally while an unexpected drop, broad policy, old data value, or wrong linked project changes production behavior. Review the migration as a data change with a target and recovery plan, not just another file in the PR.

## Identify the database the agent can reach

Before applying anything, write down the current Git branch, the Supabase project reference or local endpoint, the environment variables in use, and who has credentials to run migrations. A local website preview can still point at a remote database, so the URL and app screen alone do not prove the target. Supabase documents a local migration workflow and recommends separate staging and production projects in its environment guide. Keep production credentials away from an exploratory agent session unless the work and access have been explicitly approved. In Canopy, inspect the checkout, service commands, and terminal output together; the database target still comes from the project's own configuration.

*A release path to verify; the project IDs and connection details must be checked for your own app.*

| Stage | Database target | Evidence before proceeding |
| --- | --- | --- |
| Local trial | Disposable local Supabase stack | Fresh migration applies; seeded behavior passes |
| Staging | Separate staging project | Existing-like data and app behavior survive |
| Production | Explicit production project | Approved diff, backup option, release owner, and monitoring |

## Read the SQL and compare it with the task

For the `archived_at` example, a nullable column may be all the requested feature needs. Ask why a generated diff also drops a column, replaces a table, changes a default, updates every row, or modifies an RLS policy. Supabase's migration docs say schema changes should be captured in migration files and tested locally; they also explain that dashboard changes can be diffed into SQL. Review the actual SQL and migration order, not only the agent's summary or a green TypeScript build. Confirm how existing notes, empty values, and clients running the previous app version behave. If a migration changes access policy, use a cross-user test before calling it safe.

- List every table, column, index, function, trigger, grant, and policy changed by the migration.
- For each data update or deletion, state which rows are affected and how that was measured in a safe environment.
- Ask whether old and new app versions can coexist during deployment; plan an ordered rollout if they cannot.

## Run it on disposable data and staging

Apply the migration to a fresh local database from the repository's migration history and run the feature checks there. Then test against a staging database with representative, non-sensitive rows and existing schema, because a blank local database may miss conflicts or bad assumptions about old data. Supabase's environment guide shows a CI path that tests PRs and releases schema changes to staging before production. Record the migration file, resulting schema, sample row counts, and the app behavior that was exercised. A test that only confirms SQL executes is weaker than checking that an existing note remains readable and its owner cannot see another team's note.

- Verify both the new archive behavior and the unchanged read/edit flow.
- Check a failure path, such as a null or legacy value, with known fixtures.
- Keep test and production projects, keys, and datasets visibly distinct in the release record.

## Verify recovery before choosing a release window

Ask which backup or point-in-time recovery option is actually enabled for the production Supabase project, how current its latest restore point is, and who can perform a restore. Supabase's backup documentation shows that availability differs by plan; free-tier projects may need a deliberate exported backup, and a restore can make the project unavailable while it runs. Database backups do not include Storage API objects themselves. A Git revert of the migration file is not a database restore, and a destructive data change may not be undone by deploying old app code. If recovery is unclear, stop the production change and assign an owner to make it real before proceeding.

- Record the backup time, retention, expected data-loss window, and restore owner.
- For an existing paid product, identify writes that could arrive during rollback or restore.
- Do not run a production restore as a casual test; verify the procedure on a disposable project where possible.

## Release and inspect the final state

Have the responsible owner approve the exact migration and target project. Supabase recommends using a CI/CD pipeline for production migrations rather than applying them from a developer laptop. After the migration runs, verify the recorded version, app read/write behavior, RLS denial cases if affected, and service logs. Then compare the production schema and app commit with the reviewed PR. If a later agent revision changes the SQL, repeat the affected local and staging checks. The general PR guide covers comment and CI review; this guide supplies the database evidence for that decision.

- Record the migration version and production project reference without copying credentials.
- Watch for errors and unexpected row counts after rollout.
- Keep the reviewer, deployment owner, and recovery owner explicit.

## Copyable resources

### Migration review record

Fill with project references and results, never passwords or service-role keys.

````text
PR and latest commit: [ ]
Requested data behavior: [ ]
Migration files and affected objects: [ ]
Local project/branch and migration result: [ ]
Staging project and representative-data result: [ ]
Existing rows checked before/after: [ ]
RLS and cross-user test if policy changed: [ ]
Old app / new schema coexistence decision: [ ]
Production project reference verified by: [ ]
Backup or PITR option, latest restore point, restore owner: [ ]
Approved production execution path and window: [ ]
Post-deploy version, app checks, logs, and owner: [ ]
````

## Frequently asked questions

### If the migration ran locally, is it ready for production?

Not yet. Test with representative existing data and confirm the production target, app behavior, access rules, and recovery option.

### Can I revert the PR to undo a bad migration?

Reverting application code does not automatically restore deleted or transformed database data. Plan a database-specific correction or restore with the responsible owner.

### Does Supabase always have a recent automatic backup?

Backup availability and retention depend on the project's plan and settings. Verify the actual project and restore point before deployment; do not assume a local reset or Git history is a production backup.

### Can an agent run the production migration for me?

The execution route is a repository and operations decision. Review the exact SQL, target, access, staging result, and recovery plan before authorizing production credentials or a release pipeline.

## Sources and further reading

- [Supabase database migrations and local test workflow](https://supabase.com/docs/guides/local-development/database-migrations)
- [Supabase staging and production environment workflow](https://supabase.com/docs/guides/deployment/managing-environments)
- [Supabase backup availability and restore limits](https://supabase.com/docs/guides/platform/backups)
- [Supabase Row Level Security and grants](https://supabase.com/docs/guides/database/postgres/row-level-security)
- [Canopy current-main README and release caveat](https://github.com/FluidWorksApp/canopy-ide/blob/main/README.md)

## Related Canopy pages

- [How to review an AI-generated access-control PR](https://canopyide.dev/guides/review-ai-generated-access-control-pr.md)
- [How to review an AI-generated pull request](https://canopyide.dev/guides/review-ai-generated-pull-requests.md)
- [My coding agent committed an API key. What now?](https://canopyide.dev/guides/coding-agent-committed-api-key-to-github.md)
- [How do I start my website, API, and worker with one click?](https://canopyide.dev/use-cases/one-click-local-dev-stack.md)
- [Can I launch my AI-built app? A founder's decision sheet](https://canopyide.dev/guides/ai-built-app-launch-checklist-for-founders.md)

Canopy runs installed coding CLIs; CLI accounts, model selection, and provider billing remain separate. Check the installed release before relying on version-specific behavior.
