"""Strict contracts for one-call ARR direct structured-result ingestion.""" from __future__ import annotations import hashlib import json import re from dataclasses import dataclass, field from datetime import date, datetime from typing import Any, Dict, Mapping, Optional from arr_ingestion.contracts import ( OPAQUE_ID_RE, PROCESSOR_VERSION_RE, RESULT_SCHEMA_VERSION, SHA256_RE, ArtifactRef, IngestionError, ) DIRECT_CONTRACT_VERSION = "arr-direct-ingestion-1" MAX_DIRECT_PAYLOAD_BYTES = 3 * 1024 * 1024 DIRECT_REQUEST_FIELDS = { "submission_grant", "job_id", "attempt_no", "payload", } DIRECT_RECEIPT_FIELDS = { "contract_version", "status", "job_id", "attempt_no", "business_date", "daily_version_id", "version_no", "record_count", } GRANT_TOKEN_RE = re.compile(r"^[A-Za-z0-9_-]{32,128}$") def _fail(code: str, message: str) -> None: raise IngestionError(code, message) def canonical_json_bytes(value: Mapping[str, Any]) -> bytes: """Return the one canonical encoding used for hashing and persistence.""" try: return json.dumps( value, ensure_ascii=False, allow_nan=False, sort_keys=True, separators=(",", ":"), ).encode("utf-8") except (TypeError, ValueError): _fail( "DIRECT_SUBMISSION_INVALID", "direct result payload is not strict JSON", ) def _strict_mapping( value: Any, expected: set[str], label: str, *, error_code: str = "DIRECT_SUBMISSION_INVALID", ) -> Mapping[str, Any]: if not isinstance(value, Mapping) or set(value) != expected: _fail( error_code, f"{label} field set is invalid", ) return value def _parse_business_date( value: Any, *, error_code: str = "DIRECT_SUBMISSION_INVALID", error_message: str = "direct result business date is invalid", ) -> date: if not isinstance(value, str): _fail(error_code, error_message) try: return date.fromisoformat(value) except ValueError: _fail(error_code, error_message) @dataclass(frozen=True) class DirectSubmissionRequest: """Validated transport metadata plus a detached strict-JSON payload.""" submission_grant: str = field(repr=False) job_id: str attempt_no: int payload: Mapping[str, Any] = field(repr=False) payload_bytes: bytes = field(repr=False) payload_sha256: str business_date: date processor_version: str rule_set_sha256: str result_schema_version: str record_count: int @classmethod def from_dict(cls, raw: Any) -> "DirectSubmissionRequest": values = _strict_mapping(raw, DIRECT_REQUEST_FIELDS, "direct submission") grant = values.get("submission_grant") job_id = values.get("job_id") attempt_no = values.get("attempt_no") payload = values.get("payload") if not isinstance(grant, str) or not GRANT_TOKEN_RE.fullmatch(grant): _fail( "SUBMISSION_GRANT_INVALID", "submission grant is invalid", ) if not isinstance(job_id, str) or not OPAQUE_ID_RE.fullmatch(job_id): _fail( "DIRECT_SUBMISSION_INVALID", "direct submission job identifier is invalid", ) if ( not isinstance(attempt_no, int) or isinstance(attempt_no, bool) or not 1 <= attempt_no <= 9999 ): _fail( "DIRECT_SUBMISSION_INVALID", "direct submission attempt number is invalid", ) if not isinstance(payload, Mapping): _fail( "DIRECT_SUBMISSION_INVALID", "direct result payload must be an object", ) payload_bytes = canonical_json_bytes(payload) if not 2 <= len(payload_bytes) <= MAX_DIRECT_PAYLOAD_BYTES: _fail( "DIRECT_PAYLOAD_TOO_LARGE", "direct result payload exceeds its size limit", ) detached = json.loads(payload_bytes.decode("utf-8")) if ( detached.get("status") != "success" or detached.get("activation_eligible") is not True ): _fail( "DIRECT_RESULT_NOT_ACTIVATABLE", "direct result is not eligible for Finance activation", ) processor_version = detached.get("processor_version") rule_set_sha256 = detached.get("rule_set_sha256") result_schema_version = detached.get("result_schema_version") records = detached.get("records") if ( not isinstance(processor_version, str) or not PROCESSOR_VERSION_RE.fullmatch(processor_version) or not isinstance(rule_set_sha256, str) or not SHA256_RE.fullmatch(rule_set_sha256) or result_schema_version != RESULT_SCHEMA_VERSION or not isinstance(records, list) ): _fail( "DIRECT_SUBMISSION_INVALID", "direct result identity is invalid", ) return cls( submission_grant=grant, job_id=job_id, attempt_no=attempt_no, payload=detached, payload_bytes=payload_bytes, payload_sha256=hashlib.sha256(payload_bytes).hexdigest(), business_date=_parse_business_date(detached.get("business_date")), processor_version=processor_version, rule_set_sha256=rule_set_sha256, result_schema_version=result_schema_version, record_count=len(records), ) @property def grant_sha256(self) -> str: return hashlib.sha256(self.submission_grant.encode("utf-8")).hexdigest() @property def submission_key(self) -> str: identity = f"{self.job_id}\x00{self.attempt_no}".encode("utf-8") return "direct:" + hashlib.sha256(identity).hexdigest() def payload_json(self) -> str: return self.payload_bytes.decode("utf-8") @dataclass(frozen=True) class DirectSubmissionReceipt: status: str job_id: str attempt_no: int business_date: date daily_version_id: int version_no: int record_count: int @classmethod def from_dict(cls, raw: Any) -> "DirectSubmissionReceipt": values = _strict_mapping( raw, DIRECT_RECEIPT_FIELDS, "stored direct receipt", error_code="DATABASE_STATE_INVALID", ) if values.get("contract_version") != DIRECT_CONTRACT_VERSION: _fail( "DATABASE_STATE_INVALID", "stored direct receipt contract is invalid", ) status = values.get("status") job_id = values.get("job_id") attempt_no = values.get("attempt_no") daily_version_id = values.get("daily_version_id") version_no = values.get("version_no") record_count = values.get("record_count") if ( status not in {"committed", "already_committed"} or not isinstance(job_id, str) or not OPAQUE_ID_RE.fullmatch(job_id) or not isinstance(attempt_no, int) or isinstance(attempt_no, bool) or attempt_no < 1 or not isinstance(daily_version_id, int) or isinstance(daily_version_id, bool) or daily_version_id < 1 or not isinstance(version_no, int) or isinstance(version_no, bool) or version_no < 1 or not isinstance(record_count, int) or isinstance(record_count, bool) or record_count < 0 ): _fail( "DATABASE_STATE_INVALID", "stored direct receipt is invalid", ) return cls( status=str(status), job_id=job_id, attempt_no=attempt_no, business_date=_parse_business_date( values.get("business_date"), error_code="DATABASE_STATE_INVALID", error_message="stored direct receipt business date is invalid", ), daily_version_id=daily_version_id, version_no=version_no, record_count=record_count, ) def to_dict(self) -> Dict[str, Any]: return { "contract_version": DIRECT_CONTRACT_VERSION, "status": self.status, "job_id": self.job_id, "attempt_no": self.attempt_no, "business_date": self.business_date.isoformat(), "daily_version_id": self.daily_version_id, "version_no": self.version_no, "record_count": self.record_count, } @dataclass(frozen=True) class SubmissionGrant: submission_grant: str = field(repr=False) job_id: str attempt_no: int expires_at: datetime def to_dict(self) -> Dict[str, Any]: return { "contract_version": DIRECT_CONTRACT_VERSION, "submission_grant": self.submission_grant, "job_id": self.job_id, "attempt_no": self.attempt_no, "expires_at": self.expires_at.isoformat(), } @dataclass(frozen=True) class ReceivedDirectSubmission: submission_id: int status: str request: DirectSubmissionRequest source: ArtifactRef receipt: Optional[DirectSubmissionReceipt] = None @dataclass(frozen=True) class VerifiedDirectSubmission: submission: ReceivedDirectSubmission replay_payload_sha256: str