The original design (docs/design/original-design-notes.md §12) specified Alembic migrations driven by the registry-merged metadata. The schema registry is now implemented (src/hdh/core/schema_registry.py), but its migration story is a deliberate lightweight stand-in: get_engine() auto-adds missing nullable extension columns to existing SQLite files via ALTER TABLE ADD COLUMN (SchemaRegistry.ensure_columns).
That covers the common case — a schema module adding nullable columns — but not:
- column drops, renames, or type changes
- non-nullable columns with defaults / backfills
- index changes declared in entity specs
- non-SQLite backends (the trace DB already supports Postgres via
HDH_TRACE_DB; the clinical DB should too eventually)
The task: wire Alembic exactly as §12 designed it —
alembic init + an env.py whose target_metadata comes from bootstrap_schema() (the bootstrap sequence in §13 is the key: the registry must run in the Alembic process so merged metadata includes all module columns)
- The three-step workflow from the design: edit a module's
schema/entities/*.json → alembic revision --autogenerate -m "module: add column" → alembic upgrade head
- Decide the relationship between
ensure_columns and Alembic: keep the auto-ADD path for the zero-setup practitioner flow, gate it off when an alembic_version table exists, or replace it outright — document the choice
- Docs: a migrations section in ARCHITECTURE.md §3 and the ontology guide
Where to look
src/hdh/core/schema_registry.py — bootstrap_schema(), ensure_columns()
docs/design/original-design-notes.md §12–§13 — the original Alembic + bootstrap design
tests/test_schema_registry.py — module fixtures you can reuse for migration tests
Definition of done: autogenerate produces a correct migration when a schema module adds a column; upgrade applies it to an existing DB; the practitioner zero-setup path still works; just qa green.
The original design (docs/design/original-design-notes.md §12) specified Alembic migrations driven by the registry-merged metadata. The schema registry is now implemented (
src/hdh/core/schema_registry.py), but its migration story is a deliberate lightweight stand-in:get_engine()auto-adds missing nullable extension columns to existing SQLite files viaALTER TABLE ADD COLUMN(SchemaRegistry.ensure_columns).That covers the common case — a schema module adding nullable columns — but not:
HDH_TRACE_DB; the clinical DB should too eventually)The task: wire Alembic exactly as §12 designed it —
alembic init+ anenv.pywhosetarget_metadatacomes frombootstrap_schema()(the bootstrap sequence in §13 is the key: the registry must run in the Alembic process so merged metadata includes all module columns)schema/entities/*.json→alembic revision --autogenerate -m "module: add column"→alembic upgrade headensure_columnsand Alembic: keep the auto-ADD path for the zero-setup practitioner flow, gate it off when analembic_versiontable exists, or replace it outright — document the choiceWhere to look
src/hdh/core/schema_registry.py—bootstrap_schema(),ensure_columns()docs/design/original-design-notes.md§12–§13 — the original Alembic + bootstrap designtests/test_schema_registry.py— module fixtures you can reuse for migration testsDefinition of done: autogenerate produces a correct migration when a schema module adds a column; upgrade applies it to an existing DB; the practitioner zero-setup path still works;
just qagreen.