cadrumo.domain.retention.floor module

Pure tax-record retention-floor assessment.

A filed tax record may only be erased once the governed retention floor has elapsed. The floor is resolved from the dated registry at the assessment boundary; this module contains only the calendar arithmetic and the resulting assessment models.

This module is pure: it derives, for a set of filed records and an as_of instant, which records are still inside their retention window (and therefore block a destructive erase) and the earliest instant at which every record becomes safe to erase. It performs no I/O and holds no storage handle; the application erase path feeds it the loaded ModeloRecord set and acts on the returned RetentionFloorAssessment.

retention_floor_years(*, effective_date, authority=None)[source]

Resolve the dated retention scalar through the registry authority.

Return type:

int

Parameters:
class RetainableFilingRecord(*args, **kwargs)[source]

Bases: Protocol

Structural view of a filed record the retention floor assesses.

ModeloRecord satisfies this view. Only the fields the floor needs are declared so the retention domain does not couple to the full filing-record schema.

property filing_record_id: FilingRecordId

Content-addressed id of the filing record.

property modelo: object

AEAT modelo code the record was filed under.

property filing_year: int

Filing year the record belongs to.

property filed_at: datetime

Instant the record was filed.

class RetentionBlockingRecord(**data)[source]

Bases: BaseModel

One filed record still inside its legal retention window.

Carries the earliest instant at which the record becomes safe to erase so the refusal can name a concrete date rather than a bare “still retained”.

Parameters:

data (Any)

filing_record_id: FilingRecordId
modelo: str
filing_year: FilingYear
filed_at: UtcInstant
earliest_safe_erase_date: UtcInstant
class RetentionFloorAssessment(**data)[source]

Bases: BaseModel

Outcome of assessing a record set against the legal retention floor.

retained holds every record whose retention window has not yet elapsed as of as_of; latest_safe_erase_date is the maximum earliest_safe_erase_date across those records (the instant at which the whole set becomes erasable) or None when nothing is retained.

Parameters:

data (Any)

as_of: UtcInstant
floor_years: NonNegativeInt
retained: tuple[RetentionBlockingRecord, ...]
property blocks_erase: bool

Whether any record still inside its window blocks a destructive erase.

property latest_safe_erase_date: datetime | None

Instant the whole assessed set becomes safe to erase, or None.

erase_is_blocked(*, blocks_erase, override_approved=False)[source]

Whether the retention floor refuses a destructive erase.

The one place the rule is decided. Both destructive surfaces reach it, and they carry the two facts rather than an assessment because they hold different types: the all-profile reset works from a ConfigResetRetentionDecision it has already resolved, the single-target delete from a RetentionFloorAssessment straight off the maintenance authority. Taking the facts keeps one rule serving both without forcing either into the other’s model.

override_approved defaults to false because a surface that offers no override must not have to say so. The single-target delete has no override to record, and passing nothing is the accurate statement of that.

Before this existed the decision was written twice and the CLI verb’s docstring said so plainly: the reset tested the flag together with an override, the delete tested the flag alone, and a third condition added to the retention contract would have reached one and not the other. The NUMBERS were never duplicated – both read the retained count and the safe-erase date from the same assessment – so the risk was never a wrong figure. It was the two surfaces coming to different conclusions about the same records.

Return type:

bool

Parameters:
  • blocks_erase (bool)

  • override_approved (bool)

assess_retention_floor(records, *, as_of, authority=None)[source]

Assess records against the registry-resolved retention floor.

A record is retained (blocking) when as_of precedes its safe-erase instant, which is filed_at shifted forward by the dated registry scalar’s whole calendar years. The floor is anchored on filed_at rather than a deadline that is not carried by the record because the filing instant is the durable evidence it carries; anchoring on it is conservative for the common case (filing occurs at or near the deadline) and errs toward keeping late-filed records longer. A record whose window has elapsed is safe to erase and is excluded from the assessment’s retained set.

Return type:

RetentionFloorAssessment

Returns:

The RetentionFloorAssessment for records.

Parameters: