import { rbacApi } from "@/main-axios"; export interface NotificationChannel { id: number; userId: string; name: string; type: "webhook" | "ntfy"; config: string; enabled: boolean; createdAt: string; } export interface AlertRule { id: number; userId: string; hostId: number | null; name: string; enabled: boolean; triggerType: string; thresholdValue: number | null; thresholdDurationSeconds: number | null; cooldownMinutes: number; createdAt: string; updatedAt: string; channelIds: number[]; } export interface AlertFiring { id: number; userId: string; ruleId: number; hostId: number; hostName: string; firedAt: string; resolvedAt: string | null; value: number | null; message: string; severity: "info" | "warning" | "critical"; acknowledged: boolean; ruleName?: string; } function stringValue(value: unknown, fallback = ""): string { return typeof value === "string" ? value : fallback; } function numberValue(value: unknown, fallback = 0): number { return typeof value === "number" && Number.isFinite(value) ? value : fallback; } function nullableNumberValue(value: unknown): number | null { return typeof value === "number" && Number.isFinite(value) ? value : null; } function boolValue(value: unknown): boolean { return value === true || value === 1 || value === "1"; } function severityValue(value: unknown): AlertFiring["severity"] { return value === "info" || value === "critical" || value === "warning" ? value : "warning"; } export async function getNotificationChannels(): Promise< NotificationChannel[] > { const res = await rbacApi.get("/notification-channels"); return res.data; } export async function createNotificationChannel( data: Partial, ): Promise { const res = await rbacApi.post("/notification-channels", data); return res.data; } export async function updateNotificationChannel( id: number, data: Partial, ): Promise { const res = await rbacApi.put(`/notification-channels/${id}`, data); return res.data; } export async function deleteNotificationChannel(id: number): Promise { await rbacApi.delete(`/notification-channels/${id}`); } export async function testNotificationChannel(id: number): Promise { await rbacApi.post(`/notification-channels/${id}/test`); } function mapRule(r: Record): AlertRule { return { id: r.id as number, userId: (r.user_id ?? r.userId) as string, hostId: (r.host_id ?? r.hostId ?? null) as number | null, name: r.name as string, enabled: Boolean(r.enabled), triggerType: (r.trigger_type ?? r.triggerType) as string, thresholdValue: (r.threshold_value ?? r.thresholdValue ?? null) as | number | null, thresholdDurationSeconds: (r.threshold_duration_seconds ?? r.thresholdDurationSeconds ?? null) as number | null, cooldownMinutes: (r.cooldown_minutes ?? r.cooldownMinutes) as number, createdAt: (r.created_at ?? r.createdAt) as string, updatedAt: (r.updated_at ?? r.updatedAt) as string, channelIds: Array.isArray(r.channels) ? (r.channels as number[]) : [], }; } export function mapAlertFiring(r: Record): AlertFiring { return { id: numberValue(r.id), userId: stringValue(r.userId ?? r.user_id), ruleId: numberValue(r.ruleId ?? r.rule_id), hostId: numberValue(r.hostId ?? r.host_id), hostName: stringValue(r.hostName ?? r.host_name), firedAt: stringValue(r.firedAt ?? r.fired_at, new Date(0).toISOString()), resolvedAt: stringValue(r.resolvedAt ?? r.resolved_at) || null, value: nullableNumberValue(r.value), message: stringValue(r.message), severity: severityValue(r.severity), acknowledged: boolValue(r.acknowledged), ruleName: stringValue(r.ruleName ?? r.rule_name) || undefined, }; } export async function getAlertRules(): Promise { const res = await rbacApi.get("/alert-rules"); return (res.data as Record[]).map(mapRule); } export async function createAlertRule( data: Partial & { channels?: number[] }, ): Promise { const res = await rbacApi.post("/alert-rules", data); return mapRule(res.data as Record); } export async function updateAlertRule( id: number, data: Partial & { channels?: number[] }, ): Promise { const res = await rbacApi.put(`/alert-rules/${id}`, data); return mapRule(res.data as Record); } export async function deleteAlertRule(id: number): Promise { await rbacApi.delete(`/alert-rules/${id}`); } export async function getAlertFirings(opts?: { limit?: number; offset?: number; acknowledged?: boolean; }): Promise { const res = await rbacApi.get("/alert-firings", { params: opts }); const data = res.data as { firings?: unknown } | unknown[]; const rows = Array.isArray(data) ? data : Array.isArray(data.firings) ? data.firings : []; return rows.map((row) => mapAlertFiring(row as Record)); } export async function acknowledgeAlertFiring(id: number): Promise { await rbacApi.post(`/alert-firings/${id}/acknowledge`); } export async function acknowledgeAllAlertFirings(): Promise { await rbacApi.post("/alert-firings/acknowledge-all"); }