""" Service Module Pydantic schemas — extracted from compliance/api/schemas.py. Phase 1 Step 3: the monolithic ``compliance.api.schemas`` module is being split per domain under ``compliance.schemas``. This module is re-exported from ``compliance.api.schemas`` for backwards compatibility. """ from datetime import datetime, date from typing import Optional, List, Any, Dict from pydantic import BaseModel, ConfigDict, Field from compliance.schemas.common import ( PaginationMeta, RegulationType, ControlType, ControlDomain, ControlStatus, RiskLevel, EvidenceStatus, ) # ============================================================================ # Service Module Schemas (Sprint 3) # ============================================================================ class ServiceModuleBase(BaseModel): """Base schema for service modules.""" name: str display_name: str description: Optional[str] = None service_type: str port: Optional[int] = None technology_stack: Optional[List[str]] = None repository_path: Optional[str] = None docker_image: Optional[str] = None data_categories: Optional[List[str]] = None processes_pii: bool = False processes_health_data: bool = False ai_components: bool = False criticality: str = "medium" owner_team: Optional[str] = None owner_contact: Optional[str] = None class ServiceModuleCreate(ServiceModuleBase): """Schema for creating a service module.""" pass class ServiceModuleResponse(ServiceModuleBase): """Response schema for service module.""" id: str is_active: bool compliance_score: Optional[float] = None last_compliance_check: Optional[datetime] = None created_at: datetime updated_at: datetime regulation_count: Optional[int] = None risk_count: Optional[int] = None model_config = ConfigDict(from_attributes=True) class ServiceModuleListResponse(BaseModel): """List response for service modules.""" modules: List[ServiceModuleResponse] total: int class ServiceModuleDetailResponse(ServiceModuleResponse): """Detailed response including regulations and risks.""" regulations: Optional[List[Dict[str, Any]]] = None risks: Optional[List[Dict[str, Any]]] = None class ModuleRegulationMappingBase(BaseModel): """Base schema for module-regulation mapping.""" module_id: str regulation_id: str relevance_level: str = "medium" notes: Optional[str] = None applicable_articles: Optional[List[str]] = None class ModuleRegulationMappingCreate(ModuleRegulationMappingBase): """Schema for creating a module-regulation mapping.""" pass class ModuleRegulationMappingResponse(ModuleRegulationMappingBase): """Response schema for module-regulation mapping.""" id: str module_name: Optional[str] = None regulation_code: Optional[str] = None regulation_name: Optional[str] = None created_at: datetime model_config = ConfigDict(from_attributes=True) class ModuleSeedRequest(BaseModel): """Request to seed service modules.""" force: bool = False class ModuleSeedResponse(BaseModel): """Response from seeding service modules.""" success: bool message: str modules_created: int mappings_created: int class ModuleComplianceOverview(BaseModel): """Overview of compliance status for all modules.""" total_modules: int modules_by_type: Dict[str, int] modules_by_criticality: Dict[str, int] modules_processing_pii: int modules_with_ai: int average_compliance_score: Optional[float] = None regulations_coverage: Dict[str, int] # regulation_code -> module_count