from __future__ import annotations from pathlib import Path from govoplan_core.core.institutional import CAPABILITY_MANDATE_RESOLVER from govoplan_core.core.module_guards import ( drop_table_retirement_provider, persistent_table_uninstall_guard, ) from govoplan_core.core.modules import ( CapabilityDocumentation, DocumentationLink, DocumentationTopic, MigrationSpec, ModuleContext, ModuleInterfaceProvider, ModuleManifest, PermissionDefinition, RoleTemplate, ) from govoplan_core.core.provider_governance import declared_module_architecture from govoplan_core.db.base import Base from govoplan_mandates.backend.db import models as mandate_models from govoplan_mandates.backend.service import SqlMandateResolver MODULE_ID = "mandates" MODULE_NAME = "Mandates" MODULE_VERSION = "0.1.15" READ_SCOPE = "mandates:definition:read" WRITE_SCOPE = "mandates:definition:write" ADMIN_SCOPE = "mandates:definition:admin" def _permission(scope: str, label: str, description: str) -> PermissionDefinition: module_id, resource, action = scope.split(":", 2) return PermissionDefinition( scope=scope, label=label, description=description, category="Mandates", level="tenant", module_id=module_id, resource=resource, action=action, ) def _router(_context: ModuleContext): from govoplan_mandates.backend.router import router return router def _resolver(_context: ModuleContext) -> SqlMandateResolver: return SqlMandateResolver() manifest = ModuleManifest( id=MODULE_ID, name=MODULE_NAME, version=MODULE_VERSION, optional_dependencies=("organizations", "idm", "access", "policy", "audit"), provides_interfaces=( ModuleInterfaceProvider(name="mandates.definition", version="0.1.0"), ModuleInterfaceProvider(name="mandates.resolution", version="0.1.0"), ), permissions=( _permission(READ_SCOPE, "View mandates", "View mandate definitions, history, and resolution evidence."), _permission(WRITE_SCOPE, "Manage mandates", "Create and revise mandate definitions."), _permission(ADMIN_SCOPE, "Administer mandates", "Administer mandate lifecycle and recovery."), ), role_templates=( RoleTemplate( slug="mandate_manager", name="Mandate manager", description="Manage institutional mandate and jurisdiction definitions.", permissions=(READ_SCOPE, WRITE_SCOPE), ), RoleTemplate( slug="mandate_reader", name="Mandate reader", description="Inspect mandate definitions and resolution evidence.", permissions=(READ_SCOPE,), ), ), route_factory=_router, capability_factories={CAPABILITY_MANDATE_RESOLVER: _resolver}, capability_documentation={ CAPABILITY_MANDATE_RESOLVER: CapabilityDocumentation( label="Mandate resolver", summary="Resolves effective institutional competence deterministically and fail-closed.", contract_version="0.1.0", ) }, migration_spec=MigrationSpec( module_id=MODULE_ID, metadata=Base.metadata, script_location=str(Path(__file__).with_name("migrations") / "versions"), retirement_supported=True, retirement_provider=drop_table_retirement_provider( mandate_models.MandateRevision, label="Mandates", ), retirement_notes="Destructive retirement requires a database snapshot and removes immutable Mandate history.", ), uninstall_guard_providers=( persistent_table_uninstall_guard( mandate_models.MandateRevision, label="Mandates", ), ), documentation=( DocumentationTopic( id="mandates.definition-and-resolution", title="Institutional mandates", summary="Define and resolve effective authority, jurisdiction, legal basis, and evidence.", body=( "Mandates stores immutable revisions and resolves the one effective authority for a task. " "Conflicting or missing authority fails closed. Consequential consumers retain the exact revision and evidence." ), layer="configured", documentation_types=("admin", "user"), audience=("user", "operator", "module_admin", "auditor"), links=( DocumentationLink( label="Mandates domain and recovery", href="govoplan-mandates/docs/MANDATES_DOMAIN.md", kind="repository", ), ), ), ), architecture=declared_module_architecture( layer="institutional_foundation", kind="domain", maturity="vertical_slice", documentation_ref="docs/MANDATES_DOMAIN.md", test_ref="tests/test_mandates.py", known_limits=("No dedicated WebUI is included; administration is API-first.",), supported_authority_modes=("native_authoritative",), owned_concepts=("mandate", "jurisdiction authority", "competence history"), non_owned_concepts=("organization structure", "function incumbency", "application permission", "formal decision"), reference_packages=("product.service-to-decision",), migration_docs=("docs/MANDATES_DOMAIN.md",), recovery_docs=("docs/MANDATES_DOMAIN.md",), security_docs=("docs/MANDATES_DOMAIN.md",), operations_docs=("docs/MANDATES_DOMAIN.md",), ), ) def get_manifest() -> ModuleManifest: return manifest __all__ = [ "ADMIN_SCOPE", "MODULE_ID", "MODULE_NAME", "MODULE_VERSION", "READ_SCOPE", "WRITE_SCOPE", "get_manifest", "manifest", ]