86 lines
2.3 KiB
Python
86 lines
2.3 KiB
Python
"""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)
|