wulf-pulse/app/api/integrations/status/route.ts

114 lines
5.4 KiB
TypeScript

import { NextResponse } from 'next/server';
import postgresClient from '@/lib/services/postgres-client';
export async function GET() {
const results: Record<string, any> = {};
// ── Veeam VSPC ──────────────────────────────────────────────────────────────
try {
const [orgs, agentJobs, backupJobs, workloads] = await Promise.all([
postgresClient.query('SELECT COUNT(*) as count, MAX(synced_at) as last_sync FROM veeam_organizations'),
postgresClient.query(`SELECT COUNT(*) as total,
COUNT(*) FILTER (WHERE status='Success') as success,
COUNT(*) FILTER (WHERE status='Running') as running,
COUNT(*) FILTER (WHERE status='Failed') as failed,
COUNT(*) FILTER (WHERE status='Warning') as warning
FROM veeam_backup_agent_jobs WHERE is_enabled = true`),
postgresClient.query(`SELECT COUNT(*) as total,
COUNT(*) FILTER (WHERE status='Success') as success,
COUNT(*) FILTER (WHERE status='Failed') as failed,
COUNT(*) FILTER (WHERE status='Warning') as warning
FROM veeam_backup_jobs WHERE is_enabled = true`),
postgresClient.query('SELECT COUNT(*) as count FROM veeam_protected_workloads'),
]);
results.veeam = {
configured: !!(process.env.VEEAM_VSPC_URL && process.env.VEEAM_VSPC_API_KEY),
organizations: parseInt(orgs.rows[0].count),
lastSync: orgs.rows[0].last_sync,
agentJobs: {
total: parseInt(agentJobs.rows[0].total),
success: parseInt(agentJobs.rows[0].success),
running: parseInt(agentJobs.rows[0].running),
failed: parseInt(agentJobs.rows[0].failed),
warning: parseInt(agentJobs.rows[0].warning),
},
backupJobs: {
total: parseInt(backupJobs.rows[0].total),
success: parseInt(backupJobs.rows[0].success),
failed: parseInt(backupJobs.rows[0].failed),
warning: parseInt(backupJobs.rows[0].warning),
},
protectedWorkloads: parseInt(workloads.rows[0].count),
};
} catch (e) {
results.veeam = { configured: false, error: String(e) };
}
// ── Datto RMM ───────────────────────────────────────────────────────────────
try {
const [sites, devices, openAlerts, lastSync] = await Promise.all([
postgresClient.query(`SELECT COUNT(*) as total,
COALESCE(SUM(number_of_devices),0) as total_devices,
COALESCE(SUM(number_of_online_devices),0) as online_devices,
COALESCE(SUM(number_of_offline_devices),0) as offline_devices
FROM datto_rmm_sites`),
postgresClient.query(`SELECT COUNT(*) as total,
COUNT(*) FILTER (WHERE online = true) as online,
COUNT(*) FILTER (WHERE online = false AND deleted = false) as offline
FROM datto_rmm_devices WHERE deleted = false`),
postgresClient.query(`SELECT COUNT(*) as total,
COUNT(*) FILTER (WHERE priority = 'Critical') as critical,
COUNT(*) FILTER (WHERE priority = 'High') as high,
COUNT(*) FILTER (WHERE priority = 'Moderate') as moderate,
COUNT(*) FILTER (WHERE priority = 'Low') as low,
COUNT(*) FILTER (WHERE ticket_number IS NOT NULL) as with_ticket
FROM datto_rmm_alerts WHERE resolved = false`),
postgresClient.query(`SELECT MAX(synced_at) as last_sync FROM datto_rmm_sites`),
]);
results.dattoRmm = {
configured: !!(process.env.DATTO_RMM_API_KEY && process.env.DATTO_RMM_API_SECRET),
apiUrl: process.env.DATTO_RMM_API_URL || 'https://concord-api.centrastage.net',
lastSync: lastSync.rows[0].last_sync,
sites: parseInt(sites.rows[0].total),
devices: {
total: parseInt(devices.rows[0].total),
online: parseInt(devices.rows[0].online),
offline: parseInt(devices.rows[0].offline),
},
openAlerts: {
total: parseInt(openAlerts.rows[0].total),
critical: parseInt(openAlerts.rows[0].critical),
high: parseInt(openAlerts.rows[0].high),
moderate: parseInt(openAlerts.rows[0].moderate),
low: parseInt(openAlerts.rows[0].low),
withTicket: parseInt(openAlerts.rows[0].with_ticket),
},
};
} catch (e) {
results.dattoRmm = { configured: !!(process.env.DATTO_RMM_API_KEY && process.env.DATTO_RMM_API_SECRET), error: String(e) };
}
// ── Auvik ───────────────────────────────────────────────────────────────────
try {
results.auvik = {
configured: !!(process.env.AUVIK_API_KEY && process.env.AUVIK_API_USER),
apiUrl: process.env.AUVIK_API_URL || 'https://auvikapi.us5.my.auvik.com',
lastSync: null,
};
} catch (e) {
results.auvik = { configured: false, error: String(e) };
}
// ── Addigy ──────────────────────────────────────────────────────────────────
try {
results.addigy = {
configured: !!(process.env.ADDIGY_API_TOKEN),
apiUrl: process.env.ADDIGY_API_URL || 'https://api.addigy.com/api/v2',
lastSync: null,
};
} catch (e) {
results.addigy = { configured: false, error: String(e) };
}
return NextResponse.json(results);
}