feat: add institutional governance and recovery contracts

This commit is contained in:
2026-08-01 17:46:54 +02:00
parent b65b48832b
commit 7192d32e65
61 changed files with 12539 additions and 168 deletions
+47
View File
@@ -18,6 +18,8 @@ from sqlalchemy import create_engine, inspect, text
from govoplan_core.core.migrations import MigrationMetadataPlan, migration_metadata_plan
from govoplan_core.core import change_sequence as core_change_sequence_models # noqa: F401 - populate core metadata
from govoplan_core.core import recovery as core_recovery_models # noqa: F401 - populate core metadata
from govoplan_core.core import runtime_coordination as core_runtime_models # noqa: F401 - populate core metadata
from govoplan_core.security import credential_envelopes as core_credential_models # noqa: F401 - populate core metadata
from govoplan_core.core.change_sequence import ChangeSequenceEntry, ChangeSequenceRetentionFloor
from govoplan_core.core.module_management import load_startup_enabled_modules, startup_candidate_module_ids
@@ -590,6 +592,51 @@ def database_revision(database_url: str | None = None) -> str | None:
engine.dispose()
def database_migration_heads(
database_url: str | None = None,
) -> tuple[str, ...]:
url = database_url or settings.database_url
engine = create_engine(url)
try:
with engine.connect() as connection:
return tuple(
sorted(MigrationContext.configure(connection).get_current_heads())
)
finally:
engine.dispose()
def configured_migration_heads(
database_url: str | None = None,
*,
enabled_modules: tuple[str, ...] | list[str] | None = None,
manifest_factories: tuple[ManifestFactory, ...] = (),
migration_track: str | None = None,
) -> tuple[str, ...]:
config = alembic_config(
database_url=database_url,
enabled_modules=enabled_modules,
manifest_factories=manifest_factories,
migration_track=migration_track,
)
return tuple(sorted(ScriptDirectory.from_config(config).get_heads()))
def database_is_at_configured_heads(
database_url: str | None = None,
*,
enabled_modules: tuple[str, ...] | list[str] | None = None,
manifest_factories: tuple[ManifestFactory, ...] = (),
migration_track: str | None = None,
) -> bool:
return database_migration_heads(database_url) == configured_migration_heads(
database_url,
enabled_modules=enabled_modules,
manifest_factories=manifest_factories,
migration_track=migration_track,
)
def _has_columns(inspector, table_name: str, required: set[str]) -> bool:
try:
actual = {column["name"] for column in inspector.get_columns(table_name)}