Join the discussion on Telegram
Why this matters
Two migrations add the same three columns to Stream:
backend/prisma/migrations/20260428000000_add_pause_state_fields/migration.sql adds isPaused, pausedAt, totalPausedDuration.
backend/prisma/migrations/20260428161500_add_stream_pause_fields/migration.sql adds the identical isPaused, pausedAt, totalPausedDuration again (plus a Stream_isPaused_idx index), using plain ADD COLUMN (no IF NOT EXISTS).
On a fresh database prisma migrate deploy applies them in order and the second one fails with column "isPaused" of relation "Stream" already exists. This is the production deploy path: render.yaml startCommand is npm run prisma:deploy.
Separately, two migration folders share the exact timestamp prefix 20260428000000 (_add_pause_state_fields and _add_stream_event_unique_constraint). Prisma orders migrations lexicographically by folder name, so identical prefixes make ordering ambiguous and fragile.
CI hides this because it uses prisma db push (which diffs the schema directly) rather than replaying the migration history.
Acceptance criteria
Files to touch
backend/prisma/migrations/20260428000000_add_pause_state_fields/migration.sql
backend/prisma/migrations/20260428161500_add_stream_pause_fields/migration.sql
backend/prisma/migrations/20260428000000_add_stream_event_unique_constraint/ (rename for ordering)
Out of scope
- The
migration_lock.toml sqlite/postgres mismatch (tracked separately).
- Adding new schema fields.
Join the discussion on Telegram
Why this matters
Two migrations add the same three columns to
Stream:backend/prisma/migrations/20260428000000_add_pause_state_fields/migration.sqladdsisPaused,pausedAt,totalPausedDuration.backend/prisma/migrations/20260428161500_add_stream_pause_fields/migration.sqladds the identicalisPaused,pausedAt,totalPausedDurationagain (plus aStream_isPaused_idxindex), using plainADD COLUMN(noIF NOT EXISTS).On a fresh database
prisma migrate deployapplies them in order and the second one fails withcolumn "isPaused" of relation "Stream" already exists. This is the production deploy path:render.yamlstartCommand isnpm run prisma:deploy.Separately, two migration folders share the exact timestamp prefix
20260428000000(_add_pause_state_fieldsand_add_stream_event_unique_constraint). Prisma orders migrations lexicographically by folder name, so identical prefixes make ordering ambiguous and fragile.CI hides this because it uses
prisma db push(which diffs the schema directly) rather than replaying the migration history.Acceptance criteria
prisma migrate deploysucceeds end-to-end. Recommended: keep one migration as the source of truth for the pause-state columns and drop/neutralise the redundantADD COLUMNs in the other (preserving theStream_isPaused_idxindex exactly once).20260428000000_*migrations distinct, correctly-ordered timestamp prefixes (or otherwise guarantee deterministic ordering) without rewriting already-applied history on existing environments.npx prisma migrate deployagainst a fresh Postgres DB applies all migrations cleanly andprisma migrate statusshows no drift.schema.prisma(runprisma migrate diffordb push --accept-data-losson a throwaway DB to compare).Files to touch
backend/prisma/migrations/20260428000000_add_pause_state_fields/migration.sqlbackend/prisma/migrations/20260428161500_add_stream_pause_fields/migration.sqlbackend/prisma/migrations/20260428000000_add_stream_event_unique_constraint/(rename for ordering)Out of scope
migration_lock.tomlsqlite/postgres mismatch (tracked separately).