const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "/api/v1"; export type Dashboard = { clusters: number; nodes: number; workloads: number; networks: number; open_policy_violations: number; faulty_nodes: Array<{ id: string; name: string; status: string }>; top_talkers: Array<{ name: string; bytes: number }>; }; export type SetupStatus = { complete: boolean; has_users: boolean; has_clusters: boolean; }; export type Cluster = { id: string; name: string; api_url: string; provider: string; mode: string; last_sync_status: string | null; }; export type Project = { id: string; name: string; tenant_id: string; description: string | null; }; export type Tenant = { id: string; name: string; description: string | null; }; export type User = { id: string; email: string; display_name: string; is_active: boolean; }; export type Role = { id: string; name: string; permissions: string[]; }; export type Subnet = { id: string; network_id: string; cidr: string; gateway: string | null; dhcp_enabled: boolean; }; export type IpAddress = { id: string; subnet_id: string; address: string; status: string; note: string | null; }; export type Network = { id: string; name: string; kind: string; vlan_id: number | null; gateway: string | null; mtu: number; tags: string[]; }; export type SecurityGroup = { id: string; project_id: string | null; name: string; description: string | null; }; export type SecurityRule = { id: string; security_group_id: string; direction: string; action: string; protocol: string; source: string; destination: string; port: string | null; priority: number; logging: boolean; description: string | null; }; export type Policy = { id: string; name: string; version: number; enabled: boolean; enforcement_mode: string; definition: Record; last_compiled: Record | null; }; export type Workload = { id: string; cluster_id: string; node_id: string; project_id: string | null; external_id: string; name: string; kind: string; status: string; tags: string[]; }; export type WorkloadInsight = { workload: Workload; traffic: Array>; matching_policies: Policy[]; effective_decision: string; audit_mode_notes: string[]; }; export type ServiceCatalogItem = { id: string; name: string; protocol: string; ports: string; editable: boolean; }; export type AuditLog = { id: string; created_at: string; action: string; object_type: string; result: string; }; export function token() { return localStorage.getItem("nexafabric.token"); } export function setToken(value: string) { localStorage.setItem("nexafabric.token", value); } export async function api(path: string, init: RequestInit = {}): Promise { const response = await fetch(`${API_BASE_URL}${path}`, { ...init, headers: { "Content-Type": "application/json", ...(token() ? { Authorization: `Bearer ${token()}` } : {}), ...init.headers, }, }); if (!response.ok) { throw new Error(await response.text()); } return response.json() as Promise; } export async function publicApi(path: string, init: RequestInit = {}): Promise { const response = await fetch(`${API_BASE_URL}${path}`, { ...init, headers: { "Content-Type": "application/json", ...init.headers, }, }); if (!response.ok) { throw new Error(await response.text()); } return response.json() as Promise; } export async function login(email: string, password: string) { const data = await api<{ access_token: string }>("/auth/login", { method: "POST", body: JSON.stringify({ email, password }), }); setToken(data.access_token); return data; }