Source code for cadrumo.domain.calculations.registry.setup_profile_bindings

"""Registry-backed setup and wizard binding declarations.

The setup surface has several consumers which need the same answer-to-profile
coordinates: the core answer projector, deadline profile construction, the
Typer option surface, and page decoration.  They all resolve this small
catalogue through one mapping-fact seam so none of those consumers becomes a
second home for the declarations.

This module deliberately keeps resolution lazy.  Importing the core answer
model must remain possible before the bundled authority is initialised; a
consumer resolves the authored catalogue only when it actually projects or
renders a setup value.
"""

from __future__ import annotations

from ....core.time.clock import today_madrid
from .errors import RegistryValidationError
from .facts.resolution import MappingFactQuery, ResolvedMappingFact
from .governed_fact_scope import GovernedFactSource, governed_facts_in_scope
from .schema_references import LegalReferenceKind

_SETUP_FACT_ID = "-".join(
    (LegalReferenceKind.LEY.value, "49", "2002", "profile", "binding", "catalogue"),
)


[docs] def mapping_fact_entries(fact_id: str, *, authority: GovernedFactSource | None = None) -> dict[str, str]: """Resolve one string mapping fact and return its exact entries. The returned mapping is copied at the boundary; the authority remains the only source of the declarations and no Python fallback is retained when a required entry is absent. """ from .schema_base import DateAxis selected_authority = authority or governed_facts_in_scope() if selected_authority is None: raise RegistryValidationError("setup mapping fact requires an explicit authority operation or scope") resolved = selected_authority.resolve_governed_fact( MappingFactQuery( fact_id=fact_id, date_axis=DateAxis.FILING_PERIOD, effective_date=today_madrid(), ), ) if not isinstance(resolved, ResolvedMappingFact): raise TypeError(f"{fact_id!r} must resolve as a mapping fact") entries: dict[str, str] = {} for entry in resolved.payload.entries: if not isinstance(entry.key, str) or not isinstance(entry.value, str): raise RegistryValidationError(f"{fact_id!r} must contain string mappings") if entry.key in entries: raise RegistryValidationError(f"{fact_id!r} contains duplicate key {entry.key!r}") entries[entry.key] = entry.value return entries
[docs] def setup_answer_declarations( *, authority: GovernedFactSource | None = None, ) -> dict[str, tuple[str, type[str] | type[bool], str | None]]: """Return answer-field profile bindings from the setup catalogue.""" declarations: dict[str, tuple[str, type[str] | type[bool], str | None]] = {} prefix = "setup.field." for key, encoded in mapping_fact_entries(_SETUP_FACT_ID, authority=authority).items(): if not key.startswith(prefix): continue parts = encoded.split("|", 2) if len(parts) != 3 or parts[1] not in {"str", "bool"}: raise RegistryValidationError(f"invalid setup answer declaration {key!r}") path, value_type, default_token = parts if not path: raise RegistryValidationError(f"setup answer declaration {key!r} has no profile path") declarations[key.removeprefix(prefix)] = ( path, bool if value_type == "bool" else str, default_token or None, ) if not declarations: raise RegistryValidationError("setup answer catalogue has no setup.field declarations") return declarations
[docs] def profile_field_bindings(*, authority: GovernedFactSource | None = None) -> dict[str, str]: """Return profile-field names and their canonical persisted paths.""" prefix = "profile.field." return { key.removeprefix(prefix): value for key, value in mapping_fact_entries(_SETUP_FACT_ID, authority=authority).items() if key.startswith(prefix) }
[docs] def wizard_page_declarations(*, authority: GovernedFactSource | None = None) -> dict[str, dict[str, str]]: """Return page format/widget declarations keyed by page ID.""" prefix = "wizard.page." pages: dict[str, dict[str, str]] = {} for key, value in mapping_fact_entries(_SETUP_FACT_ID, authority=authority).items(): if not key.startswith(prefix): continue page_key, _, attribute = key.removeprefix(prefix).rpartition(".") if not page_key or attribute not in {"format_hint", "widget_kind"}: raise RegistryValidationError(f"invalid wizard page declaration {key!r}") pages.setdefault(page_key, {})[attribute] = value return pages
__all__ = [ "legal_source_kind_declarations", "mapping_fact_entries", "profile_field_bindings", "setup_answer_declarations", "wizard_page_declarations", ]