- ui/monitoring_tab.py (1546 dong) tach thanh presentation/monitoring/** (container + 7 tab/card + shared helper), ui/monitoring_tab.py con lai re-export shim de app.py khong doi. - infrastructure/telemetry/audit_logger.py: CanonicalAuditLogger, core/audit_log.py thanh wrapper mong, tuong thich nguoc 100% voi schema .jsonl cu. - application/monitoring/monitoring_query_service.py: MonitoringQueryService read-only, filter/sort/pagination, khong import PySide6. - Go circular import model_pricing<->usage_tracker va agent_security<-> agent_security_alert (core/agent_security_types.py moi). - infrastructure/sandbox/sandbox_capabilities.py: SandboxCapabilityMatrix theo OS (Windows/Linux/macOS), chua dau noi vao core/sandbox_manager.py. - conftest.py: sua loi checkout khong ten cowork_local khien pytest import nham thu muc khac. - 77 test moi, 167/167 pass. QA da xac nhan UI/business logic khong doi (xem evidence/report/unified_report.html). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
"""Application-layer view of an audit event — decoupled from the
|
|
infrastructure ``CanonicalAuditEvent`` so ``application/`` doesn't need to
|
|
share a concrete class with ``infrastructure/`` (only the shape). Field names
|
|
match the canonical audit schema (see
|
|
``infrastructure/telemetry/audit_logger.py``) 1:1.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, Dict
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class AuditEventDTO:
|
|
ts: str
|
|
kind: str
|
|
name: str
|
|
ok: bool
|
|
detail: str
|
|
agent_role: str = ""
|
|
account: str = ""
|
|
role: str = ""
|
|
machine: str = ""
|
|
|
|
@classmethod
|
|
def from_raw(cls, raw: Dict[str, Any]) -> "AuditEventDTO":
|
|
"""Tolerant of missing keys — accepts both a
|
|
``CanonicalAuditEvent.to_dict()`` result and any historical raw
|
|
``.jsonl`` row."""
|
|
return cls(
|
|
ts=str(raw.get("ts", "")),
|
|
kind=str(raw.get("kind", "")),
|
|
name=str(raw.get("name", "")),
|
|
ok=bool(raw.get("ok", False)),
|
|
detail=str(raw.get("detail", "")),
|
|
agent_role=str(raw.get("agent_role", "")),
|
|
account=str(raw.get("account", "")),
|
|
role=str(raw.get("role", "")),
|
|
machine=str(raw.get("machine", "")),
|
|
)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
return {
|
|
"ts": self.ts, "kind": self.kind, "agent_role": self.agent_role,
|
|
"name": self.name, "ok": self.ok, "detail": self.detail,
|
|
"account": self.account, "role": self.role, "machine": self.machine,
|
|
}
|