"""Phase 12: Risk Intelligence schemas.""" from datetime import datetime from typing import Any, Dict, List, Optional from uuid import UUID from pydantic import BaseModel, ConfigDict VALID_RISK_LEVELS = ["critical", "high", "medium", "low", "info"] class TechniqueRiskProfileOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: UUID technique_id: UUID risk_score: float likelihood: float impact: float risk_level: str detection_gap: float threat_actor_count: int osint_signal_count: int test_fail_count: int test_total_count: int test_failure_rate: float confidence_level: float scoring_breakdown: Optional[Dict[str, Any]] recommendations: Optional[List[str]] computed_at: datetime is_stale: bool class RiskMatrixEntry(BaseModel): model_config = ConfigDict(from_attributes=True) technique_id: UUID technique_name: Optional[str] = None technique_tid: Optional[str] = None # e.g. "T1059" risk_score: float likelihood: float impact: float risk_level: str detection_gap: float computed_at: datetime class RiskSummary(BaseModel): total_techniques: int scored_techniques: int stale_count: int by_level: Dict[str, int] # {"critical": 3, "high": 12, ...} avg_risk_score: float top_risks: List[RiskMatrixEntry] class RecommendationItem(BaseModel): technique_id: UUID technique_name: Optional[str] = None technique_tid: Optional[str] = None risk_level: str risk_score: float recommendations: List[str] priority: int # 1 = highest class ComputeResult(BaseModel): computed: int skipped: int errors: int duration_seconds: float