chore: initial project setup with backend, frontend, CI/CD, and documentation
Add complete NexaFabric project structure including: - FastAPI backend with SQLAlchemy models, JWT auth, RBAC, audit logging, and provider interfaces - React + TypeScript frontend with Vite, Tailwind CSS, TanStack Query, and Zustand - Docker Compose configuration for PostgreSQL, Redis, API, worker, frontend, and nginx - GitHub Actions and GitLab CI workflows for testing, linting, building, and security scanning - Environment
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
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 Cluster = {
|
||||
id: string;
|
||||
name: string;
|
||||
api_url: string;
|
||||
provider: string;
|
||||
mode: string;
|
||||
last_sync_status: string | null;
|
||||
};
|
||||
|
||||
export type Network = {
|
||||
id: string;
|
||||
name: string;
|
||||
kind: string;
|
||||
vlan_id: number | null;
|
||||
gateway: string | null;
|
||||
mtu: number;
|
||||
tags: string[];
|
||||
};
|
||||
|
||||
export type Policy = {
|
||||
id: string;
|
||||
name: string;
|
||||
version: number;
|
||||
enabled: boolean;
|
||||
definition: Record<string, unknown>;
|
||||
};
|
||||
|
||||
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<T>(path: string, init: RequestInit = {}): Promise<T> {
|
||||
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<T>;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user