cadrumo.domain.attachments.service module

Service-layer helpers over AttachmentStoreProtocol.

Thin orchestration on top of AttachmentStoreProtocol primitives: ingest a file from disk, build the corresponding Attachment manifest, persist it, and expose simple read paths for callers that do not need the full repository API.

class AttachmentIngestionRequest(**data)[source]

Bases: BaseModel

Typed manifest facts for one attachment capture.

Parameters:

data (Any)

kind: AttachmentKind
source: AttachmentSource
source_reference: str
mime_type: str
captured_at: UtcInstant
bucket_id: BucketId | None
captured_by: str | None
source_command: str | None
metadata: Mapping[str, str]
notes: str
class AttachmentFileContent(**data)[source]

Bases: BaseModel

One local file supplied to the attachment custody service.

Parameters:

data (Any)

path: Path
class AttachmentBytesContent(**data)[source]

Bases: BaseModel

One already-fetched byte payload supplied to the custody service.

Parameters:

data (bytes)

data: bytes
add_attachment(store, *, content, request)[source]

Store one typed file or byte payload and persist its attachment manifest.

Return type:

Attachment

Parameters:

Append invoice_id to an already-persisted attachment’s linked_invoice_ids.

Closes the provenance loop the other direction from add_attachment’s link_invoice_ids parameter: that parameter can only be populated for an invoice that already exists before the evidence is captured, but the evidence-confirmation flow mints the Invoice after the attachment is already stored. This helper re-persists the same manifest (attachment id and bytes unchanged) through the same AttachmentStoreProtocol.write_manifest() write path (aeat-architecture-boundaries), with invoice_id appended.

Idempotent by construction: Attachment’s linked_invoice_ids validator deduplicates and preserves first-seen order, so calling this twice with the same invoice_id is a no-op – the manifest’s byte content after the second call is identical to after the first (a real re-confirm safely re-links without growing the tuple).

Parameters:
Return type:

Attachment

Returns:

The re-persisted Attachment manifest carrying invoice_id in Attachment.linked_invoice_ids.

Append transaction_id to a persisted attachment’s linked_transaction_ids.

The transaction-side twin of link_attachment_invoice(), and for the same reason: add_attachment’s link_transaction_ids parameter can only be populated for a transaction that already exists before the evidence is captured, but the ledger evidence flow attaches an already-stored attachment to an existing transaction. Without this the link was recorded on the transaction only, so iter_manifests() filtered by linked_to=<transaction_id> could not discover an attachment the transaction itself cites – even though the manifest models the link and the surrounding workflow documents the provenance as bidirectional.

Re-persists the same manifest (attachment id and bytes unchanged) through the same AttachmentStoreProtocol.write_manifest() write path (aeat-architecture-boundaries).

Idempotent by construction: Attachment’s linked_transaction_ids validator deduplicates and preserves first-seen order, so a repeated attach is a no-op rather than a growing tuple.

Parameters:
Return type:

Attachment

Returns:

The re-persisted Attachment manifest carrying transaction_id in Attachment.linked_transaction_ids.