feat: Phase 7 - Frontend scaffolding and auth (T-023, T-024, T-025)
T-023: Initialize React project - Vite + React 19 + TypeScript scaffold - Tailwind CSS v4 with @tailwindcss/vite plugin - Dependencies: react-router-dom, axios, @tanstack/react-query, lucide-react - Project structure: api/, components/, pages/, context/, types/, hooks/, lib/ T-024: API client and auth context - Axios client with JWT interceptor (auto-attach token, clear on 401) - login() and getMe() API functions - AuthContext: user state, login, logout, isAuthenticated, isLoading - Token persistence via localStorage with hydration on mount - TypeScript types for all backend models T-025: Login page and layout - LoginPage with form, error handling, redirect on success - Layout with sidebar + header + Outlet - Sidebar with role-aware navigation (System only for admin) - ProtectedRoute wrapper with role-based access control - Routes: /login, /dashboard, /techniques, /tests, /system
This commit is contained in:
91
frontend/src/types/models.ts
Normal file
91
frontend/src/types/models.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/* ── Shared TypeScript types matching the backend Pydantic schemas ── */
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
export interface Technique {
|
||||
id: string;
|
||||
mitre_id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
tactic: string | null;
|
||||
platforms: string[];
|
||||
mitre_version: string | null;
|
||||
mitre_last_modified: string | null;
|
||||
is_subtechnique: boolean;
|
||||
parent_mitre_id: string | null;
|
||||
status_global: TechniqueStatus;
|
||||
review_required: boolean;
|
||||
last_review_date: string | null;
|
||||
}
|
||||
|
||||
export type TechniqueStatus =
|
||||
| "not_evaluated"
|
||||
| "in_progress"
|
||||
| "validated"
|
||||
| "partial"
|
||||
| "not_covered"
|
||||
| "review_required";
|
||||
|
||||
export interface Test {
|
||||
id: string;
|
||||
technique_id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
platform: string | null;
|
||||
procedure_text: string | null;
|
||||
tool_used: string | null;
|
||||
execution_date: string | null;
|
||||
created_by: string | null;
|
||||
result: TestResult | null;
|
||||
state: TestState;
|
||||
validated_by: string | null;
|
||||
validated_at: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export type TestState = "draft" | "in_review" | "validated" | "rejected";
|
||||
export type TestResult = "detected" | "not_detected" | "partially_detected";
|
||||
|
||||
export interface Evidence {
|
||||
id: string;
|
||||
test_id: string;
|
||||
file_name: string;
|
||||
file_path: string;
|
||||
sha256_hash: string;
|
||||
uploaded_by: string | null;
|
||||
uploaded_at: string;
|
||||
}
|
||||
|
||||
export interface IntelItem {
|
||||
id: string;
|
||||
technique_id: string | null;
|
||||
url: string;
|
||||
title: string | null;
|
||||
source: string | null;
|
||||
detected_at: string;
|
||||
reviewed: boolean;
|
||||
}
|
||||
|
||||
export interface CoverageSummary {
|
||||
total_techniques: number;
|
||||
validated: number;
|
||||
partial: number;
|
||||
not_covered: number;
|
||||
in_progress: number;
|
||||
not_evaluated: number;
|
||||
coverage_percentage: number;
|
||||
}
|
||||
|
||||
export interface TacticCoverage {
|
||||
tactic: string;
|
||||
total: number;
|
||||
validated: number;
|
||||
partial: number;
|
||||
not_covered: number;
|
||||
not_evaluated: number;
|
||||
in_progress: number;
|
||||
}
|
||||
Reference in New Issue
Block a user