"""Audit helper used by the HTTP layer. Every sensitive operation calls this. It is deliberately cheap (one INSERT) so there is no excuse to skip it. """ from __future__ import annotations from sqlalchemy.ext.asyncio import AsyncSession from app.application.ports.realtime import emit_audit_recorded from app.domain.audit.models import AuditEvent from app.infrastructure.repositories.audit import AuditRepository async def record_audit( session: AsyncSession, *, action: str, organization_id: str | None = None, actor_user_id: str | None = None, target_type: str = "", target_id: str = "", metadata: dict | None = None, ip: str = "", user_agent: str = "", ) -> AuditEvent: event = AuditEvent( action=action, organization_id=organization_id, actor_user_id=actor_user_id, target_type=target_type, target_id=target_id, metadata_json=metadata or {}, ip_address=ip, user_agent=user_agent, ) recorded = await AuditRepository(session).record(event=event) # Live push: the audit timelines (dashboard, traces) update as actions # happen instead of waiting for the next reload. await emit_audit_recorded( organization_id=organization_id, action=action, target_type=target_type, target_id=target_id, ) return recorded