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