import { NextResponse } from 'next/server'; import postgresClient from '@/lib/services/postgres-client'; export async function GET() { const results: Record = {}; // ── 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); }