fix: make the migration chain runnable from an empty database

0001 called Base.metadata.create_all(), building the schema from the
current models, so on a fresh PostgreSQL 0002 collided on
datasets.raw_sha256 and `alembic upgrade head` could never run from zero.

0001 is now an explicit, frozen baseline: the seven base tables exactly as
the real history created them, before 0002/0006 extended them. Databases
already past 0001 never re-run it. Proof: a fresh `upgrade head` produces a
schema identical (pg_dump --schema-only) to the long-lived dev database.

0019 repairs a latent bug found by that comparison: 0006 used
server_default="now()" as a string, which PostgreSQL froze at the instant
the column was created, so every Agent and Job got the same created_at.
It also adds three indexes the models declare but no migration created.

central/tests/test_migration_baseline.py guards (via AST) against
migrations importing the models or using string timestamp defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-23 00:30:51 -03:00
co-authored by Claude Opus 5.5
parent ce606b04cc
commit a11209d123
4 changed files with 207 additions and 6 deletions
+9 -3
View File
@@ -121,9 +121,15 @@ Agents with `central/scripts/register_agent.py` (see below).
`docker exec <postgres-container> pg_dump -U gti gti_fiscal > backup.sql`
(or `pg_dumpall` for the whole cluster) on whatever schedule your
operations policy requires.
- Migrations are additive-only so far (`0001`..`0006`); always run
`alembic upgrade head` (the container does this automatically) rather than
hand-editing the schema.
- Always run `alembic upgrade head` (the container does this automatically)
rather than hand-editing the schema. An **empty** database is initialized
by that same command — never with `alembic stamp` or `create_all`. `0001` is
an explicit, frozen baseline (it used to call `Base.metadata.create_all()`,
which made `0002` collide on `datasets.raw_sha256` on any fresh database);
`central/tests/test_migration_baseline.py` keeps that from coming back.
- `0019` repairs `agents.created_at/updated_at` and `jobs.created_at`, whose
defaults `0006` had frozen at the instant it ran (rows created before `0019`
keep that frozen value — their real creation time is not recoverable).
### HTTPS / reverse proxy