/** Shared types + query keys for MITRE ATT&CK browsing. */ export interface MitreTactic { id: string; external_id: string; short_name: string; name: string; description: string | null; url: string | null; } export interface MitreTechnique { id: string; external_id: string; name: string; description: string | null; url: string | null; tactics: Array<{ external_id: string; name: string }>; } export interface MitreSubtechnique { id: string; external_id: string; name: string; description: string | null; url: string | null; technique_id: string; } export interface Paginated { items: T[]; total: number; limit: number; offset: number; } export interface MitreStatus { last_sync: string | null; version: string | null; source_url: string | null; default_url: string; default_version: string; } export type MitreTagKind = 'tactic' | 'technique' | 'subtechnique'; export interface MitreTag { kind: MitreTagKind; id: string; external_id: string; name: string; } // Query keys. `status` + `matrix` drive the M4 picker; the per-list factories // (`tactics`/`techniques`/`subtechniques`) are unused today but the M5 // template forms will consume them for the standalone REST endpoints when // users edit a single test's tags inline. export const mitreKeys = { status: ['mitre', 'status'] as const, matrix: ['mitre', 'matrix'] as const, tactics: (q?: string) => ['mitre', 'tactics', q ?? ''] as const, techniques: (tactic?: string, q?: string) => ['mitre', 'techniques', tactic ?? '', q ?? ''] as const, subtechniques: (technique?: string, q?: string) => ['mitre', 'subtechniques', technique ?? '', q ?? ''] as const, }; export interface MatrixSubtechnique { id: string; external_id: string; name: string; } export interface MatrixTechnique { id: string; external_id: string; name: string; subtechniques: MatrixSubtechnique[]; } export interface MatrixTactic { id: string; external_id: string; short_name: string; name: string; techniques: MatrixTechnique[]; } export interface MitreMatrix { tactics: MatrixTactic[]; } /** Mirror of backend `SyncResultOut` (`api/mitre.py`). */ export interface MitreSyncResult { tactics_upserted: number; techniques_upserted: number; subtechniques_upserted: number; subtechniques_skipped_orphan: number; technique_tactic_links: number; version: string | null; source: string; started_at: string; finished_at: string; duration_ms: number; }