feat(phase-25): add detection rule associations, checklist UI and evaluation workflow (T-215, T-216)

This commit is contained in:
2026-02-09 16:44:35 +01:00
parent cd124b655b
commit f4de12d8ab
9 changed files with 970 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
import client from "./client";
export interface DetectionRuleItem {
id: string;
mitre_technique_id: string;
title: string;
description: string | null;
source: string;
source_url: string | null;
rule_content?: string;
rule_format: string;
severity: string | null;
platforms: string[];
log_sources: Record<string, string> | null;
is_primary?: boolean;
is_active?: boolean;
// Evaluation fields (from for-test endpoint)
triggered?: boolean | null;
notes?: string | null;
evaluated_at?: string | null;
result_id?: string | null;
}
export interface DetectionRulesForTest {
test_id: string;
mitre_technique_id: string;
rules: DetectionRuleItem[];
total: number;
evaluated: number;
triggered: number;
detection_rate: number;
}
export interface EvaluatePayload {
test_id: string;
detection_rule_id: string;
triggered: boolean | null;
notes?: string;
}
export interface EvaluateResult {
id: string;
triggered: boolean | null;
notes: string | null;
evaluated_at: string | null;
}
/** List detection rules with optional filters. */
export async function listDetectionRules(params?: {
technique?: string;
source?: string;
severity?: string;
search?: string;
offset?: number;
limit?: number;
}): Promise<{ total: number; items: DetectionRuleItem[] }> {
const { data } = await client.get("/detection-rules", { params });
return data;
}
/** Get detection rules for a specific test (with evaluation results). */
export async function getDetectionRulesForTest(testId: string): Promise<DetectionRulesForTest> {
const { data } = await client.get<DetectionRulesForTest>(`/detection-rules/for-test/${testId}`);
return data;
}
/** Get detection rules for a specific template. */
export async function getDetectionRulesForTemplate(
templateId: string
): Promise<{ template_id: string; rules: DetectionRuleItem[]; total: number }> {
const { data } = await client.get(`/detection-rules/for-template/${templateId}`);
return data;
}
/** Evaluate a detection rule for a test. */
export async function evaluateDetectionRule(payload: EvaluatePayload): Promise<EvaluateResult> {
const { data } = await client.post<EvaluateResult>("/detection-rules/evaluate", payload);
return data;
}
/** Trigger auto-association of templates ↔ detection rules (admin). */
export async function autoAssociateDetectionRules(): Promise<{
created: number;
skipped: number;
total_associations: number;
}> {
const { data } = await client.post("/detection-rules/auto-associate");
return data;
}