aeat.adapters.persistence.profile.usage_ratios module

Encrypted secure-object persistence for UsageRatioProfile.

These load / save helpers are the persistence adapter behind the pure usage_ratios register. A usage-ratio profile is stored as an Envelope-wrapped encrypted byte object via SecureObjectRepository at SensitivityClass FINANCIAL; no plaintext profile JSON or envelope file lands on disk.

Living in the persistence adapter (not in usage_ratios) keeps the SecureObjectRepository / Envelope coupling out of the domain layer: the domain package owns only the pure UsageRatioProfile model, the censo derivation, and the read-modify-write lock, and depends on no persistence substrate. The censo refuse-load guard composes the read with the domain-pure derivation so an operator’s persisted HOME_OFFICE override is refused on any disagreement with the bound censo (no auto-migration, no silent coercion).

load_usage_ratios(*, bucket_id, objects=None)[source]

Load one bucket’s persisted UsageRatioProfile, or return an empty one.

Parameters:
Return type:

UsageRatioProfile

save_usage_ratios(profile, *, bucket_id, objects=None)[source]

Persist one bucket’s usage-ratio profile in the encrypted database.

Parameters:
Return type:

None

load_usage_ratios_with_censo_guard(*, bucket_id, raw_afectacion_ratio, year=2025, objects=None)[source]

Load a usage-ratio profile and refuse on censo disagreement.

Calls load_usage_ratios() and then enforces the binding- censo invariant for HOME_OFFICE_SUMINISTROS and HOME_OFFICE_OWNERSHIP categories: every persisted override must equal the censo-derived value (raw_afectacion_ratio * statutory_multiplier). When the operator has not yet captured a censo snapshot, any persisted HOME_OFFICE override is refused as well, since there is no legally-grounded reference to validate against.

The refusal is a clean break: no auto-migration, no silent coercion, no warning-and-continue. The calling surface (calculate / verify / file / build_draft / approve_draft / export_draft) must therefore surface the underlying CensoRatioMismatchError to the operator so they can re-run aeat config profile censo pull + apply or unset the diverging override.

Parameters:
  • bucket_id (str) – Active workflow bucket id.

  • raw_afectacion_ratio (Decimal | None) – office_m2 / total_m2 from the bound censo snapshot, or None if the operator has not yet applied a censo.

  • year (int) – Registry year whose proportionality rules drive the derivation.

  • objects (SecureObjectRepository | None) – Optional injected SecureObjectRepository (testing seam).

Return type:

UsageRatioProfile

Returns:

The persisted UsageRatioProfile when no HOME_OFFICE override disagrees with the censo.

Raises:

CensoRatioMismatchError – When at least one persisted HOME_OFFICE override disagrees with the censo-derived value, or when any persisted HOME_OFFICE override exists with raw_afectacion_ratio unset.