Coverage for src / lexigram / contracts / admin / audit_entry.py: 100%
22 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:58 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:58 +0800
1"""AuditEntry value object and AuditOutcome enum for admin audit logging."""
3from __future__ import annotations
5from dataclasses import dataclass, field
6from enum import Enum
7from typing import Any
10class AuditOutcome(str, Enum):
11 """Categorised outcome of an admin audit event."""
13 SUCCESS = "success"
14 DENIED = "denied"
15 ERRORED = "errored"
18@dataclass(frozen=True)
19class AuditEntry:
20 """Immutable audit entry representing a single admin audit event.
22 Captures who did what, to which resource, the outcome, request
23 context metadata, and optional before/after state snapshots.
25 Args:
26 admin_user_id: Identifier of the admin user performing the action.
27 action: Action name (e.g. 'delete_user', 'update_role').
28 resource_type: Type of resource being acted upon.
29 resource_id: Identifier of the specific resource instance.
30 outcome: Categorised outcome — success, denied, or errored.
31 before: Snapshot of resource state before the action.
32 after: Snapshot of resource state after the action.
33 correlation_id: Request correlation ID for tracing.
34 request_id: Original request identifier.
35 request_ip: Client IP address.
36 metadata: Arbitrary supplementary metadata.
37 """
39 admin_user_id: str
40 action: str
41 resource_type: str
42 resource_id: str | None
43 outcome: AuditOutcome | str
44 before: dict[str, Any] = field(default_factory=dict)
45 after: dict[str, Any] = field(default_factory=dict)
46 correlation_id: str | None = None
47 request_id: str | None = None
48 request_ip: str | None = None
49 metadata: dict[str, Any] = field(default_factory=dict)
52__all__ = [
53 "AuditEntry",
54 "AuditOutcome",
55]