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:
@@ -0,0 +1,106 @@
|
||||
import client from "./client";
|
||||
import type { TestTemplate, TestTemplateSummary } from "../types/models";
|
||||
|
||||
// ── Filters ────────────────────────────────────────────────────────
|
||||
|
||||
export interface TemplateFilters {
|
||||
source?: string;
|
||||
platform?: string;
|
||||
severity?: string;
|
||||
mitre_technique_id?: string;
|
||||
search?: string;
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
// ── Create payload ─────────────────────────────────────────────────
|
||||
|
||||
export interface CreateTemplatePayload {
|
||||
mitre_technique_id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
source?: string;
|
||||
source_url?: string;
|
||||
attack_procedure?: string;
|
||||
expected_detection?: string;
|
||||
platform?: string;
|
||||
tool_suggested?: string;
|
||||
severity?: string;
|
||||
atomic_test_id?: string;
|
||||
}
|
||||
|
||||
// ── Import response ────────────────────────────────────────────────
|
||||
|
||||
export interface ImportAtomicResponse {
|
||||
message: string;
|
||||
imported: number;
|
||||
skipped: number;
|
||||
total_parsed: number;
|
||||
}
|
||||
|
||||
// ── List (paginated, filtered) ─────────────────────────────────────
|
||||
|
||||
/** Fetch a paginated, filtered list of test templates. */
|
||||
export async function getTemplates(
|
||||
filters?: TemplateFilters,
|
||||
): Promise<TestTemplateSummary[]> {
|
||||
const params = new URLSearchParams();
|
||||
if (filters?.source) params.append("source", filters.source);
|
||||
if (filters?.platform) params.append("platform", filters.platform);
|
||||
if (filters?.severity) params.append("severity", filters.severity);
|
||||
if (filters?.mitre_technique_id)
|
||||
params.append("mitre_technique_id", filters.mitre_technique_id);
|
||||
if (filters?.search) params.append("search", filters.search);
|
||||
if (filters?.offset !== undefined)
|
||||
params.append("offset", String(filters.offset));
|
||||
if (filters?.limit !== undefined)
|
||||
params.append("limit", String(filters.limit));
|
||||
|
||||
const { data } = await client.get<TestTemplateSummary[]>(
|
||||
`/test-templates${params.toString() ? `?${params}` : ""}`,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
// ── Detail ─────────────────────────────────────────────────────────
|
||||
|
||||
/** Fetch a single test template by ID. */
|
||||
export async function getTemplateById(id: string): Promise<TestTemplate> {
|
||||
const { data } = await client.get<TestTemplate>(`/test-templates/${id}`);
|
||||
return data;
|
||||
}
|
||||
|
||||
// ── By technique ───────────────────────────────────────────────────
|
||||
|
||||
/** Fetch all templates mapped to a specific MITRE technique. */
|
||||
export async function getTemplatesByTechnique(
|
||||
mitreId: string,
|
||||
): Promise<TestTemplateSummary[]> {
|
||||
const { data } = await client.get<TestTemplateSummary[]>(
|
||||
`/test-templates/by-technique/${mitreId}`,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
// ── Create (admin) ─────────────────────────────────────────────────
|
||||
|
||||
/** Create a custom test template. Admin only. */
|
||||
export async function createTemplate(
|
||||
payload: CreateTemplatePayload,
|
||||
): Promise<TestTemplate> {
|
||||
const { data } = await client.post<TestTemplate>(
|
||||
"/test-templates",
|
||||
payload,
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
// ── Import Atomic Red Team ─────────────────────────────────────────
|
||||
|
||||
/** Trigger Atomic Red Team import. Admin only. */
|
||||
export async function importAtomicTests(): Promise<ImportAtomicResponse> {
|
||||
const { data } = await client.post<ImportAtomicResponse>(
|
||||
"/system/import-atomic-tests",
|
||||
);
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user