informed-decision/informed_decision/records.py
tegwick 2cc32168ac Persist review evidence and deliver audit records transactionally
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 23:27:19 +02:00

48 lines
1.9 KiB
Python

"""JSON persistence of the existing domain objects; never pickle or a new memo schema."""
from dataclasses import asdict
import json
from .disposition import Actor, ActorKind, Disposition, Verb
from .memo import (BindingLevel, BindingSlice, Highlight, Identifier, Memo,
PacketItem, Principal, Scope, StepKind)
from .presentation import Phase, Presentation
from .provenance import Claim, Route
def dumps(value) -> str:
return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False,
allow_nan=False, default=lambda x: sorted(x) if isinstance(x, frozenset) else asdict(x))
def memo_from(data: dict) -> Memo:
data = dict(data)
binding = dict(data["binding"])
principal = dict(binding["principal"])
principal["identifiers"] = tuple(Identifier(**i) for i in principal.get("identifiers", []))
binding["principal"] = Principal(**principal)
binding["target"] = Scope(**binding["target"])
data["binding"] = BindingSlice(**binding)
data["binding_level"] = BindingLevel(data["binding_level"])
data["step_kind"] = StepKind(data["step_kind"])
data["packet"] = tuple(PacketItem(**p) for p in data["packet"])
data["highlights"] = tuple(Highlight(**h) for h in data["highlights"])
return Memo(**data)
def presentation_from(data: dict) -> Presentation:
data = dict(data)
data["phase"] = Phase(data["phase"])
data["acked_highlight_ids"] = frozenset(data["acked_highlight_ids"])
for field in ("tenant", "principal_type"):
if data[field] is not None:
data[field] = Claim(data[field]["value"], Route(data[field]["route"]))
return Presentation(**data)
def disposition_from(data: dict) -> Disposition:
data = dict(data)
data["verb"] = Verb(data["verb"])
data["actor"] = Actor(data["actor"]["sub"], ActorKind(data["actor"]["kind"]))
data["reasons"] = tuple(data["reasons"])
return Disposition(**data)