const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"; let authToken: string | null = null; export function setAuthToken(token: string) { authToken = token; if (typeof window !== "undefined") { localStorage.setItem("auth_token", token); } } export function getAuthToken(): string | null { if (authToken) return authToken; if (typeof window !== "undefined") { return localStorage.getItem("auth_token"); } return null; } export function clearAuthToken() { authToken = null; if (typeof window !== "undefined") { localStorage.removeItem("auth_token"); } } async function apiFetch(path: string, init?: RequestInit): Promise { const token = getAuthToken(); const headers: Record = { "Content-Type": "application/json" }; if (token) { headers["Authorization"] = `Bearer ${token}`; } const res = await fetch(`${API_BASE}${path}`, { headers: { ...headers, ...init?.headers }, ...init, }); if (!res.ok) { if (res.status === 401) { clearAuthToken(); if (typeof window !== "undefined") { window.location.href = "/login"; } } const body = await res.json().catch(() => ({})); throw new Error(body.message || res.statusText); } return res.json(); } export interface Subscriber { id: number; imsi: string; msisdn: string; first_name: string; last_name: string; email: string; organization_id: string; status: "active" | "inactive" | "suspended" | "terminated" | "provisioning"; plan_id: number; balance: number; profile_status: string; created_at: string; updated_at: string; } export interface SystemStats { active_sessions: number; total_accounts: number; blocked_users: number; low_balance_alerts: number; uptime: number; } export interface HealthStatus { redis_connected: boolean; active_sync: boolean; last_sync: string; memory_usage: number; } export interface PaginatedResponse { data: T[]; total: number; page: number; page_size: number; } // Services Management Types export interface Service { name: string; namespace: string; creationTimestamp: string; labels: Record; replicas: number; readyReplicas: number; availableReplicas: number; updatedReplicas: number; unavailableReplicas: number; } export interface ServiceHealth { service: string; status: "healthy" | "degraded" | "unhealthy"; replicas_desired: number; replicas_ready: number; replicas_available: number; } export interface PodStatus { deployment: { replicas: number; ready_replicas: number; available_replicas: number; updated_replicas: number; unavailable_replicas: number; }; pods: Array<{ name: string; phase: string; node_name: string; created: string; conditions: Array<{ type: string; status: string; reason: string; }>; }>; } export interface ServiceEvent { type: string; reason: string; message: string; first_timestamp: string; last_timestamp: string; count: number; } // Monitoring & Metrics Types export interface MetricSample { timestamp: string; value: number; } export interface Alert { name: string; state: string; severity: string; summary: string; description: string; startsAt: string; endsAt?: string; } // Deployment Management Types export interface Deployment { id: number; service: string; version: string; status: "pending" | "running" | "completed" | "failed" | "rolling_back"; started_at: string; completed_at?: string; metadata: Record; } export interface DeploymentStartRequest { service: string; version: string; metadata?: Record; } // Plugin Management Types export interface Plugin { id: number; name: string; version: string; description: string; author: string; enabled: boolean; config: Record; created_at: string; updated_at: string; } export interface PluginInstallRequest { name: string; version: string; config?: Record; } // Automation Management Types export interface Automation { id: number; name: string; description: string; trigger: string; schedule?: string; enabled: boolean; config: Record; created_at: string; updated_at: string; } export interface AutomationRun { id: number; automation_id: number; status: "pending" | "running" | "completed" | "failed"; started_at: string; completed_at?: string; output?: string; error?: string; } // Billing & Invoicing Types export interface Invoice { id: number; subscriber_id: number; amount: number; currency: string; status: "draft" | "sent" | "paid" | "overdue" | "cancelled"; due_date: string; created_at: string; line_items: Array<{ description: string; quantity: number; unit_price: number; amount: number; }>; } export interface Payment { id: number; invoice_id: number; amount: number; currency: string; status: "pending" | "completed" | "failed" | "refunded"; method: string; transaction_id: string; created_at: string; } // Configuration Management Types export interface ConfigEntry { id: number; key: string; value: string; type: string; sensitive: boolean; description: string; updated_at: string; } export interface ConfigValidationResult { valid: boolean; errors: string[]; } // Chaos Engineering Types export interface ChaosExperiment { id: number; name: string; type: string; target: string; parameters: Record; status: "pending" | "running" | "completed" | "failed" | "cancelled"; created_at: string; started_at?: string; completed_at?: string; } export interface ChaosExperimentRequest { name: string; type: string; target: string; parameters: Record; } // Authentication Types export interface LoginRequest { username: string; password: string; } export interface RegisterRequest { username: string; email: string; password: string; first_name: string; last_name: string; } export interface AuthResponse { access_token: string; refresh_token: string; user: User; } export interface User { id: number; username: string; email: string; first_name: string; last_name: string; role: string; is_active: boolean; created_at: string; updated_at: string; } export interface ChangePasswordRequest { old_password: string; new_password: string; } export const api = { // Authentication auth: { login: (data: LoginRequest) => apiFetch("/v1/auth/login", { method: "POST", body: JSON.stringify(data) }), register: (data: RegisterRequest) => apiFetch("/v1/auth/register", { method: "POST", body: JSON.stringify(data) }), refresh: (refreshToken: string) => apiFetch("/v1/auth/refresh", { method: "POST", body: JSON.stringify({ refresh_token: refreshToken }), headers: { "Content-Type": "application/json" } }), logout: () => apiFetch("/v1/auth/logout", { method: "POST" }), profile: () => apiFetch("/v1/auth/profile"), changePassword: (data: ChangePasswordRequest) => apiFetch("/v1/auth/change-password", { method: "POST", body: JSON.stringify(data) }), }, subscribers: { list: (page = 1, pageSize = 20) => apiFetch>(`/api/subscribers?page=${page}&pageSize=${pageSize}`), get: (id: number) => apiFetch(`/api/subscribers/${id}`), create: (data: Partial) => apiFetch("/api/subscribers", { method: "POST", body: JSON.stringify(data) }), update: (id: number, data: Partial) => apiFetch(`/api/subscribers/${id}`, { method: "PUT", body: JSON.stringify(data) }), delete: (id: number) => apiFetch(`/api/subscribers/${id}`, { method: "DELETE" }), }, system: { stats: () => apiFetch("/api/system/stats"), health: () => apiFetch("/api/system/health"), }, // Services Management services: { list: () => apiFetch<{ services: Service[]; total: number; namespace: string }>("/v1/services"), get: (id: string) => apiFetch(`/v1/services/${id}`), restart: (id: string) => apiFetch<{ message: string; service: string }>(`/v1/services/${id}/restart`, { method: "POST" }), logs: (id: string, tailLines = 100) => apiFetch(`/v1/services/${id}/logs?tailLines=${tailLines}`), start: (id: string) => apiFetch<{ message: string; service: string }>(`/v1/services/${id}/start`, { method: "POST" }), stop: (id: string) => apiFetch<{ message: string; service: string }>(`/v1/services/${id}/stop`, { method: "POST" }), scale: (id: string, replicas: number) => apiFetch<{ message: string; service: string; replicas: number }>(`/v1/services/${id}/scale`, { method: "POST", body: JSON.stringify({ replicas }) }), health: (id: string) => apiFetch(`/v1/services/${id}/health`), podStatus: (id: string) => apiFetch(`/v1/services/${id}/pods`), events: (id: string, limit = 50) => apiFetch<{ events: ServiceEvent[]; total: number }>(`/v1/services/${id}/events?limit=${limit}`), }, // Monitoring & Metrics monitoring: { metrics: (query = "up") => apiFetch<{ data: MetricSample[] }>(`/v1/monitoring/metrics?query=${query}`), alerts: () => apiFetch("/v1/monitoring/alerts"), health: () => apiFetch<{ status: string; services: Record }>("/v1/monitoring/health"), logs: (service?: string, level?: string, limit = 100) => apiFetch<{ logs: string[]; total: number }>(`/v1/monitoring/logs?service=${service || ""}&level=${level || ""}&limit=${limit}`), }, // Deployment Management deployments: { status: () => apiFetch<{ deployments: Deployment[]; total: number }>("/v1/deploy/status"), start: (data: DeploymentStartRequest) => apiFetch("/v1/deploy/start", { method: "POST", body: JSON.stringify(data) }), rollback: (deploymentId: number) => apiFetch("/v1/deploy/rollback", { method: "POST", body: JSON.stringify({ deployment_id: deploymentId }) }), history: (page = 1, pageSize = 20) => apiFetch>(`/v1/deploy/history?page=${page}&pageSize=${pageSize}`), }, // Plugin Management plugins: { list: (enabled?: boolean) => apiFetch<{ plugins: Plugin[]; total: number }>(`/v1/plugins${enabled !== undefined ? `?enabled=${enabled}` : ""}`), install: (data: PluginInstallRequest) => apiFetch("/v1/plugins/install", { method: "POST", body: JSON.stringify(data) }), uninstall: (id: number) => apiFetch(`/v1/plugins/${id}`, { method: "DELETE" }), enable: (id: number) => apiFetch(`/v1/plugins/${id}/enable`, { method: "POST" }), disable: (id: number) => apiFetch(`/v1/plugins/${id}/disable`, { method: "POST" }), get: (id: number) => apiFetch(`/v1/plugins/${id}`), }, // Automation Management automation: { list: (enabled?: boolean) => apiFetch<{ automations: Automation[]; total: number }>(`/v1/automation${enabled !== undefined ? `?enabled=${enabled}` : ""}`), run: (automationId: number, parameters?: Record) => apiFetch("/v1/automation/run", { method: "POST", body: JSON.stringify({ automation_id: automationId, parameters }) }), schedule: (automationId: number, schedule: string) => apiFetch(`/v1/automation/${automationId}/schedule`, { method: "POST", body: JSON.stringify({ schedule }) }), logs: (automationId?: number, page = 1, pageSize = 20) => apiFetch>(`/v1/automation/logs${automationId ? `?automation_id=${automationId}&` : "?"}page=${page}&pageSize=${pageSize}`), get: (id: number) => apiFetch(`/v1/automation/${id}`), create: (data: Partial) => apiFetch("/v1/automation", { method: "POST", body: JSON.stringify(data) }), update: (id: number, data: Partial) => apiFetch(`/v1/automation/${id}`, { method: "PUT", body: JSON.stringify(data) }), delete: (id: number) => apiFetch(`/v1/automation/${id}`, { method: "DELETE" }), }, // Billing & Invoicing billing: { invoices: (subscriberId?: number, status?: string, page = 1, pageSize = 20) => apiFetch>(`/v1/billing/invoices${subscriberId ? `?subscriber_id=${subscriberId}&` : "?"}${status ? `status=${status}&` : ""}page=${page}&pageSize=${pageSize}`), payments: (invoiceId?: number, status?: string, page = 1, pageSize = 20) => apiFetch>(`/v1/billing/payments${invoiceId ? `?invoice_id=${invoiceId}&` : "?"}${status ? `status=${status}&` : ""}page=${page}&pageSize=${pageSize}`), generateInvoice: (subscriberId: number, month: string, year: number) => apiFetch("/v1/billing/invoices", { method: "POST", body: JSON.stringify({ subscriber_id: subscriberId, month, year }) }), getInvoice: (id: number) => apiFetch(`/v1/billing/invoices/${id}`), }, // Configuration Management config: { get: (key?: string) => apiFetch(key ? `/v1/config?key=${key}` : "/v1/config"), update: (key: string, value: string, type = "string") => apiFetch("/v1/config", { method: "POST", body: JSON.stringify({ key, value, type }) }), validate: (config: Record) => apiFetch("/v1/config/validate", { method: "POST", body: JSON.stringify(config) }), delete: (key: string) => apiFetch(`/v1/config/${key}`, { method: "DELETE" }), }, // Chaos Engineering chaos: { experiments: (status?: string, page = 1, pageSize = 20) => apiFetch>(`/v1/chaos/experiments${status ? `?status=${status}&` : "?"}page=${page}&pageSize=${pageSize}`), run: (data: ChaosExperimentRequest) => apiFetch("/v1/chaos/experiments", { method: "POST", body: JSON.stringify(data) }), status: (experimentId: number) => apiFetch(`/v1/chaos/status?experiment_id=${experimentId}`), cancel: (experimentId: number) => apiFetch(`/v1/chaos/experiments/${experimentId}`, { method: "DELETE" }), }, };