cadrumo.application.live.justificante module

Application-live persistence for captured AEAT justificante receipts.

The live justificante pull retrieves the authentic, AEAT-signed justificante de presentación PDF for a filed work unit through the read-only sede surface (capture_justificante → SedeCapture) and persists it as a bucket-scoped, content-addressed secure object. The persisted artefact is the durable, official evidence the local reconciler reads — the operator no longer hand-downloads the receipt.

This service is a stateful SnapshotService sibling of the Modelo 100 borrador service: it keys supersession on the (modelo, filing_year, period) axis so a re-filed period’s fresh capture supersedes the prior ACTIVE one, and it persists each snapshot through a SecureObjectRepository at FINANCIAL sensitivity under cadrumo.adapters.persistence.storage.secure_object_namespaces.LIVE_JUSTIFICANTE_CAPTURE_SNAPSHOT_NAMESPACE, and records each capture as a lifecycle event via BucketEventHistoryRepository.

The captured PDF bytes ride inside the encrypted snapshot Envelope as a base64 str (binary cannot survive the JSON envelope verbatim); the raw-bytes pdf_sha256 is the content address used for snapshot-id derivation and dedup.

See also

cadrumo.application.live

Public read-only live facade that orchestrates capture and reports JustificanteCaptureOutcome.

cadrumo.application.live.filed_observation_persistence.enroll_filed_justificante_evidence()

Filed-history path that performs the same metadata registration and current-record evidence stamping from declaration-register artefacts.

cadrumo.application.overview

Calendar projection that reads JustificanteCaptureSnapshot rows and matching domain justificante metadata as AEAT-side evidence.

cadrumo.adapters.persistence.profile.snapshots.SecureSnapshotRepository

Shared encrypted snapshot repository used by this bucket-scoped capture repository.

ModeloRecord

Local filing record stamped with live ExternalEvidence only after the receipt matches the current filing axis.

class JustificanteAuthenticity(*values)[source]

Bases: StrEnum

Verdict of the read-only AEAT cotejo check on a captured receipt.

The four members are distinct states and never collapse into a boolean. NOT_CHECKED is the default a capture carries until the cotejo viewer has been consulted; UNAVAILABLE records that the check was attempted and could not be completed. Neither is a denial, and neither may be read as one. Only CONFIRMED means AEAT rendered the CSV-bound document viewer for this receipt, and only DENIED means AEAT answered that it holds no such document.

A verdict is advisory provenance about the captured PDF. It says nothing about the correctness of the declared values and must never be promoted into a filing-grade figure by a downstream consumer.

NOT_CHECKED
CONFIRMED
DENIED
UNAVAILABLE
exception JustificanteCaptureSnapshotNotFoundError(message=None, *, context=None, translated_message=None)[source]

Bases: SnapshotNotFoundError

Raised when a live justificante-capture snapshot lookup misses by id.

Parameters:
  • message (str | None)

  • context (Mapping[str, object] | None)

  • translated_message (str | None)

Return type:

None

code
class JustificanteCaptureSnapshot(**data)[source]

Bases: BaseModel

One live-captured AEAT justificante receipt persisted for a bucket.

Bundles the work-unit axis (modelo / filing_year / period), the sede provenance (expediente_id / csv), the content address (pdf_sha256 over the raw bytes), and the receipt itself (pdf_base64). The official source_kind records that the receipt came from an authenticated live capture.

Parameters:

data (Any)

snapshot_id: SnapshotId
bucket_id: BucketId
modelo: str
filing_year: FilingYear
period: Period
expediente_id: AeatExpedienteId
csv: AeatCsv
pdf_sha256: ContentDigest
pdf_base64: str
source_kind: ObservationSourceKind
authenticity: JustificanteAuthenticity
captured_at: datetime
state: SnapshotLifecycleState
superseded_by_snapshot_id: SnapshotId | None
discarded_at: datetime | None
discarded_by: str
discard_reason: str
decoded_pdf_bytes()[source]

Return the raw PDF bytes decoded from pdf_base64.

Return type:

bytes

justificante_capture_snapshot_object_key(bucket_id, snapshot_id)[source]

Return the secure-object key for one bucket’s justificante-capture snapshot.

The key shape is the object-key grammar declared by cadrumo.adapters.persistence.storage.secure_object_namespaces.LIVE_JUSTIFICANTE_CAPTURE_SNAPSHOT_NAMESPACE.

Return type:

str

Parameters:
  • bucket_id (str)

  • snapshot_id (str)

derive_justificante_capture_snapshot_id(*, modelo, filing_year, period, pdf_sha256)[source]

Return the content-addressed id for one justificante capture.

The id is derived from the work-unit axis plus the raw-PDF content address, so re-capturing the identical receipt is idempotent while a re-filed period (a different signed PDF) yields a new id that supersedes the prior ACTIVE snapshot on the same axis.

Return type:

str

Parameters:
resolve_period_expediente(*, declarations, expedientes, modelo, period)[source]

Resolve the capturable expediente for one (modelo, period) filing.

The procedure-tree Expediente carries no period, so for a multi-period modelo (quarterly 1T-4T) it cannot disambiguate which quarter’s receipt to pull. The period-bearing surface is the filed declarations register (Declaracion carries period and expediente_id). This resolver picks the declaration matching the target (modelo, period) (the latest filing for that period when a period was re-filed), then cross-references its expediente_id against the tree to return the capturable expediente. It NEVER returns a different period’s expediente: a missing or unmatched declaration raises rather than falling back to a wrong-quarter receipt.

The within-period tiebreak ranks the accepted (ALTA) declaration ahead of presented_at, matching the two sibling period-resolution surfaces (latest_declarations_by_period and the sede walker’s latest-selection), so a later cancellation / correction row (a non-ALTA estado such as Anulada or Baja) presented after the accepted filing does not win and pull the wrong-state receipt.

Raises:

LiveApplicationInputError – when no declaration matches the requested period, or the matched declaration’s expediente is absent from the tree.

Return type:

JustificanteExpediente

Parameters:
class JustificanteCaptureSnapshotRepository(*, persistence)[source]

Bases: object

Secure-DB repository for captured justificante snapshots in one bucket.

Composes the shared SecureSnapshotRepository for the read surface (load / resolve / list / exists), preserving the class identity, JustificanteCaptureSnapshotNotFoundError messages, and the captured_at list ordering. save is kept local because justificante stamps the envelope written_at with the capture time (not now()), a deliberate divergence from the shared base.

The namespace, sensitivity, schema version, and key grammar come from cadrumo.adapters.persistence.storage.secure_object_namespaces.LIVE_JUSTIFICANTE_CAPTURE_SNAPSHOT_NAMESPACE. Each JustificanteCaptureSnapshot is written through an Envelope so the captured PDF, CSV, and expediente metadata stay inside the encrypted SecureObjectRepository bucket store.

Parameters:

persistence (JustificanteSnapshotPersistencePort)

property bucket_id: str

Execute this public contract operation.

exists(snapshot_id)[source]

Execute this public contract operation.

Return type:

bool

Parameters:

snapshot_id (str)

load(snapshot_id)[source]

Execute this public contract operation.

Return type:

JustificanteCaptureSnapshot

Parameters:

snapshot_id (str)

list_snapshots()[source]

Execute this public contract operation.

Return type:

tuple[JustificanteCaptureSnapshot, ...]

resolve(snapshot_id)[source]

Execute this public contract operation.

Return type:

JustificanteCaptureSnapshot

Parameters:

snapshot_id (str)

save(snapshot)[source]

Execute this public contract operation.

Return type:

None

Parameters:

snapshot (JustificanteCaptureSnapshot)

class JustificanteCaptureSnapshotService(*, bucket_id, repository)[source]

Bases: SnapshotService[JustificanteCaptureSnapshot, _JustificanteCaptureRequest]

Canonical backend service for bucket-scoped live justificante captures.

Parameters:
capture(*, modelo, filing_year, period, expediente_id, csv, pdf_bytes, pdf_sha256, captured_at)[source]

Persist one captured justificante and return the ACTIVE JustificanteCaptureSnapshot.

Idempotent on the receipt content address: re-capturing the same signed PDF returns the existing snapshot. A re-filed period (a new signed PDF) supersedes the prior ACTIVE snapshot on the (modelo, filing_year, period) axis.

Return type:

JustificanteCaptureSnapshot

Parameters:
list_snapshots(*, filing_year=None, state=SnapshotLifecycleState.ACTIVE)[source]

Execute this public contract operation.

Return type:

tuple[JustificanteCaptureSnapshot, ...]

Parameters:
stamp_authenticity(*, snapshot, authenticity)[source]

Persist authenticity onto snapshot and return the stamped record.

The verdict rides the same encrypted snapshot envelope as the receipt it describes, so no plaintext copy of the capture leaves the secure store. Re-stamping is idempotent for an unchanged verdict and overwrites in place otherwise: the cotejo answer is a current-state fact about the document, not an append-only ledger of attempts.

Return type:

JustificanteCaptureSnapshot

Parameters:
show(snapshot_id)[source]

Execute this public contract operation.

Return type:

JustificanteCaptureSnapshot

Parameters:

snapshot_id (str)

parse_capture_to_justificante(snapshot, *, ports)[source]

Parse a persisted capture’s PDF into a strict domain Justificante.

Reads the encrypted snapshot’s bytes in memory and runs the inbound parser. Used to register the captured receipt as official filing evidence and to reconcile against it.

Return type:

Justificante

Parameters:
register_capture_justificante_metadata(*, snapshot, ports)[source]

Persist parsed justificante metadata for a live capture.

This records the official AEAT receipt metadata even when the local app has no current ModeloRecord for the period. It does not stamp or create a local filing row; that remains owned by register_capture_as_filing_evidence().

Returns the persisted Justificante, or None when the captured snapshot cannot be parsed into one.

Return type:

Justificante | None

Parameters:
reconcile_capture(*, work_unit_id, snapshot, actor='operator', operation)[source]

Reconcile a work unit against a persisted live capture.

Reads the captured PDF from secure storage into memory and delegates to the existing local-only reconciler; the reconciler never contacts AEAT and never writes the plaintext receipt to disk. This is the live-sourced equivalent of the operator hand-passing a downloaded justificante via the local reconcile import --file PATH surface.

Return type:

ModeloReconciliationReport

Returns:

A ModeloReconciliationReport for the in-memory receipt comparison.

Parameters:
register_capture_as_filing_evidence(*, snapshot, ports)[source]

Confirm the period’s filing with a persisted live capture of its receipt.

Loads the period’s current filing record first; with one present, parses the captured receipt into a domain Justificante (keyed by the capture’s CSV, which is the gate’s evidence reference), registers it, and reconciles the filing chain with it through reconcile_aeat_register_entry(). A receipt carries only totals, so a pending filing is confirmed only when its computed result matches them. Once confirmed, the cross-period clean-state gate’s MISSING_JUSTIFICANTE_VERIFICATION blocker clears for the period.

Returns the confirmed ModeloRecord.

Raises:

LiveApplicationInputError – when no current filing record exists for the captured (modelo, filing_year, period), when the receipt does not match it, or when the reconciliation does not confirm it.

Return type:

ModeloRecord

Parameters:
expected_tax_id_for_filing_record(filing)
Return type:

str

Parameters:

filing (ModeloRecord)

stamp_capture_evidence_if_filed(snapshot, *, ports)[source]

Best-effort filing-evidence registration for an already persisted capture.

Return type:

ModeloRecord | None

Parameters:
async verify_capture_authenticity(*, snapshot, service, verifier, browser=None, browser_session_factory=None)[source]

Ask AEAT’s public cotejo viewer about snapshot and stamp the verdict.

Runs the read-only verify_csv() round trip against the capture’s own CSV and persists the resulting JustificanteAuthenticity on the snapshot through service.

The three answers stay distinct. AEAT rendering the CSV-bound document viewer is JustificanteAuthenticity.CONFIRMED; AEAT answering that it holds no such document is JustificanteAuthenticity.DENIED; a round trip that could not be completed at all — no browser, a navigation failure, a guard refusal — is JustificanteAuthenticity.UNAVAILABLE, which is emphatically not a denial and must never be reported as one. The capture itself is already persisted before this runs, so an unreachable cotejo surface downgrades the provenance available for the receipt without losing the receipt.

Parameters:
  • snapshot (JustificanteCaptureSnapshot) – The already-persisted capture whose CSV is checked.

  • service (JustificanteCaptureSnapshotService) – Snapshot service owning snapshot’s bucket; it performs the encrypted write of the stamped record.

  • verifier (JustificanteAuthenticityVerifierPort) – Port that submits the capture CSV to the authenticity surface.

  • browser (object | None) – An already-constructed browser session to borrow. When None, the verifier builds and closes its own.

  • browser_session_factory (Callable[[], object] | None) – Optional no-argument factory for the self-owned verifier path. Ignored when browser is supplied.

Return type:

JustificanteCaptureSnapshot

Returns:

The stamped JustificanteCaptureSnapshot.

class JustificanteCaptureOutcome(snapshot, justificante, filing_record)[source]

Bases: object

Outcome of one live justificante capture and local evidence enrolment.

Parameters:
snapshot: JustificanteCaptureSnapshot
justificante: Justificante | None
filing_record: ModeloRecord | None
property justificante_metadata_registered: bool

Return whether the captured receipt yielded stored justificante metadata.

property filing_evidence_stamped: bool

Return whether the receipt matched an existing local filing record.

property filing_record_id: str | None

Return the local filing-record identifier when capture stamped one.

async capture_justificante_snapshot(*, bucket_id, modelo, year, period, service, read_port, registration_ports, verifier)[source]

Capture and persist the official justificante for one filed work unit.

Return type:

JustificanteCaptureSnapshot

Parameters:
async capture_justificante_snapshot_outcome(*, bucket_id, modelo, year, period, service, read_port, registration_ports, verifier)[source]

Capture a justificante and report the separate metadata and filing-evidence outcomes.

Return type:

JustificanteCaptureOutcome

Parameters: