Migrations
How Handlet manages Supabase schema changes safely.
Database migrations version-control schema changes and apply them consistently across environments.
In Handlet, migration history is strict and forward-only:
- Existing files in
apps/web/supabase/migrationsare immutable once they exist on the target branch - Follow-up database changes must be shipped in a new later-timestamped migration
apps/web/supabase/schemasholds the current intended schema;migrations/is the historical record of how it evolved
Creating a Migration
Update the declarative schema first, then generate a new migration:
pnpm --filter web supabase:db:diff
This will generate a new migration file in the apps/web/supabase/migrations directory based on the differences between your local database and the schema files.
If you realize an earlier migration needs to change, do not edit or rename it. Restore the old migration exactly as it exists on the target branch, keep the intended schema update in schemas/, and generate a new migration for the delta.
Applying Migrations
To apply pending migrations to your local database:
pnpm supabase:web:migration:up
Migration Best Practices
- Test migrations locally before applying them elsewhere.
- Add indexes for foreign keys and frequently queried columns.
- Include RLS policies in the same migration as table creation.
- Never rewrite migration history after a migration exists on the target branch.
- Regenerate TypeScript database types after schema changes.
Local Enforcement
Run the local discipline check before pushing any schema or migration changes:
pnpm run check-db-discipline-local
This resolves the local merge base from your upstream branch, with origin/develop and origin/main as fallbacks, then runs the same migration and RLS guards used in CI.
The repository also installs a managed pre-push hook on pnpm install to run this automatically. In GitHub, branch protection should require the db-discipline status check for main and develop.
Resetting the Database
To completely reset your local database with the latest schema:
pnpm supabase:web:reset
This will drop all tables and reapply all migrations from scratch.