49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.audit_log import AuditLog
|
|
from app.models.user import User
|
|
|
|
|
|
def describe_create(resource_type: str, resource_id: int, name: str) -> str:
|
|
return f"Created {resource_type} '{name}' (#{resource_id})"
|
|
|
|
|
|
def describe_update(resource_type: str, resource_id: int, changes: dict) -> str:
|
|
safe = {k: ("***" if k == "password" else v) for k, v in changes.items()}
|
|
parts = ", ".join(f"{k}={v!r}" for k, v in safe.items())
|
|
suffix = f": {parts}" if parts else ""
|
|
return f"Updated {resource_type} #{resource_id}{suffix}"
|
|
|
|
|
|
def describe_delete(resource_type: str, resource_id: int, name: str) -> str:
|
|
return f"Deleted {resource_type} '{name}' (#{resource_id})"
|
|
|
|
|
|
async def log(
|
|
db: AsyncSession,
|
|
*,
|
|
actor: User,
|
|
action: str,
|
|
resource_type: str,
|
|
resource_id: int | None,
|
|
description: str,
|
|
) -> None:
|
|
entry = AuditLog(
|
|
user_id=actor.id,
|
|
user_email=actor.email,
|
|
action=action,
|
|
resource_type=resource_type,
|
|
resource_id=resource_id,
|
|
description=description,
|
|
)
|
|
db.add(entry)
|
|
await db.commit()
|
|
|
|
|
|
async def list_recent(db: AsyncSession, limit: int = 200) -> list[AuditLog]:
|
|
result = await db.execute(
|
|
select(AuditLog).order_by(AuditLog.created_at.desc()).limit(limit)
|
|
)
|
|
return list(result.scalars().all())
|