"""Pydantic schemas for coverage-metrics endpoints.""" # Import datetime from datetime from datetime import datetime # Import BaseModel, ConfigDict from pydantic from pydantic import BaseModel, ConfigDict # Define class CoverageSummary class CoverageSummary(BaseModel): """Global coverage summary across all MITRE ATT&CK techniques.""" # total_techniques: int total_techniques: int # validated: int validated: int # partial: int partial: int # not_covered: int not_covered: int # in_progress: int in_progress: int # not_evaluated: int not_evaluated: int # coverage_percentage: float # (validated + partial) / total * 100 coverage_percentage: float # (validated + partial) / total * 100 # Define class TacticCoverage class TacticCoverage(BaseModel): """Coverage breakdown for a single tactic.""" # tactic: str tactic: str # total: int total: int # validated: int validated: int # partial: int partial: int # not_covered: int not_covered: int # not_evaluated: int not_evaluated: int # in_progress: int in_progress: int # ── V2 — Test Pipeline ──────────────────────────────────────────────── class TestPipelineCounts(BaseModel): """Counters per state in the test pipeline.""" # Assign draft = 0 draft: int = 0 # Assign red_executing = 0 red_executing: int = 0 # Assign blue_evaluating = 0 blue_evaluating: int = 0 # Assign in_review = 0 in_review: int = 0 # Assign validated = 0 validated: int = 0 # Assign rejected = 0 rejected: int = 0 # Assign total = 0 total: int = 0 # ── V2 — Team Activity ─────────────────────────────────────────────── class TeamActivity(BaseModel): """Activity summary for a team (Red or Blue).""" # team: str team: str # Assign tests_completed = 0 tests_completed: int = 0 # Assign tests_pending = 0 tests_pending: int = 0 # Assign avg_completion_hours = None avg_completion_hours: float | None = None # ── V2 — Validation Rate ───────────────────────────────────────────── class ValidationRate(BaseModel): """Approval / rejection rate for a manager role.""" # role: str # "red_lead" or "blue_lead" role: str # "red_lead" or "blue_lead" # Assign total_reviewed = 0 total_reviewed: int = 0 # Assign approved = 0 approved: int = 0 # Assign rejected = 0 rejected: int = 0 # Assign approval_rate = 0.0 # percentage approval_rate: float = 0.0 # percentage # ── V2 — Recent Test ───────────────────────────────────────────────── class RecentTestItem(BaseModel): """Lightweight test entry for the recent-tests widget.""" # id: str id: str # name: str name: str # state: str state: str # Assign technique_mitre_id = None technique_mitre_id: str | None = None # Assign technique_name = None technique_name: str | None = None # Assign created_at = None created_at: datetime | None = None # Assign model_config = ConfigDict(from_attributes=True) model_config = ConfigDict(from_attributes=True)