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())