Database migrations
Schema changes are Prisma migrations, checked into git under packages/db/prisma/migrations/. In production they're applied by the one‑shot db-migrate container, which runs prisma migrate deploy and exits.
db-migrateshowingExitedindocker compose psis correct — it's a run‑once job, not a long‑running service.
Golden rule: migrate before deploying code that needs the column
New service code that queries a new column will crash if the column doesn't exist yet. Always: add the migration → run it → then deploy the service.
Creating a migration (local)
cd packages/db
node_modules/.bin/prisma migrate dev --name <change_name> # generates + applies locally
This writes prisma/migrations/<timestamp>_<change_name>/migration.sql. Commit the whole folder. (Migrations are additive and safe by default — adding nullable columns or columns with a constant default doesn't rewrite the table on Postgres.)
Applying in production
DC="docker compose -f docker-compose.yml -f docker-compose.prod.yml"
git pull origin main
$DC build db-migrate # rebuild so the new migration file is in the image
$DC up db-migrate # runs `prisma migrate deploy`, then exits
# verify the migration name in the output, exit code 0
Then rebuild the services that use the new schema (their Prisma client is regenerated at build):
$DC build --no-cache <service> && $DC up -d --no-deps <service>
Data backfills
One‑off data fixes live in packages/db/prisma/backfills/*.sql and are not run by prisma migrate deploy. Run them by hand after the migration, with psql inside the postgres container:
$DC exec -T postgres psql -U axon -d axon_db < packages/db/prisma/backfills/<file>.sql
# sanity check
$DC exec postgres psql -U axon -d axon_db -c "SELECT collection_status, count(*) FROM funding_coverages GROUP BY 1;"
Worked example — the collection_status change
This is the exact sequence used to ship the Instant Funding collection tracking:
- Add the enum + columns to
schema.prisma(CoverageCollectionStatus,collectionStatus @default(PENDING),collectedAt, index). - Create the migration
..._funding_coverage_collection_status(additive:CREATE TYPE,ALTER TABLE … ADD COLUMN … DEFAULT 'PENDING',CREATE INDEX). - Commit + push.
- On server:
$DC build db-migrate && $DC up db-migrate. - Run the backfill so already‑swept coverages are marked
COLLECTED(and aren't re‑swept). - Rebuild + redeploy
service-funding(new sweeper/watcher).
Rollback
Prisma migrations roll forward. To undo a schema change, write a new migration that reverses it. Dropping columns is the risky direction — for an additive column that nothing else reads, it's safest to leave it in place and just revert the code.