From 5d9b2c03fb6bdd28e4c233a35005c709cdd3760c Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sun, 13 Sep 2026 21:41:28 +0200 Subject: fix(hub): the migration chain runs, and a test says so MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `add_email_verification` wrote PostgreSQL's `(now() at time zone 'utc')` as a literal server default, where every other migration in the chain uses `sa.func.now()` and lets the dialect render it. On SQLite that is `sqlite3.OperationalError: near "at": syntax error` — so `meshbay-hub migrate` could not reach head on the database the suite and the documented local-hub workflow both use. Which is how it survived: the only test that ran alembic at all stopped at `c3d4e5f6a7b8`, the revision immediately before it. The two newest migrations — email verification, and the mail quota committed two days ago — had been run by exactly one thing, a production deploy, and the newest by nothing at all. `test_migrations_reach_head.py` upgrades to head and compares what that built against `Base.metadata`, both directions: a column in the models and in no migration never reaches production, and one in the migrations and in no model is a rename abandoned halfway. Both tests fail on the unfixed migration with the error above; the drift half was checked by adding a model column on purpose and watching it be named. The schemas agree today. It still does not check PostgreSQL-only behaviour — a default, an index type or a constraint one dialect accepts and the other refuses. Running the chain somewhere beats running it nowhere, and is not the same as running it where it ships. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01UMxEQadpzPkYLFf5CYKhpW --- CLAUDE.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'CLAUDE.md') diff --git a/CLAUDE.md b/CLAUDE.md index 10792aa..528ee0e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -639,7 +639,19 @@ do. Read them before writing anything that touches the same mechanism. reaches the deployed hub. Symptom: one endpoint answering 500 with an HTML body while everything else works, and a `psycopg` `UndefinedColumn` in the journal. `deploy-hub.sh` runs `alembic upgrade head` before restarting the service; a schema - change that skips a migration file will still pass every test you have + change that skips a migration file used to pass every test there was. + **`test_migrations_reach_head.py` is the one that does not**: it upgrades to head + on SQLite and compares what that built against `Base.metadata`, in both + directions. It could not have existed before 2026-09-13, because + `add_email_verification` wrote PostgreSQL's `(now() at time zone 'utc')` as a + literal server default — a syntax error on SQLite — so the chain could not reach + head on the only database the suite has, and the single test that ran alembic + stopped at the revision before it. The two newest migrations had therefore been + run by exactly one thing: a production deploy. **A server default goes in + `sa.func.now()`**, which the dialect running it renders; a dialect's own SQL + written out by hand is a migration that only one database can apply. What this + still does not check is PostgreSQL-only behaviour — running the chain somewhere + beats running it nowhere and is not the same as running it where it ships - **Some paths only exist in a browser, and only one browser has them.** The download-to-disk story is three different mechanisms — File System Access -- cgit v1.2.3