35 lines
1.4 KiB
Python
35 lines
1.4 KiB
Python
"""
|
|
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
|