Files
Aegis/backend/app/schemas/metrics.py

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)