cadrumo.application.modelo.m036_lifecycle module¶
Modelo 036 declarative-recording contracts, storage, and event emission.
Per the accepted Modelo 036/037 foundation decision, the local app never files a
036. AEAT is the authority; the operator files the declaration through AEAT Sede or in person at
a competent AEAT office, then records that fact locally through aeat app modelo m036
{alta,modificacion,baja}. This module owns the typed application service behind
that surface: it persists encrypted declaration rows through the required
application-owned lifecycle ports, emits the matching
modelo.036.declaration.* bucket event, and exposes the same application
capability for list/view read-back.
The closed event-kind axis comes from
CensoModeloEventKind, whose values are
derived from the registry-owned censo foundation. Modelo 037 remains historical
metadata and is intentionally outside this recording surface.
See also
cadrumo.domain.calculations.registry.censo_modelosRegistry-owned Modelo 036 active-foundation and Modelo 037 historical routing.
cadrumo.entrypoints.cli._modelo_m036_cliThin Typer boundary that turns CLI verbs into these application commands.
cadrumo.domain.buckets.event.BucketEventTypeDeclares the
CENSO_DECLARATION_ALTA,CENSO_DECLARATION_MODIFICACION, andCENSO_DECLARATION_BAJAaudit events emitted here.
- derive_m036_declaration_id(*, profile_id, event_kind, declared_on, sede_justificante)[source]¶
Content-address the declaration tuple as 64-char lowercase SHA-256 hex.
The address makes a replay of the same operator-declared filing idempotent: a second invocation with identical inputs hashes to the same
declaration_idand the secure-object write becomes a no-op overwrite of the same row.sede_justificanteis folded in unmangled ("-"when omitted) so a same-day same-kind re-declaration that acquires the acuse is recorded as a distinct record, not silently coalesced with the pre-acuse draft.The
event_kindmember is aCensoModeloEventKind, so the digest can only describe one of the registry-backedalta,modificacion, orbajalifecycle events.- Return type:
- Parameters:
profile_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=36, pattern=^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$, ascii_only=None)])
event_kind (CensoModeloEventKind)
declared_on (date)
sede_justificante (str | None)
- class M036DeclarationCommand(**data)[source]¶
Bases:
BaseModelOperator request to record an M036 declaration already filed with AEAT.
The operator files the 036 through AEAT Sede or in person at a competent AEAT office. This command records that declaration locally so the downstream stale-cascade + audit-trail logic can react. The optional
sede_justificanterecords an electronic AEAT receipt when available; its absence does not prevent recording an office filing. The command MUST NOT trigger any local filing action.event_kindis typed asCensoModeloEventKind, preserving the registry foundation’s closed event set at the application boundary.- Parameters:
data (Any)
- profile_id: ProfileId¶
- event_kind: CensoModeloEventKind¶
- declared_on: date¶
- sede_justificante: str | None¶
- note: str | None¶
- exception M036DeclarationNotFoundError(message=None, *, context=None, translated_message=None)[source]¶
Bases:
CadrumoErrorRaised when a requested M036 declaration does not exist.
- Parameters:
- Return type:
None
- code¶
- exception M036DeclarationAmbiguousError(message=None, *, context=None, translated_message=None)[source]¶
Bases:
CadrumoErrorRaised when an M036 declaration prefix addresses multiple records.
- Parameters:
- Return type:
None
- code¶
- class M036DeclarationResult(**data)[source]¶
Bases:
BaseModelOutcome of a successful declaration-recording call.
Carries the content-addressed declaration id (SHA-256 over the derived tuple), the canonical event-kind, the declared date, the bucket scope of the record, and the timestamp at which the local record was written. The
bucket_idfield bridges the persistence capability’s bucket cross-check when loading and saving records (it refuses payloads whose bucket disagrees with the repository binding). Downstream consumers (stale-cascade engine, profile-state re-derivation) read these fields to decide what to recompute.The record is the payload model for the application-owned declaration repository capability.
- Parameters:
data (Any)
- declaration_id: ContentDigest¶
- bucket_id: BucketId¶
- profile_id: ProfileId¶
- event_kind: CensoModeloEventKind¶
- declared_on: date¶
- sede_justificante: str | None¶
- note: str | None¶
- recorded_at: datetime¶
- list_m036_declarations(*, bucket_id, ports)[source]¶
Return every recorded M036 declaration in the active bucket.
Reads through the same declaration capability the write path persists into (no parallel read path), enumerating the encrypted rows scoped to
bucket_idand returning the typedM036DeclarationResultrecords verbatim — every persisted field (declaration_id,event_kind,declared_on,recorded_at,sede_justificante,note) is preserved, never collapsed to a flat mapping. An empty bucket returns an empty tuple, the clean “no declarations recorded yet” signal, not an error.- Return type:
- Parameters:
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
ports (M036LifecyclePorts)
- read_m036_declaration(declaration_id, *, bucket_id, ports)[source]¶
Return one recorded M036 declaration by id or unambiguous prefix.
Reads through the owning declaration capability, resolving the full content-addressed
declaration_idor an unambiguous prefix of it to a single typedM036DeclarationResult. Raises the repository’s not-found error for an unknown id and the ambiguous-prefix error when a prefix matches more than one record, mirroring the established secure-object id-or-prefix resolution.- Return type:
- Parameters:
declaration_id (str)
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
ports (M036LifecyclePorts)
- record_m036_declaration(command, *, bucket_id, ports)[source]¶
Persist an M036 declaration record and emit its BucketEvent.
Records an M036 declaration already filed through AEAT Sede or in person at a competent AEAT office. The local app NEVER files; this verb only records the operator’s declaration so downstream profile-state re-derivation and stale-cascade reasoning can react. An optional
sede_justificanterecords electronic receipt evidence, so its absence does not prevent recording an office filing. The content-addresseddeclaration_idkeeps a re-declaration with the identical tuple idempotent; the parallelBucketEvent(one ofBucketEventType.CENSO_DECLARATION_ALTA/CENSO_DECLARATION_MODIFICACION/CENSO_DECLARATION_BAJA) carries the audit-trail entry the composition-service rule requires alongside the data write, saved via the bucket-event capability supplied inports.The persisted
M036DeclarationResultis encrypted into the bucket-local declaration row keyed bym036-declaration:<bucket_id>:<declaration_id>via the declaration repository capability (shared with thelist_m036_declarations()/read_m036_declaration()read-back surface through_m036_declaration_repository()).bucket_idis checked against the repository binding at save time, so a cross-bucket payload cannot land silently.- Parameters:
command (
M036DeclarationCommand) – The declaration command naming the profile, event kind, declared-on date, and optional electronic justificante.bucket_id (
str) – The bucket to persist into; checked againstcommand.profile_idbefore anything is derived or stored.ports (
M036LifecyclePorts) – Bucket-bound persistence and event capabilities used by the declaration lifecycle.
- Raises:
LiveApplicationInputError – If
command.profile_idnames a different profile thanbucket_id. A bucket identity IS the profile UUID that owns it, so the two must agree before anything is derived, stored, or emitted.Modelo036PriorAltaRequiredError – If
modificacionorbajais requested with no declaration on record yet. Checked, and refused, before anything is derived, stored or emitted.Modelo036TerminalStateError – If the latest recorded declaration is already a
baja— a terminal state no further declaration (altaincluded) may follow. Checked, and refused, before anything is derived, stored or emitted.
- Return type:
- Return type:
- Parameters:
command (M036DeclarationCommand)
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
ports (M036LifecyclePorts)