Source code for cadrumo.application.profile_deletion_hold_contract
"""Read-only legal and filing owner projections for profile deletion.The destructive custody transaction consumes these projections but cannotcreate or alter their source facts. Their distinct legal- and filing-ownermodules own the durable records and the semantic mutations that refresh them."""from__future__importannotationsfromdatetimeimportdatetimefromenumimportStrEnumfromtypingimportLiteralfromuuidimportUUIDfrompydanticimportBaseModel,Field,field_validator,model_validatorfrom..core.errors.hierarchyimportpydantic_validation_boundaryfrom..core.identity.digestimportPrefixedContentDigestfrom..core.modelsimportSTRICT_FROZEN_CONFIGfrom..core.time.utcimportvalidate_utc_aware
[docs]classProfileDeletionHoldOwner(StrEnum):"""Which duty keeps a profile from being deleted. The two are not interchangeable and not ordered: a legal hold and a filing hold can be present independently, and clearing one never clears the other. """LEGAL="legal""""A retention duty imposed by law."""FILING="filing""""An obligation still open against a tax filing."""
ProfileDeletionHoldOwnerValue=Literal[ProfileDeletionHoldOwner.LEGAL,ProfileDeletionHoldOwner.FILING,]"""The same owner for a strict projection or evidence field."""
[docs]classProfileDeletionHoldOwnerProjection(BaseModel):"""Authenticated owner result consumed by custody deletion preflight."""model_config=STRICT_FROZEN_CONFIGowner:ProfileDeletionHoldOwnerValueprofile_id:UUIDblocks_local_deletion:boolsource_record_id:str=Field(min_length=3,max_length=256)source_record_digest:PrefixedContentDigestassessed_at:datetime@field_validator("source_record_id")@classmethoddef_validate_source_record_id(cls,value:str)->str:ifvalue!=value.strip()orany(characterinvalueforcharacterin"\\/\x00"):raiseValueError("profile deletion hold source record id must be one canonical identifier")returnvalue@field_validator("source_record_digest")@classmethoddef_validate_source_record_digest(cls,value:str)->str:if(len(value)!=71ornotvalue.startswith("sha256:")orany(characternotin"0123456789abcdef"forcharacterinvalue[7:])):raiseValueError("profile deletion hold source record digest must be lowercase sha256")returnvalue@model_validator(mode="after")@pydantic_validation_boundarydef_validate_assessed_at(self)->ProfileDeletionHoldOwnerProjection:validate_utc_aware(self.assessed_at)returnself