| name | prisma-migration |
| description | Change the Prisma schema and create an incremental migration the standard Prisma way (migrate dev for local, migrate deploy for prod), then regenerate the client and seed. Use whenever editing backend/prisma/schema.prisma or adding/altering DB tables, columns, indexes, or enums. |
Prisma schema change → incremental migration
This repo uses standard incremental Prisma migrations (append-only history).
Each schema change adds a NEW migration; never edit a migration that's already
applied/committed. Run from backend/ with the dev DB + Redis up (docker compose -f docker-compose.dev.yml up -d).
Steps
- Edit
prisma/schema.prisma. Conventions:
relationMode = "prisma" → NO DB foreign keys. Add @@index on relation
scalar fields manually (e.g. @@index([packageId])).
- Money columns:
Decimal @db.Decimal(12, 2), not Float.
- Scalar list defaults:
String[] @default([]).
- Create + apply the migration (generates the delta SQL, applies it to the dev
DB, and regenerates the client):
bun run prisma:migrate # = prisma migrate dev (prompts for a name)
# or non-interactive:
bunx prisma migrate dev --name <descriptive_snake_case_name>
This creates prisma/migrations/<timestamp>_<name>/migration.sql — commit it.
- Review the generated
migration.sql (Prisma may need guidance on renames vs
drop+add, data-preserving changes, etc.). If it would lose data, adjust the schema
approach or add a follow-up data migration — don't hand-edit an applied one.
- Seed new reference data in
prisma/seed.ts / prisma/seed-*.ts (idempotent
upserts keyed on a unique column), then bun run db:seed.
- Typecheck:
bun run build — Decimal columns become Prisma.Decimal; fix consumers.
- Deploy (CI/prod, applies pending migrations in order):
bun run prisma:deploy
(= prisma migrate deploy). On an existing DB never reset; to adopt baseline
migrations use bunx prisma migrate resolve --applied <name>.
If you edited the schema without migrating yet (e.g. exploring), run
bun run prisma:generate to refresh the client. migrate dev already does this.
Keep migration_lock.toml intact (provider = "postgresql").