Files
FabledSteward/roundtable/core/audit.py
T
2026-04-13 17:13:55 -04:00

41 lines
1.3 KiB
Python

"""roundtable/core/audit.py
Helpers for writing audit log entries. Each call opens its own DB
session so audit events are committed independently of the calling
route's transaction (audit is only written after the main action
succeeds, by calling this after the main `async with db.begin()` block).
"""
from __future__ import annotations
import json
import logging
from datetime import datetime, timezone
logger = logging.getLogger(__name__)
async def log_audit(
app,
user_id: str | None,
username: str,
action: str,
entity_type: str | None = None,
entity_id: str | None = None,
detail: dict | None = None,
) -> None:
"""Write one audit event. Never raises — failures are logged and swallowed."""
from roundtable.models.audit import AuditEvent
try:
async with app.db_sessionmaker() as db:
async with db.begin():
db.add(AuditEvent(
user_id=user_id,
username=username or "unknown",
action=action,
entity_type=entity_type,
entity_id=entity_id,
detail_json=json.dumps(detail) if detail else None,
timestamp=datetime.now(timezone.utc),
))
except Exception:
logger.exception("Failed to write audit event action=%r", action)