From f5f13f09611400f188d9829d3a5e756dff2e47f6 Mon Sep 17 00:00:00 2001 From: Anto Subash Date: Mon, 19 Oct 2026 13:18:48 +0200 Subject: [PATCH 01/14] docs(migrations): describe the real multi-root, multi-head graph and pin it with a test (#503) Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4 --- CLAUDE.md | 22 +++-- docs/database/migrations.md | 50 +++++++++--- host/tests/test_migration_graph.py | 127 +++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 17 deletions(-) create mode 100644 host/tests/test_migration_graph.py diff --git a/CLAUDE.md b/CLAUDE.md index 87987f9d9..0f3077caf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -275,19 +275,27 @@ dependency + `get_csrf_token(request)` as a view prop, echoed as `X-CSRF-Token` never by importing `tenants`. `docs/framework/multi-tenancy.md`. - **Migrations** live in `host/migrations/versions/`, never in module packages. `host/migrations/env.py` builds metadata from every installed module and runs - `ensure_db_extensions` first. The history has **several heads** (one per - labelled branch), so apply with `upgrade heads` (what `make migrate` does) - and autogenerate against one branch, since plain `revision --autogenerate` - refuses with "Multiple heads": + `ensure_db_extensions` first. The history is **not** one linear chain: it has + two roots (`77162e7b184b` initial schema, `e36ab09c4a92` tenants) and four + heads (`audit_log`, `tenants`, `keycloak`, and the users trunk, which Alembic + reports as `api_tokens`). Apply with `upgrade heads` (what `make migrate` + does); plain `revision --autogenerate` refuses with "Multiple heads", so name + the branch: ``` uv run --project host alembic -c host/alembic.ini revision --autogenerate \ -m "" --head @head ``` - A module's first revision sets `branch_labels = ("",)` (older - modules lack it); the label is a named target, not a per-module rollback: - `downgrade @base` walks everything beneath it. + Labels are inherited by every descendant and are only named targets, not + per-module rollbacks: `downgrade