feat(tests): types and API client for red/blue review workflow

This commit is contained in:
kitos
2026-07-06 12:02:07 +02:00
parent 8a028bf0ed
commit 82033b5037
2 changed files with 40 additions and 0 deletions
+25
View File
@@ -197,6 +197,31 @@ export async function startBlueWork(testId: string): Promise<Test> {
return data; return data;
} }
// ── Lead Review Gates (red_review / blue_review) ────────────────────
export interface RedReviewPayload {
decision: "approve" | "reopen";
notes?: string;
}
export interface BlueReviewPayload {
decision: "approve" | "reopen" | "gap";
notes?: string;
system_gaps?: string;
}
/** Assigned Red Lead approves or reopens a test sitting in red_review. */
export async function reviewAsRedLead(testId: string, payload: RedReviewPayload): Promise<Test> {
const { data } = await client.post<Test>(`/tests/${testId}/review-red`, payload);
return data;
}
/** Assigned Blue Lead approves, reopens, or flags a capability gap on a test in blue_review. */
export async function reviewAsBlueLead(testId: string, payload: BlueReviewPayload): Promise<Test> {
const { data } = await client.post<Test>(`/tests/${testId}/review-blue`, payload);
return data;
}
// ── Lead Validation ──────────────────────────────────────────────── // ── Lead Validation ────────────────────────────────────────────────
/** Red Lead approves/rejects the red side. */ /** Red Lead approves/rejects the red side. */
+15
View File
@@ -48,7 +48,9 @@ export type TechniqueStatus =
export type TestState = export type TestState =
| "draft" | "draft"
| "red_executing" | "red_executing"
| "red_review" // Red Lead reviews the operator's work before it queues for Blue Team
| "blue_evaluating" | "blue_evaluating"
| "blue_review" // Blue Lead reviews the operator's work before cross-validation
| "in_review" | "in_review"
| "validated" | "validated"
| "rejected" | "rejected"
@@ -121,6 +123,19 @@ export interface Test {
red_tech_assignee: string | null; red_tech_assignee: string | null;
blue_tech_assignee: string | null; blue_tech_assignee: string | null;
// Red Team review fields
red_reviewer_assignee: string | null;
red_review_by: string | null;
red_review_at: string | null;
red_review_notes: string | null;
// Blue Team review fields
blue_reviewer_assignee: string | null;
blue_review_by: string | null;
blue_review_at: string | null;
blue_review_notes: string | null;
system_gaps: string | null;
// On-hold fields // On-hold fields
is_on_hold: boolean; is_on_hold: boolean;
hold_reason: string | null; hold_reason: string | null;