from datetime import datetime from uuid import UUID from fastapi import APIRouter, Depends, Query from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from src.api.v1.dependencies.auth import get_current_user, require_role from src.domain.entities import UserRole from src.infrastructure.database.repositories import AuditLogRepository from src.infrastructure.database.session import get_db_session from src.services.auth.security import TokenData from src.services.audit.audit_service import AuditService router = APIRouter(prefix="/audit", tags=["Audit"]) class AuditLogResponse(BaseModel): id: UUID actor_id: UUID | None actor_type: str | None action: str resource_type: str resource_id: str | None old_value: dict | None new_value: dict | None ip_address: str | None user_agent: str | None request_id: str | None created_at: datetime | None class AuditLogListResponse(BaseModel): items: list[AuditLogResponse] total: int offset: int limit: int def _get_service(session: AsyncSession) -> AuditService: return AuditService(AuditLogRepository(session)) @router.get("/logs", response_model=AuditLogListResponse) async def list_audit_logs( actor_id: UUID | None = None, action: str | None = None, resource_type: str | None = None, offset: int = Query(0, ge=0), limit: int = Query(50, ge=1, le=200), session: AsyncSession = Depends(get_db_session), current_user: TokenData = Depends(require_role(UserRole.ADMIN)), ): service = _get_service(session) entities, total = await service.list_logs( actor_id=actor_id, action=action, resource_type=resource_type, offset=offset, limit=limit, ) items = [ AuditLogResponse( id=e.id, actor_id=e.actor_id, actor_type=e.actor_type, action=e.action, resource_type=e.resource_type, resource_id=e.resource_id, old_value=e.old_value, new_value=e.new_value, ip_address=e.ip_address, user_agent=e.user_agent, request_id=e.request_id, created_at=e.created_at, ) for e in entities ] return AuditLogListResponse(items=items, total=total, offset=offset, limit=limit)