// Server stats / health helpers. // Wraps /api/v1/admin/monitoring/* + /api/v1/platform/* + a few observability // endpoints used by the monitoring dashboard. import type { ArcadiaClient } from "@crema/arcadia-client" // --- Rate limits --------------------------------------------------------- export interface RateLimit { type: string max_requests: number window_seconds: number } export async function getRateLimits(arcadia: ArcadiaClient): Promise { const res = await arcadia.GET<{ data: { limits: RateLimit[] } }>( "/api/v1/admin/monitoring/rate-limits", ) return res.data.limits ?? [] } // --- Active sessions ---------------------------------------------------- export interface ActiveSession { user_id: string email: string first_name: string | null last_name: string | null status: string user_type: string | null last_sign_in_at: string tenant_id: string two_factor_enabled: boolean } export async function getActiveSessions( arcadia: ArcadiaClient, ): Promise<{ sessions: ActiveSession[]; count: number }> { const res = await arcadia.GET<{ data: { sessions: ActiveSession[]; count: number } }>( "/api/v1/admin/monitoring/sessions", ) return res.data } // --- Background jobs (Oban) --------------------------------------------- export type JobState = | "available" | "executing" | "scheduled" | "retryable" | "discarded" | "cancelled" | "completed" export interface JobStats { counts: Record by_queue: Record>> queues: string[] } export interface ObanJob { id: number queue: string state: JobState worker: string attempt: number max_attempts: number inserted_at: string attempted_at: string | null completed_at: string | null scheduled_at: string | null errors: Array<{ at?: string; attempt?: number; error?: string }> | null } export async function getJobStats(arcadia: ArcadiaClient): Promise { const res = await arcadia.GET<{ data: JobStats }>( "/api/v1/admin/monitoring/jobs/stats", ) return res.data } export async function getRecentJobs( arcadia: ArcadiaClient, params?: { limit?: number; state?: JobState; queue?: string }, ): Promise { const res = await arcadia.GET<{ data: { jobs: ObanJob[]; count: number } }>( "/api/v1/admin/monitoring/jobs", { params: params as Record }, ) return res.data.jobs ?? [] } export async function retryJob(arcadia: ArcadiaClient, id: number): Promise { await arcadia.POST(`/api/v1/admin/monitoring/jobs/${id}/retry`) } // --- Platform infrastructure (DigitalOcean) ----------------------------- /** Provider returns whatever it returns; admin UI surfaces it loosely. */ export type InfrastructureSummary = Record export type Space = Record export async function getInfrastructureSummary( arcadia: ArcadiaClient, ): Promise { try { const res = await arcadia.GET<{ data: InfrastructureSummary }>( "/api/v1/platform/infrastructure/summary", ) return res.data } catch { return null } } export async function getSpaces(arcadia: ArcadiaClient): Promise { try { const res = await arcadia.GET<{ data: Space[] }>( "/api/v1/platform/infrastructure/spaces", ) return res.data ?? [] } catch { return [] } } // --- Droplets ------------------------------------------------------------ export interface Droplet { id: number | string name: string status: string region?: { slug?: string; name?: string } | string size_slug?: string vcpus?: number memory?: number disk?: number created_at?: string networks?: unknown /** Provider-specific fields surface verbatim. */ [key: string]: unknown } export interface DropletMetrics { cpu?: Array<{ time: string; value: number }> memory?: Array<{ time: string; value: number }> disk?: Array<{ time: string; value: number }> bandwidth?: Array<{ time: string; value: number }> [key: string]: unknown } export async function listDroplets(arcadia: ArcadiaClient): Promise { try { const res = await arcadia.GET<{ droplets?: Droplet[]; data?: Droplet[] }>( "/api/v1/platform/droplets", ) return res.droplets ?? res.data ?? [] } catch { return [] } } export async function getDropletMetrics( arcadia: ArcadiaClient, id: number | string, ): Promise { try { const res = await arcadia.GET<{ data: DropletMetrics }>( `/api/v1/platform/droplets/${id}/metrics`, ) return res.data } catch { return null } } // --- Audit stats (already used by /activity, exposed here for the dashboard) --- export interface AuditStats { total: number by_action?: Record by_severity?: Record by_resource_type?: Record /** When backend supports it: { period: ISO, total: number }[] */ over_time?: Array<{ period: string; total: number }> [key: string]: unknown } export async function getAuditStats( arcadia: ArcadiaClient, params?: { from?: string; to?: string }, ): Promise { const res = await arcadia.GET<{ data: AuditStats }>( "/api/v1/observability/audit_stats", { params: params as Record }, ) return res.data }