feat(records): govern lifecycle recovery and transfer evidence
This commit is contained in:
@@ -148,6 +148,99 @@ class RecordItemCreateRequest(StrictModel):
|
||||
metadata: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class RecordLifecycleActionRequest(StrictModel):
|
||||
expected_revision: int = Field(ge=1)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
reason: str = Field(min_length=1, max_length=2_000)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
|
||||
class RecordCloseRequest(RecordLifecycleActionRequest):
|
||||
retention_trigger_at: datetime | None = None
|
||||
restart_retention: bool = False
|
||||
|
||||
|
||||
class RecordAppraisalRequest(RecordLifecycleActionRequest):
|
||||
outcome: Literal["retain", "transfer", "destroy", "reclassify"]
|
||||
policy_refs: list[str] = Field(default_factory=list, max_length=100)
|
||||
override_retention_not_due: bool = False
|
||||
|
||||
|
||||
class RecordHoldCreateRequest(StrictModel):
|
||||
hold_id: str | None = Field(default=None, max_length=255)
|
||||
expected_record_revision: int = Field(ge=1)
|
||||
reason: str = Field(min_length=1, max_length=10_000)
|
||||
authority: str = Field(min_length=1, max_length=500)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
scope: dict[str, Any] = Field(default_factory=dict)
|
||||
effective_from: datetime | None = None
|
||||
effective_to: datetime | None = None
|
||||
policy_refs: list[str] = Field(default_factory=list, max_length=100)
|
||||
institutional_context: dict[str, Any] = Field(default_factory=dict)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_interval(self):
|
||||
if (
|
||||
self.effective_from
|
||||
and self.effective_to
|
||||
and self.effective_to <= self.effective_from
|
||||
):
|
||||
raise ValueError("effective_to must be after effective_from")
|
||||
return self
|
||||
|
||||
|
||||
class RecordHoldReleaseRequest(StrictModel):
|
||||
expected_hold_revision: int = Field(ge=1)
|
||||
reason: str = Field(min_length=1, max_length=2_000)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
|
||||
class RecordDispositionCreateRequest(StrictModel):
|
||||
disposition_id: str | None = Field(default=None, max_length=255)
|
||||
expected_record_revision: int = Field(ge=1)
|
||||
action: Literal["retain", "transfer", "destroy", "reclassify"]
|
||||
reason: str = Field(min_length=1, max_length=10_000)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
policy_refs: list[str] = Field(default_factory=list, max_length=100)
|
||||
institutional_context: dict[str, Any] = Field(default_factory=dict)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
|
||||
class RecordDispositionFinalizeRequest(StrictModel):
|
||||
expected_disposition_revision: int = Field(ge=1)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
|
||||
class RecordDispositionWithdrawRequest(RecordDispositionFinalizeRequest):
|
||||
reason: str = Field(min_length=1, max_length=2_000)
|
||||
|
||||
|
||||
class RecordTransferPackageCreateRequest(StrictModel):
|
||||
package_id: str | None = Field(default=None, max_length=255)
|
||||
disposition_id: str = Field(min_length=1, max_length=255)
|
||||
expected_record_revision: int = Field(ge=1)
|
||||
provider_id: str = Field(min_length=1, max_length=100)
|
||||
profile: str = Field(min_length=1, max_length=255)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
|
||||
class RecordTransferDispatchRequest(StrictModel):
|
||||
expected_package_revision: int = Field(ge=1)
|
||||
purpose: str = Field(min_length=1, max_length=255)
|
||||
recorded_at: datetime
|
||||
idempotency_key: str = Field(min_length=1, max_length=255)
|
||||
|
||||
|
||||
class RecordListResponse(StrictModel):
|
||||
records: list[dict[str, Any]]
|
||||
total: int
|
||||
@@ -165,6 +258,9 @@ class RecordDetailResponse(StrictModel):
|
||||
volumes: list[dict[str, Any]]
|
||||
items: list[dict[str, Any]]
|
||||
chronology: list[dict[str, Any]]
|
||||
holds: list[dict[str, Any]]
|
||||
dispositions: list[dict[str, Any]]
|
||||
transfer_packages: list[dict[str, Any]]
|
||||
access_explanation: dict[str, Any]
|
||||
|
||||
|
||||
@@ -172,15 +268,43 @@ class RecordSourceProviderResponse(StrictModel):
|
||||
providers: list[dict[str, Any]]
|
||||
|
||||
|
||||
class RecordArchiveProviderResponse(StrictModel):
|
||||
providers: list[dict[str, Any]]
|
||||
|
||||
|
||||
class RecordRecoveryStatusResponse(StrictModel):
|
||||
record_id: str
|
||||
record_revision: int
|
||||
evidence_sha256: str
|
||||
healthy: bool
|
||||
source_checks: list[dict[str, Any]]
|
||||
package_checks: list[dict[str, Any]]
|
||||
recovery_operations: list[dict[str, Any]]
|
||||
failure_count: int
|
||||
limitations: list[str]
|
||||
|
||||
|
||||
__all__ = [
|
||||
"FilePlanNodeWriteRequest",
|
||||
"RecordAppraisalRequest",
|
||||
"RecordArchiveProviderResponse",
|
||||
"RecordCatalogResponse",
|
||||
"RecordClassWriteRequest",
|
||||
"RecordCloseRequest",
|
||||
"RecordCreateRequest",
|
||||
"RecordDetailResponse",
|
||||
"RecordDispositionCreateRequest",
|
||||
"RecordDispositionFinalizeRequest",
|
||||
"RecordDispositionWithdrawRequest",
|
||||
"RecordHoldCreateRequest",
|
||||
"RecordHoldReleaseRequest",
|
||||
"RecordItemCreateRequest",
|
||||
"RecordLifecycleActionRequest",
|
||||
"RecordListResponse",
|
||||
"RecordRecoveryStatusResponse",
|
||||
"RecordSourceProviderResponse",
|
||||
"RecordTransferDispatchRequest",
|
||||
"RecordTransferPackageCreateRequest",
|
||||
"RecordUpdateRequest",
|
||||
"RecordVolumeCreateRequest",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user