feat/agentic-commerce-x402-local-sim
py 47 lines 1.25 KB
Raw
1 """Append-only in-memory audit trail for the deterministic local path."""
2
3 from __future__ import annotations
4
5 from collections.abc import Callable
6 from datetime import UTC, datetime
7 from typing import Any
8
9 from .models import AuditEvent, AuditEventType
10
11 Clock = Callable[[], datetime]
12
13
14 def utc_now() -> datetime:
15 return datetime.now(UTC)
16
17
18 class AuditTrail:
19 """Record ordered events without exposing mutable internal state."""
20
21 def __init__(self, *, clock: Clock = utc_now) -> None:
22 self._clock = clock
23 self._events: list[AuditEvent] = []
24
25 def append(
26 self,
27 *,
28 request_id: str,
29 event_type: AuditEventType,
30 detail: dict[str, Any] | None = None,
31 ) -> AuditEvent:
32 event = AuditEvent(
33 sequence=len(self._events) + 1,
34 occurred_at=self._clock(),
35 request_id=request_id,
36 event_type=event_type,
37 detail=detail or {},
38 )
39 self._events.append(event)
40 return event
41
42 def for_request(self, request_id: str) -> tuple[AuditEvent, ...]:
43 return tuple(event for event in self._events if event.request_id == request_id)
44
45 @property
46 def events(self) -> tuple[AuditEvent, ...]:
47 return tuple(self._events)