""" Shared Pydantic schemas for audit log API responses. Used across all services for consistent audit log retrieval. """ from datetime import datetime from typing import Any, Dict, Optional from uuid import UUID from pydantic import BaseModel, Field class AuditLogResponse(BaseModel): """Response schema for audit log entries""" id: UUID tenant_id: UUID user_id: Optional[UUID] = None service_name: str action: str resource_type: str resource_id: Optional[str] = None severity: str # low, medium, high, critical description: str changes: Optional[Dict[str, Any]] = None audit_metadata: Optional[Dict[str, Any]] = None endpoint: Optional[str] = None method: Optional[str] = None # HTTP method ip_address: Optional[str] = None user_agent: Optional[str] = None created_at: datetime class Config: from_attributes = True json_encoders = { datetime: lambda v: v.isoformat(), UUID: lambda v: str(v) } class AuditLogFilters(BaseModel): """Query parameters for filtering audit logs""" start_date: Optional[datetime] = Field(None, description="Filter logs from this date") end_date: Optional[datetime] = Field(None, description="Filter logs until this date") user_id: Optional[UUID] = Field(None, description="Filter by user ID") action: Optional[str] = Field(None, description="Filter by action type") resource_type: Optional[str] = Field(None, description="Filter by resource type") severity: Optional[str] = Field(None, description="Filter by severity level") search: Optional[str] = Field(None, description="Search in description field") limit: int = Field(100, ge=1, le=1000, description="Number of records to return") offset: int = Field(0, ge=0, description="Number of records to skip") class AuditLogListResponse(BaseModel): """Paginated response for audit log listings""" items: list[AuditLogResponse] total: int limit: int offset: int has_more: bool class Config: json_encoders = { datetime: lambda v: v.isoformat(), UUID: lambda v: str(v) } class AuditLogStatsResponse(BaseModel): """Statistics about audit logs""" total_events: int events_by_action: Dict[str, int] events_by_severity: Dict[str, int] events_by_resource_type: Dict[str, int] date_range: Dict[str, Optional[datetime]] class Config: json_encoders = { datetime: lambda v: v.isoformat() }