feat(dashboard): Phase 13 — Executive Dashboard
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

PostureSnapshot model, Alembic migration (b039exec), schemas, service
aggregating all phases (coverage/risk/operations/knowledge/MTTD), and
router at /api/v1/dashboard with executive view, KPIs, coverage-by-tactic,
posture-history, posture-snapshot, and activity-feed endpoints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-05-20 16:20:21 +02:00
parent 41a0c536bb
commit ab591d30c4
8 changed files with 997 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
"""Phase 13: Executive Dashboard — Pydantic schemas."""
from __future__ import annotations
from datetime import date, datetime
from typing import Any, Dict, List, Optional
from uuid import UUID
from pydantic import BaseModel, Field
class PostureSnapshotOut(BaseModel):
id: UUID
snapshot_date: date
# Coverage
total_techniques: int
validated_count: int
partial_count: int
not_covered_count: int
coverage_pct: float
# Risk
avg_risk_score: float
critical_count: int
high_count: int
medium_count: int
low_count: int
# Operations
open_queue_items: int
orphan_techniques: int
# Knowledge
playbook_count: int
lesson_count: int
# MTTD
mttd_avg_seconds: Optional[float] = None
executions_30d: int
detection_rate_30d: Optional[float] = None
# Meta
created_by: Optional[UUID] = None
created_at: Optional[datetime] = None
extra: Optional[Dict[str, Any]] = None
class Config:
from_attributes = True
class ExecutiveSummary(BaseModel):
"""Full executive view — current posture + trends."""
snapshot: PostureSnapshotOut
coverage_trend: List[Dict[str, Any]] = Field(
default_factory=list,
description="Last 30-day coverage_pct series [{date, value}]",
)
risk_trend: List[Dict[str, Any]] = Field(
default_factory=list,
description="Last 30-day avg_risk_score series [{date, value}]",
)
top_risks: List[Dict[str, Any]] = Field(
default_factory=list,
description="Top 5 highest-risk techniques",
)
coverage_by_tactic: List[Dict[str, Any]] = Field(
default_factory=list,
description="Per-tactic validated/partial/not_covered counts",
)
recent_activity: List[Dict[str, Any]] = Field(
default_factory=list,
description="Most-recent events (tests, paths, queue changes)",
)
class KpiBlock(BaseModel):
"""Compact KPI block for a dashboard header."""
coverage_pct: float
avg_risk_score: float
critical_count: int
open_queue_items: int
orphan_techniques: int
mttd_avg_seconds: Optional[float] = None
detection_rate_30d: Optional[float] = None
playbook_count: int
lesson_count: int
snapshot_date: date
snapshot_id: UUID
class CoverageByTactic(BaseModel):
tactic: str
total: int
validated: int
partial: int
not_covered: int
coverage_pct: float
class PostureHistoryEntry(BaseModel):
snapshot_date: date
coverage_pct: float
avg_risk_score: float
critical_count: int
open_queue_items: int
class ActivityEntry(BaseModel):
ts: datetime
category: str # "test" | "attack_path" | "queue" | "osint"
title: str
detail: Optional[str] = None