v1
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
Audit logging service.
|
||||
|
||||
Call `log_audit(db, ...)` from within any request handler that already holds
|
||||
an open AsyncSession. The entry is added to the session — it will be
|
||||
committed with the surrounding transaction.
|
||||
|
||||
For error logging outside a request session (e.g. exception middleware), open
|
||||
a fresh session via `AsyncSessionLocal`, call `log_audit`, then `commit`.
|
||||
"""
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.audit import AuditLog
|
||||
from app.services.settings import get_feature_settings_snapshot
|
||||
|
||||
|
||||
async def log_audit(
|
||||
db: AsyncSession,
|
||||
*,
|
||||
action_type: str,
|
||||
area: str,
|
||||
description: str,
|
||||
member_id: Optional[uuid.UUID] = None,
|
||||
member_email: Optional[str] = None,
|
||||
status: str = "success",
|
||||
booking_id: Optional[uuid.UUID] = None,
|
||||
error_message: Optional[str] = None,
|
||||
error_detail: Optional[str] = None,
|
||||
ip_address: Optional[str] = None,
|
||||
user_agent: Optional[str] = None,
|
||||
extra: Optional[dict] = None,
|
||||
) -> None:
|
||||
feature_settings = await get_feature_settings_snapshot(db)
|
||||
if not feature_settings.audit_history_enabled:
|
||||
return
|
||||
|
||||
entry = AuditLog(
|
||||
timestamp=datetime.now(timezone.utc),
|
||||
member_id=member_id,
|
||||
member_email=member_email,
|
||||
action_type=action_type,
|
||||
area=area,
|
||||
description=description,
|
||||
status=status,
|
||||
booking_id=booking_id,
|
||||
error_message=error_message,
|
||||
error_detail=error_detail,
|
||||
ip_address=ip_address,
|
||||
user_agent=user_agent,
|
||||
extra=extra,
|
||||
)
|
||||
db.add(entry)
|
||||
Reference in New Issue
Block a user