from typing import List, Optional from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from sqlalchemy import asc, desc, or_, cast, String from app.config.database import get_db from app.middleware.auth_middleware import get_current_user, User from app.models.system.audit_log import AuditLog from app.schemas.auth.audit_schema import AuditLogListResponse router = APIRouter() @router.get("/", response_model=AuditLogListResponse) def get_audit_logs( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), module_name: Optional[str] = Query(None, description="Filter by module name"), action_type: Optional[str] = Query(None, description="CREATE | UPDATE | DELETE"), performed_by_email: Optional[str] = Query(None, description="Filter by actor email"), search: Optional[str] = Query(None, description="Search audit logs"), module_names: Optional[List[str]] = Query(None, description="Filter by module names"), action_types: Optional[List[str]] = Query(None, description="Filter by action types"), performed_by_emails: Optional[List[str]] = Query(None, description="Filter by actor emails"), sort_by: Optional[str] = Query("created_at", description="Sort by created_at, module_name, action_type, or performed_by_email"), sort_order: Optional[str] = Query("desc", description="Sort order: asc or desc"), limit: int = Query(50, ge=1, le=500), offset: int = Query(0, ge=0), ): """ Fetch audit logs with optional filters. Only accessible to authenticated users (super-admin in practice). """ query = db.query(AuditLog) if module_name: query = query.filter(AuditLog.module_name == module_name) if module_names: query = query.filter(AuditLog.module_name.in_(module_names)) if action_type: query = query.filter(AuditLog.action_type == action_type.upper()) if action_types: normalized_action_types = [item.upper() for item in action_types] query = query.filter(AuditLog.action_type.in_(normalized_action_types)) if performed_by_email: query = query.filter( AuditLog.performed_by_email.ilike(f"%{performed_by_email}%") ) if performed_by_emails: query = query.filter(AuditLog.performed_by_email.in_(performed_by_emails)) if search: search_term = search.strip() query = query.filter( or_( AuditLog.module_name.ilike(f"%{search_term}%"), AuditLog.action_type.ilike(f"%{search_term}%"), AuditLog.entity_name.ilike(f"%{search_term}%"), AuditLog.description.ilike(f"%{search_term}%"), AuditLog.performed_by_email.ilike(f"%{search_term}%"), AuditLog.ip_address.ilike(f"%{search_term}%"), cast(AuditLog.entity_id, String).ilike(f"%{search_term}%"), ) ) total = query.count() sort_column_map = { "created_at": AuditLog.created_at, "module_name": AuditLog.module_name, "action_type": AuditLog.action_type, "performed_by_email": AuditLog.performed_by_email, } sort_column = sort_column_map.get(sort_by or "created_at", AuditLog.created_at) order_fn = asc if (sort_order or "").lower() == "asc" else desc items = ( query.order_by(order_fn(sort_column)) .offset(offset) .limit(limit) .all() ) return AuditLogListResponse( items=items, total=total, limit=limit, offset=offset, )