import { NextResponse } from 'next/server'; import postgresClient from '@/lib/services/postgres-client'; export async function GET() { try { // Get compliance summary const summaryResult = await postgresClient.query(` SELECT mismatch_type, COUNT(*) as count FROM veeam_compliance_results GROUP BY mismatch_type `); let contractedNotBackedUp = 0; let backedUpNotContracted = 0; for (const row of summaryResult.rows) { if (row.mismatch_type === 'contracted_not_backed_up') { contractedNotBackedUp = parseInt(row.count); } else if (row.mismatch_type === 'backed_up_not_contracted') { backedUpNotContracted = parseInt(row.count); } } // Get total contracted devices (config items with backup UDF + company has active contract) const contractedResult = await postgresClient.query(` SELECT COUNT(DISTINCT ci.id) as count FROM configuration_items ci JOIN contracts ct ON ct.company_id = ci.company_id AND ct.status = 1 WHERE ci.backup_type_udf IS NOT NULL AND ci.backup_type_udf != '' AND ci.is_active = true AND ci.is_deleted = false `); const totalContracted = parseInt(contractedResult.rows[0]?.count || '0'); const matched = totalContracted - contractedNotBackedUp; // Get last computed time const lastComputed = await postgresClient.query( 'SELECT MAX(computed_at) as computed_at FROM veeam_compliance_results' ); // Get mismatch details with active contract service coverage. // "Covered" = company has an active contract with a ContractService line // matching workstation backup (service_name ILIKE '%workstation%backup%' or '%w/ backup%'). // Falls back to billing_items if contract_services not yet populated. const mismatches = await postgresClient.query(` WITH cs_backup AS ( SELECT DISTINCT ON (ct.company_id) ct.company_id, ct.id AS contract_id, ct.contract_name, cs.quantity AS contracted_qty FROM contract_services cs JOIN contracts ct ON ct.id = cs.contract_id WHERE cs.is_deleted = false AND ct.is_deleted = false AND ct.status = 1 AND ( cs.service_name ILIKE '%workstation%backup%' OR cs.service_name ILIKE '%w/ backup%' OR cs.description ILIKE '%workstation%backup%' OR cs.description ILIKE '%w/ backup%' OR cs.service_name ILIKE '%windows server%' OR cs.service_name ILIKE '%server virtual%' OR cs.service_name ILIKE '%server physical%' OR cs.service_name ILIKE '%server phys%' OR cs.service_name ILIKE '%esxi host%' OR cs.service_name ILIKE '%wulf 365 it complete endpoint%' OR cs.service_name ILIKE '%wulf 365 it complete server%' OR cs.service_name ILIKE '%wulf it complete (server)%' OR cs.service_name ILIKE '%wulf it complete (endpoint)%' ) ORDER BY ct.company_id, CASE WHEN ct.contract_name ILIKE '%backup%' THEN 0 WHEN ct.contract_name ILIKE '%managed it%' THEN 1 WHEN ct.contract_name ILIKE '%fixed price%' THEN 2 ELSE 3 END ), bi_backup AS ( SELECT DISTINCT ON (bi.company_id) bi.company_id, ct.id AS contract_id, ct.contract_name, bi.quantity AS contracted_qty FROM billing_items bi LEFT JOIN LATERAL ( SELECT id, contract_name FROM contracts WHERE company_id = bi.company_id AND is_deleted = false AND status = 1 ORDER BY CASE WHEN contract_name ILIKE '%backup%' THEN 0 WHEN contract_name ILIKE '%managed it%' THEN 1 WHEN contract_name ILIKE '%fixed price%' THEN 2 ELSE 3 END LIMIT 1 ) ct ON true WHERE bi.is_deleted = false AND bi.description ILIKE '%windows workstation w/ backup%' AND bi.synced_at::date = ( SELECT MAX(synced_at::date) FROM billing_items WHERE is_deleted = false ) ORDER BY bi.company_id, bi.quantity DESC ), coverage AS ( SELECT company_id, contract_id, contract_name, contracted_qty, 'contract_services' AS source FROM cs_backup UNION ALL SELECT b.company_id, b.contract_id, b.contract_name, b.contracted_qty, 'billing_items' AS source FROM bi_backup b WHERE NOT EXISTS (SELECT 1 FROM cs_backup cs WHERE cs.company_id = b.company_id) ) SELECT cr.*, c.company_name, cov.contract_name AS billing_contract_name, cov.contract_id AS billing_contract_id, (cov.company_id IS NOT NULL) AS billing_covered, cov.contracted_qty::int AS billing_contracted_qty, cov.source AS coverage_source FROM veeam_compliance_results cr LEFT JOIN companies c ON c.id = cr.company_id LEFT JOIN coverage cov ON cov.company_id = cr.company_id ORDER BY cr.mismatch_type, c.company_name, cr.device_name `); return NextResponse.json({ summary: { totalContractedDevices: totalContracted, matchedDevices: Math.max(0, matched), contractedNotBackedUp, backedUpNotContracted, computedAt: lastComputed.rows[0]?.computed_at || null, }, mismatches: mismatches.rows, }); } catch (error) { console.error('[VEEAM-API] compliance error:', error); return NextResponse.json({ summary: { totalContractedDevices: 0, matchedDevices: 0, contractedNotBackedUp: 0, backedUpNotContracted: 0, computedAt: null, }, mismatches: [], }); } }