parity(api): declare _goldbank_migrations as an ignored model; drift now zero

Prisma migrate diff proposed DROP TABLE "_goldbank_migrations" because the
table exists in the database but was not declared in the schema. Declaring
it with @@ignore removes the proposal without exposing it to Prisma Client,
and the table and all its rows are kept.

Correcting the earlier DEAD-07 note: this is not a leftover from the
pre-Prisma port. It is the tracking table of the application's own
migration runner (src/prisma/migrate.ts:5), which exists because the Docker
deploy image is copy-only and ships no Prisma CLI, so migrate deploy cannot
run in the container (migrate.ts:7-13). The project therefore keeps two
ledgers deliberately: _prisma_migrations for the CLI in development, and
_goldbank_migrations for the runtime runner in the container. That runner
already filtered out any DROP of its own table (migrate.ts:190-196); the
schema declaration removes the cause rather than relying on that guard.

The practical consequence, recorded in DECISIONS.md D15: a new migration
must be safe under both paths, so its SQL stays idempotent.

The ledger grew 12 -> 14 rows while testing, with nothing deleted: starting
the API ran prepareDatabase(), which appended the two migrations applied
earlier today. Its $$-aware statement splitter handled the PL/pgSQL trigger
body correctly — trigger and function are both present and the 9 trigger
assertions pass against the live database.

Also records the UTF-8 testing rule: Persian test input must come from a
file, never a shell argument, because the Windows shell replaces Persian
characters with '?' and a test can then pass while storing '????'.

Verified: migrate diff -> "This is an empty migration" (zero drift);
migrate status -> up to date; tsc clean; 32 jest; 9 trigger assertions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-09-22 08:25:03 +03:30
co-authored by Claude Opus 5
parent 8133a2bdf4
commit 654b98520d
4 changed files with 147 additions and 5 deletions
+25 -3
View File
@@ -974,10 +974,10 @@ model CustomerOtp {
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
/// bcrypt hash of the 4-digit code. Never the code itself.
codeHash String
expiresAt DateTime
codeHash String
expiresAt DateTime
/// Failed verify attempts against THIS challenge.
attempts Int @default(0)
attempts Int @default(0)
/// Set when the code is accepted, so one challenge cannot be reused.
consumedAt DateTime?
@@ -989,3 +989,25 @@ model CustomerOtp {
@@index([customerId])
@@index([expiresAt])
}
/// Bespoke migration ledger left by the EARLIER, pre-Prisma port.
///
/// It predates Prisma Migrate in this repo and holds 12 historical rows
/// (`0001_init.sql`, `0002_admin_schema.sql`, `seed:initial`, and the early
/// `2026091…` migrations). It is the only record of how that port was applied,
/// so it is **kept and never written to or deleted from** (DEAD-07).
///
/// It is declared here purely so `prisma migrate diff` stops proposing
/// `DROP TABLE "_goldbank_migrations"` — an undeclared table reads as drift.
/// `@@ignore` keeps it out of Prisma Client: nothing in the application should
/// ever read or write it, and Prisma Migrate will not manage its shape either.
///
/// Prisma's own ledger is `_prisma_migrations`, which is separate and is never
/// edited by hand (D14).
model goldbank_migrations {
name String @id
appliedAt DateTime @default(now()) @map("applied_at") @db.Timestamptz(6)
@@map("_goldbank_migrations")
@@ignore
}