""" Audit trail: one append-only row per business action, attributed to the signed-in user. `record()` only ADDS the row to the caller's ORM session — the caller's own `db.commit()` persists it atomically with the action itself, so a failed action never leaves a phantom audit entry (and a recorded action is never lost to a second commit failing). """ from __future__ import annotations from fastapi import Request from sqlalchemy.orm import Session as OrmSession from ..db import models def record(db: OrmSession, request: Request | None, action: str, detail: str = "", session: models.Session | None = None) -> models.AuditLog: """Attach an audit row to the caller's transaction. Identity comes from the verified bearer token; with auth off (dev / tests before the first user) the row is still written with an empty username, so the trail's shape is the same everywhere.""" from ..api.auth import current_user # late import: auth imports models too user = current_user(request) if request is not None else None row = models.AuditLog( username=user.username if user else "", display_name=user.display_name if user else "", action=action, session_id=session.id if session is not None else None, session_name=session.name if session is not None else "", detail=(detail or "")[:2000], ) db.add(row) return row