fix(backend): freeze F11 matrix inline in the initial migration (MA3)

Code-review MAJOR MA3. The initial Alembic migration imported the live
`mimic.rbac.matrix.GROUP_PERMISSIONS` to seed the `permission` / `group` /
`group_permission` rows. That breaks the Alembic invariant "a migration
produces the same schema regardless of when you replay it": a future tweak
to the runtime matrix would silently change the seeded baseline on a fresh
DB.

Two changes:

1. The migration now carries an *inline frozen snapshot* of the F11 matrix
   (`_PERMISSIONS_FROZEN`, `_GROUP_PERMISSIONS_FROZEN`, `_GROUP_DESCRIPTIONS`).
   The seed reads from these tuples/dicts only. If the canonical matrix
   evolves, the next migration is responsible for the delta.

2. A new unit test `test_migration_seed_matches_current_matrix` enforces
   that the frozen seed equals the runtime `Permission` enum and
   `GROUP_PERMISSIONS` mapping. Drift now fails CI loudly with a hint to
   write a new migration instead of editing the existing one.

Also: docstring no longer mentions `ttp_version` (M8 follow-up).
This commit is contained in:
knacky
2026-05-22 05:24:37 +02:00
parent feadad850b
commit 36c1ed5ffb
2 changed files with 116 additions and 28 deletions

View File

@@ -0,0 +1,39 @@
"""MA3: the frozen RBAC seed in the initial migration must keep matching
the runtime F11 matrix in `mimic.rbac.matrix`. When they drift, *do not* edit
the migration in place — write a new migration. This test enforces it.
"""
from __future__ import annotations
import importlib
from mimic.rbac.matrix import GROUP_PERMISSIONS, GroupName, Permission
def _load_migration():
return importlib.import_module("mimic.db.migrations.versions.202605210001_initial_schema")
def test_frozen_permission_list_matches_runtime() -> None:
migration = _load_migration()
runtime_codes = {p.value for p in Permission}
frozen_codes = set(migration._PERMISSIONS_FROZEN)
assert runtime_codes == frozen_codes, (
"Permission enum drifted from the migration freeze; "
"write a new migration, do not edit the existing one."
)
def test_frozen_group_membership_matches_runtime() -> None:
migration = _load_migration()
runtime = {gn.value: {p.value for p in perms} for gn, perms in GROUP_PERMISSIONS.items()}
frozen = {gn: set(perms) for gn, perms in migration._GROUP_PERMISSIONS_FROZEN.items()}
assert runtime == frozen, (
"GROUP_PERMISSIONS drifted from the migration freeze; "
"write a new migration, do not edit the existing one."
)
def test_frozen_group_names_match_enum() -> None:
migration = _load_migration()
assert set(migration._GROUP_PERMISSIONS_FROZEN.keys()) == {g.value for g in GroupName}