from __future__ import annotations from datetime import UTC, datetime import hashlib import json from govoplan_core.core.records import ( RecordArchiveProviderState, RecordArchiveReceipt, RecordArchiveTransferRequest, RecordContractError, ) SIMULATION_PROVIDER_ID = "simulation" SIMULATION_PROFILE = "govoplan-simulation-v1" class SimulatedRecordArchiveProvider: """Exercise the transfer boundary without claiming archival custody.""" provider_id = SIMULATION_PROVIDER_ID def state(self) -> RecordArchiveProviderState: checked_at = datetime.now(UTC) return RecordArchiveProviderState( provider_id=self.provider_id, label="Records transfer simulation", profiles=(SIMULATION_PROFILE,), authority_modes=("linked_reference",), healthy=True, checked_at=checked_at, last_success_at=checked_at, freshness_seconds=0, limitations=( "Simulation validates package and receipt handling but does not transfer custody.", "It is not an xDOMEA or archival conformance profile.", ), simulated=True, ) def dispatch( self, session: object, principal: object, *, request: RecordArchiveTransferRequest, ) -> RecordArchiveReceipt: del session, principal if request.package.profile != SIMULATION_PROFILE: raise RecordContractError( "The simulation provider only accepts its declared profile." ) observed_at = datetime.now(UTC) receipt_payload = { "provider_id": self.provider_id, "package_id": request.package.package_id, "manifest_sha256": request.package.manifest_sha256, "profile": request.package.profile, "outcome": "accepted", "simulated": True, } receipt_sha256 = hashlib.sha256( json.dumps( receipt_payload, sort_keys=True, separators=(",", ":"), ).encode("utf-8") ).hexdigest() return RecordArchiveReceipt( provider_id=self.provider_id, package_id=request.package.package_id, outcome="accepted", observed_at=observed_at, receipt_sha256=receipt_sha256, external_reference=f"simulation:{request.package.package_id}", retry_safe=True, simulated=True, metadata={ "manifest_sha256": request.package.manifest_sha256, "profile": request.package.profile, "custody_transferred": False, }, ) __all__ = [ "SIMULATION_PROFILE", "SIMULATION_PROVIDER_ID", "SimulatedRecordArchiveProvider", ]