Files
trustos/frontend/src/lib/api.ts
drjones 09bae21c00 Add premium features roadmap and quick-win implementation guides
- PREMIUM_FEATURES_ROADMAP.md: Strategic feature roadmap for 3x-5x revenue expansion
  * Top 5 features: Board Autopilot, Insurance Integration, Predictive Modeling, Workflow Integration, Executive Monitoring
  * Revenue projections: $250K → $665K ARR over 3 years
  * 18+ feature ideas ranked by revenue, complexity, stickiness

- QUICK_WIN_FEATURES.md: Implementation guides for immediate value
  * Board Presentation Autopilot: 14-day implementation, $30K-$40K/year
  * Insurance Savings Calculator: 10-day implementation, $25K-$50K/year
  * Step-by-step code examples and deployment plan

Enables:
- 2.5x-3x wallet expansion per customer
- Shift from audit services to sticky SaaS
- 140-150% NRR with premium features
- $3.5M+ Year 1 revenue with premium offerings

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-07 09:54:12 +00:00

141 lines
4.1 KiB
TypeScript

const BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
let authToken: string | null = null;
export function setAuthToken(token: string | null) {
authToken = token;
}
async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
const headers: Record<string, string> = {
"Content-Type": "application/json",
...(options.headers as Record<string, string>),
};
if (authToken) {
headers["Authorization"] = `Bearer ${authToken}`;
}
const res = await fetch(`${BASE}${path}`, { ...options, headers });
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }));
throw new Error(err.detail || `HTTP ${res.status}`);
}
return res.json();
}
export const api = {
login: (email: string, password: string) =>
request<{ access_token: string; role: string; tenant_id: string; full_name: string }>(
"/api/v1/auth/login",
{ method: "POST", body: JSON.stringify({ email, password }) }
),
me: () => request<{ id: string; email: string; full_name: string; role: string; tenant_id: string }>(
"/api/v1/auth/me"
),
dashboard: (tenantId: string) =>
request<DashboardData>(`/api/v1/dashboard/${tenantId}`),
findings: (tenantId: string, params?: string) =>
request<Finding[]>(`/api/v1/findings?tenant_id=${tenantId}${params ? "&" + params : ""}`),
finding: (id: string) =>
request<Finding>(`/api/v1/findings/${id}`),
updateFindingStatus: (id: string, body: { status: string; resolution_note?: string }) =>
request<Finding>(`/api/v1/findings/${id}/status`, {
method: "PATCH",
body: JSON.stringify(body),
}),
attackPaths: (findingId: string) =>
request<AttackPath[]>(`/api/v1/attack-paths/${findingId}`),
footprint: (tenantId: string) =>
request<FootprintData>(`/api/v1/footprint/${tenantId}`),
aiExplain: (findingId: string, question: string) =>
request<{ question: string; answer: string }>(`/api/v1/ai/explain/${findingId}?question=${encodeURIComponent(question)}`),
aiExplainFinding: (findingId: string) =>
request<{
finding_id: string;
summary?: string;
business_impact?: string;
impact_level?: string;
remediation_steps?: string;
fix_priority?: string;
generated_at?: string;
status: "available" | "processing";
message?: string;
}>(`/api/v1/findings/${findingId}/ai-explain`),
};
// ─── Types ────────────────────────────────────────────────────────────────────
export interface DashboardData {
tenant_name: string;
current_score: number;
previous_score: number | null;
score_delta: number | null;
score_trend: { date: string; score: number }[];
top_risks: RiskCard[];
open_critical: number;
open_high: number;
open_medium: number;
total_open: number;
baseline_score: number | null;
baseline_date: string | null;
}
export interface RiskCard {
id: string;
title: string;
ai_summary: string | null;
ai_business_impact: string | null;
ai_impact_level: string | null;
ai_fix_priority: string | null;
severity: string;
category: string;
}
export interface Finding {
id: string;
tenant_id: string;
title: string;
severity: string;
status: string;
category: string;
technical_description: string | null;
cve_id: string | null;
cvss_score: number | null;
affected_component: string | null;
ai_summary: string | null;
ai_business_impact: string | null;
ai_impact_level: string | null;
ai_remediation_steps: string | null;
ai_fix_priority: string | null;
assignee_email: string | null;
due_date: string | null;
is_top_risk: boolean;
source: string | null;
created_at: string;
updated_at: string;
}
export interface AttackPath {
id: string;
finding_id: string;
title: string;
ai_narrative: string | null;
nodes_json: string | null;
edges_json: string | null;
}
export interface FootprintData {
tenant_id: string;
executives: { id: string; name: string; title: string; email: string }[];
footprint_findings: any[];
total_exposures: number;
}