Planning a Migration Change

Wikantik's database migrations live in bin/db/migrations/. The convention is small and strict: numbered files, idempotent DDL, one schema concern per file, and never edit after production. The migrations are the only schema definition — there is no other DDL anywhere, not even for tests.

When to use this runbook

Before any commit that adds, drops, renames, or alters a database object.

Context

bin/db/migrate.sh runs the unapplied V*.sql files in order against the configured database, each inside a single transaction (psql --single-transaction), and records the version in the schema_migrations table. It runs on every bin/deploy-local.sh and bin/redeploy.sh, and the production container's entrypoint runs it before Tomcat starts and refuses to start on failure. Nothing ever reverses a migration, so the history is append-only: a bad migration is fixed with a follow-up, and rolling the application image back does not roll the schema back.

The :app_user psql variable is bound by the migrate script from DB_APP_USER — using it in GRANT statements keeps migrations portable between environments where the application role has a different name.

Tests read the same files: PostgresTestDb (the wikantik-jdbc test-jar) applies every migration to a throwaway pgvector container, so a test that needs a table is a reason to write the migration first. Never hand-write a CREATE TABLE in a test; TestSchemaSingleSourceTest fails the build if you do.

Walkthrough

The frontmatter steps are the canonical procedure. Local apply + re-apply is the cheap way to catch idempotence bugs before they hit production, and running the test class that needs the table proves the migration and the code agree.

Changing an existing column or table

Because the previous release's code may still be running against the schema (during a deploy, or after an image rollback), prefer additive migrations: add the new column or table in one migration, ship the code that uses it, and drop or rename the old object in a later migration once nothing reads it. Do not rename and drop in the same release that stops using the object.

Pitfalls

The frontmatter pitfalls capture the failure modes worth memorising. The "editing after prod" rule is the most expensive to violate — it splits the migration history between "what production has applied" and "what the source tree says was applied", and that divergence is extremely painful to recover from.


Cluster Hub: Agent Cookbook (agent-cookbook)