feat(phase-13): update frontend types and API clients for Red/Blue workflow (T-113, T-114)
T-113: Rewrite models.ts with v2 types - TestState now includes red_executing/blue_evaluating, add TeamSide, ValidationStatus, TestTemplate, TestTemplateSummary, TestTimelineEntry types, RED_EDITABLE_STATES/BLUE_EDITABLE_STATES constants, and dual validation fields on Test interface. Remove old validated_by/validated_at references from TestDetailPage and techniques API. T-114: Rewrite tests.ts API client with 16 functions covering full Red/Blue workflow (createTestFromTemplate, updateTestRed/Blue, startExecution, submitRed/Blue, validateAsRedLead/BlueLead, reopenTest, getTestTimeline). Rewrite evidence.ts with team parameter on upload/list and new deleteEvidence. Create test-templates.ts with getTemplates, getTemplateById, getTemplatesByTechnique, createTemplate, importAtomicTests.
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
/* ── Shared TypeScript types matching the backend Pydantic schemas ── */
|
||||
|
||||
// ── Users ──────────────────────────────────────────────────────────
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
// ── Techniques ─────────────────────────────────────────────────────
|
||||
|
||||
export interface Technique {
|
||||
id: string;
|
||||
mitre_id: string;
|
||||
@@ -30,6 +34,28 @@ export type TechniqueStatus =
|
||||
| "not_covered"
|
||||
| "review_required";
|
||||
|
||||
// ── Tests (v2 — Red/Blue dual validation) ──────────────────────────
|
||||
|
||||
export type TestState =
|
||||
| "draft"
|
||||
| "red_executing"
|
||||
| "blue_evaluating"
|
||||
| "in_review"
|
||||
| "validated"
|
||||
| "rejected";
|
||||
|
||||
export type TestResult = "detected" | "not_detected" | "partially_detected";
|
||||
|
||||
export type ValidationStatus = "pending" | "approved" | "rejected";
|
||||
|
||||
export type TeamSide = "red" | "blue";
|
||||
|
||||
/** States in which Red Team can edit / upload evidence. */
|
||||
export const RED_EDITABLE_STATES: TestState[] = ["draft", "red_executing"];
|
||||
|
||||
/** States in which Blue Team can edit / upload evidence. */
|
||||
export const BLUE_EDITABLE_STATES: TestState[] = ["blue_evaluating"];
|
||||
|
||||
export interface Test {
|
||||
id: string;
|
||||
technique_id: string;
|
||||
@@ -42,13 +68,30 @@ export interface Test {
|
||||
created_by: string | null;
|
||||
result: TestResult | null;
|
||||
state: TestState;
|
||||
validated_by: string | null;
|
||||
validated_at: string | null;
|
||||
created_at: string;
|
||||
|
||||
// Red Team fields
|
||||
red_summary: string | null;
|
||||
attack_success: boolean | null;
|
||||
red_validated_by: string | null;
|
||||
red_validated_at: string | null;
|
||||
red_validation_status: ValidationStatus | null;
|
||||
red_validation_notes: string | null;
|
||||
|
||||
// Blue Team fields
|
||||
blue_summary: string | null;
|
||||
detection_result: TestResult | null;
|
||||
blue_validated_by: string | null;
|
||||
blue_validated_at: string | null;
|
||||
blue_validation_status: ValidationStatus | null;
|
||||
blue_validation_notes: string | null;
|
||||
|
||||
// Separated evidences
|
||||
red_evidences: Evidence[];
|
||||
blue_evidences: Evidence[];
|
||||
}
|
||||
|
||||
export type TestState = "draft" | "in_review" | "validated" | "rejected";
|
||||
export type TestResult = "detected" | "not_detected" | "partially_detected";
|
||||
// ── Evidence (v2 — with team) ──────────────────────────────────────
|
||||
|
||||
export interface Evidence {
|
||||
id: string;
|
||||
@@ -58,8 +101,51 @@ export interface Evidence {
|
||||
sha256_hash: string;
|
||||
uploaded_by: string | null;
|
||||
uploaded_at: string;
|
||||
team: TeamSide;
|
||||
notes: string | null;
|
||||
download_url?: string;
|
||||
}
|
||||
|
||||
// ── Test Templates ─────────────────────────────────────────────────
|
||||
|
||||
export interface TestTemplate {
|
||||
id: string;
|
||||
mitre_technique_id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
source: string;
|
||||
source_url: string | null;
|
||||
attack_procedure: string | null;
|
||||
expected_detection: string | null;
|
||||
platform: string | null;
|
||||
tool_suggested: string | null;
|
||||
severity: string | null;
|
||||
atomic_test_id: string | null;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface TestTemplateSummary {
|
||||
id: string;
|
||||
mitre_technique_id: string;
|
||||
name: string;
|
||||
source: string;
|
||||
platform: string | null;
|
||||
severity: string | null;
|
||||
}
|
||||
|
||||
// ── Timeline ───────────────────────────────────────────────────────
|
||||
|
||||
export interface TestTimelineEntry {
|
||||
id: string;
|
||||
action: string;
|
||||
user_id: string | null;
|
||||
timestamp: string;
|
||||
details: Record<string, unknown>;
|
||||
}
|
||||
|
||||
// ── Intel ──────────────────────────────────────────────────────────
|
||||
|
||||
export interface IntelItem {
|
||||
id: string;
|
||||
technique_id: string | null;
|
||||
@@ -70,6 +156,8 @@ export interface IntelItem {
|
||||
reviewed: boolean;
|
||||
}
|
||||
|
||||
// ── Metrics ────────────────────────────────────────────────────────
|
||||
|
||||
export interface CoverageSummary {
|
||||
total_techniques: number;
|
||||
validated: number;
|
||||
|
||||
Reference in New Issue
Block a user