feat(dashboard): sort Critical Gaps by risk score instead of MITRE ID

- Create frontend/src/api/risk.ts with getRiskProfiles() API function
- Executive Dashboard fetches risk profiles and builds a techniqueId→profile map
- Critical Gaps sorted by risk_score DESC (highest risk shown first)
- Ties resolved: not_covered before not_evaluated; unscored techniques last
- Table now shows Risk Score (0-100, color-coded) and Risk Level badge per row
- Column renamed to "Critical Gaps — Top 10 by Risk Priority"
This commit is contained in:
kitos
2026-05-28 15:42:52 +02:00
parent a48bd3c475
commit cf19a18810
2 changed files with 139 additions and 36 deletions
+44
View File
@@ -0,0 +1,44 @@
import client from "./client";
// ── Types ───────────────────────────────────────────────────────────
export interface RiskProfile {
id: string;
technique_id: string;
risk_score: number;
likelihood: number;
impact: number;
risk_level: string;
detection_gap: number;
threat_actor_count: number;
osint_signal_count: number;
test_fail_count: number;
test_total_count: number;
test_failure_rate: number;
confidence_level: number;
scoring_breakdown: Record<string, unknown> | null;
recommendations: string[] | null;
computed_at: string;
is_stale: boolean;
}
// ── API Functions ───────────────────────────────────────────────────
/** List risk profiles sorted by risk_score DESC. */
export async function getRiskProfiles(params?: {
risk_level?: string;
min_score?: number;
max_score?: number;
stale_only?: boolean;
limit?: number;
offset?: number;
}): Promise<RiskProfile[]> {
const { data } = await client.get<RiskProfile[]>("/risk/profiles", { params });
return data;
}
/** Get the risk profile for a single technique. */
export async function getRiskProfile(techniqueId: string): Promise<RiskProfile> {
const { data } = await client.get<RiskProfile>(`/risk/profiles/${techniqueId}`);
return data;
}