"""Coverage-metrics endpoints. Provides aggregated views of MITRE ATT&CK technique coverage for dashboards and reporting. V2 adds pipeline, team-activity, and validation-rate endpoints for the Red/Blue workflow. Thin HTTP adapter: delegates all data logic to metrics_query_service. """ from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from app.database import get_db from app.dependencies.auth import get_current_user from app.models.user import User from app.schemas.metrics import ( CoverageSummary, RecentTestItem, TacticCoverage, TeamActivity, TestPipelineCounts, ValidationRate, ) from app.services.metrics_query_service import ( get_coverage_by_tactic, get_coverage_summary, get_recent_tests, get_team_activity, get_test_pipeline_counts, get_validation_rate, ) router = APIRouter(prefix="/metrics", tags=["metrics"]) # --------------------------------------------------------------------------- # GET /metrics/summary # --------------------------------------------------------------------------- @router.get("/summary", response_model=CoverageSummary) def coverage_summary( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Return a global coverage summary across all techniques.""" return get_coverage_summary(db) # --------------------------------------------------------------------------- # GET /metrics/by-tactic # --------------------------------------------------------------------------- @router.get("/by-tactic", response_model=list[TacticCoverage]) def coverage_by_tactic( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Return coverage breakdown grouped by tactic.""" return get_coverage_by_tactic(db) # --------------------------------------------------------------------------- # GET /metrics/test-pipeline — counters per pipeline state # --------------------------------------------------------------------------- @router.get("/test-pipeline", response_model=TestPipelineCounts) def test_pipeline( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Return how many tests are in each pipeline state.""" return get_test_pipeline_counts(db) # --------------------------------------------------------------------------- # GET /metrics/team-activity — activity per team # --------------------------------------------------------------------------- @router.get("/team-activity", response_model=list[TeamActivity]) def team_activity( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Return activity summary for Red and Blue teams.""" return get_team_activity(db) # --------------------------------------------------------------------------- # GET /metrics/validation-rate — approval / rejection rates # --------------------------------------------------------------------------- @router.get("/validation-rate", response_model=list[ValidationRate]) def validation_rate( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Return approval and rejection rates for Red Lead and Blue Lead.""" return get_validation_rate(db) # --------------------------------------------------------------------------- # GET /metrics/recent-tests — latest 10 updated tests # --------------------------------------------------------------------------- @router.get("/recent-tests", response_model=list[RecentTestItem]) def recent_tests( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Return the 10 most recently created tests.""" return get_recent_tests(db, limit=10)