It died on its first real use, on a production server, before running a single
statement:
error: Cannot find module './plugin-schemas.gen' from officer_db/src/schema.ts
It imported `officerdb/db`, which imports `schema.ts`, which imports the
gitignored `plugin-schemas.gen.ts`. That file does not exist on a fresh clone —
which is exactly the state every machine this script is FOR is in. It had been
tested against a scratch database on a machine where the barrel happened to
exist, so the one condition that mattered was the one condition never tested.
A migration issues ALTER statements. It has no business needing the
application's schema barrel, its table objects or its query layer. It now opens
its own `postgres` connection and imports none of them.
Tested the way it failed: barrel moved out of the tree, script run against a
scratch database built in the old shape. Renames the table, the column, both
indexes and all three CHECK constraints, keeps the rows, and the idempotent
path still no-ops. Verified by reading pg_indexes and pg_constraint afterwards
rather than trusting the exit code.
Deployed to edge-pertento today with two real users. Nine grants migrated
intact, old table gone, permissions page confirmed in the browser. The only
casualty was a minute lost to this bug, because the database had not been
touched when it failed — the import blew up before the first query, which is
the one place a crash costs nothing.
`bun db:push` was already immune: it runs scripts/gen-plugin-schemas.ts first.
That fix existed because the same trap was found earlier today in the setup
path. It was not applied here because I did not think of this script as
something that runs on a fresh clone, which is precisely what it is.