Without a migration tool, schema changes are applied by hand through a database GUI or cloud console — changes that are invisible to version control, not reproducible across environments, and impossible to roll back systematically. When the production schema diverges from the development schema, bugs surface only in production. ISO 25010 recoverability requires that the system can be restored to a known state; without a migration history, the schema cannot be reliably reconstructed after a failure. Prisma's db push shortcut is specifically not a migration tool — it applies schema changes without creating a history file, meaning it cannot be used to reproduce or audit schema evolution.
High because schema changes without version control cannot be audited, replicated across environments, or rolled back — any schema divergence between environments causes hard-to-diagnose bugs.
Set up a migration tool that matches your ORM and commit all migration files to version control. For Prisma, switch from db push to migrate dev for development and migrate deploy for production.
# Prisma — create migration from schema changes
npx prisma migrate dev --name add_user_role_column
# Apply migrations in production
npx prisma migrate deploy
# .github/workflows/deploy.yml — run migrations before deploying
- name: Run database migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
For Supabase, use supabase migration new <name> to create versioned SQL files in supabase/migrations/. Never apply schema changes through the Supabase dashboard without capturing them in a migration file.
ID: database-design-operations.migration-versioning.migration-tool-present
Severity: high
What to look for: Enumerate every migration file and check for the presence of a migration framework and its artifacts. Prisma: look for prisma/migrations/ directory containing timestamped migration directories. Drizzle Kit: look for drizzle/ or a configured output directory in drizzle.config.*. Knex: look for migrations/ directory and knexfile.*. TypeORM: look for src/migrations/ or configured migration directory. Sequelize: look for migrations/ directory and sequelize-cli configuration. Raw SQL: look for a migrations/ or db/migrations/ directory with versioned .sql files (e.g., 001_create_users.sql, 20240101000000_add_email_index.sql). Supabase: look for supabase/migrations/ directory. Also check package.json scripts for migration-related commands: migrate, db:migrate, db:push, migration:run, prisma migrate.
Pass criteria: A migration tool is configured and has at least 1 migration file. Schema changes are tracked through versioned migrations. Package scripts exist for running migrations.
Fail criteria: No migration directory exists. No migration tool in dependencies. Schema managed by manually running SQL in a database GUI or cloud console. db:push (Prisma's schema-push mode) used as the only schema management approach in production (db:push doesn't create migration history).
Skip (N/A) when: N/A — always applicable for SQL databases (PostgreSQL, MySQL, SQLite). For NoSQL databases (MongoDB), check for schema evolution tooling if applicable.
Detail on fail: Specify what is missing. Example: "No migration directory found. Prisma is in use but only 'prisma db push' found in package scripts — no migration history." or "No migration tool in dependencies. No migration directory. Schema appears to be managed manually.".
Remediation: Set up migration tooling appropriate for your ORM:
# Prisma — create and run migrations
npx prisma migrate dev --name init # creates migration, applies to dev DB
npx prisma migrate deploy # applies pending migrations in production
# Drizzle Kit
npm install -D drizzle-kit
npx drizzle-kit generate # generates SQL migration from schema changes
npx drizzle-kit migrate # applies migrations
# Supabase — local migration workflow
supabase migration new create_users_table
supabase db push # apply to remote
For raw SQL, establish a naming convention and use a migration runner (e.g., node-pg-migrate, golang-migrate, flyway, or a custom script that tracks applied migrations in a schema_migrations table).