"""Audit logging. Every mutation records an append-only AuditEntry attributing the change to a User (or the assistant principal acting for a User). Staged on the session; the caller commits as part of its unit of work. """ import uuid from sqlalchemy.ext.asyncio import AsyncSession from app.models.audit import AuditEntry from app.models.enums import AuditActorType def record_audit( session: AsyncSession, *, action: str, entity_type: str, entity_id: uuid.UUID | None = None, tree_id: uuid.UUID | None = None, actor_user_id: uuid.UUID | None = None, actor_type: AuditActorType = AuditActorType.user, before: dict | None = None, after: dict | None = None, ) -> AuditEntry: entry = AuditEntry( action=action, entity_type=entity_type, entity_id=entity_id, tree_id=tree_id, actor_user_id=actor_user_id, actor_type=actor_type, before=before, after=after, ) session.add(entry) return entry