From d3eeb4cab37c16bf74fc81af0cdd367320a87653 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 Feb 2026 21:50:23 -0500 Subject: [PATCH] fix: handle missing tables in dashboard stats API - Added tableExists helper to check if tables exist before querying - Gracefully handle missing auvik_tenants, rmm_sites, and quotes tables - Return partial data when some tables are missing --- app/api/dashboard/stats/route.ts | 106 +++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/app/api/dashboard/stats/route.ts b/app/api/dashboard/stats/route.ts index 5456d0d..0a66928 100644 --- a/app/api/dashboard/stats/route.ts +++ b/app/api/dashboard/stats/route.ts @@ -1,6 +1,18 @@ import { NextRequest, NextResponse } from 'next/server'; import { postgresClient } from '@/lib/services/postgres-client'; +async function tableExists(tableName: string): Promise { + try { + const result = await postgresClient.query( + "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1)", + [tableName] + ); + return result.rows[0]?.exists || false; + } catch { + return false; + } +} + export async function GET(request: NextRequest) { try { // Get companies count from database @@ -8,41 +20,71 @@ export async function GET(request: NextRequest) { 'SELECT COUNT(*) as total, COUNT(CASE WHEN is_active = true THEN 1 END) as active FROM companies WHERE company_type = 1' ); - // Get Auvik mapping stats from database - const auvikResult = await postgresClient.query( - 'SELECT COUNT(*) as mapped FROM auvik_tenant_mappings WHERE autotask_company_id IS NOT NULL' - ); + // Get Auvik mapping stats + let auvikMapped = 0; + try { + const auvikResult = await postgresClient.query( + 'SELECT COUNT(*) as mapped FROM auvik_tenant_mappings WHERE autotask_company_id IS NOT NULL' + ); + auvikMapped = parseInt(auvikResult.rows[0]?.mapped || '0'); + } catch { + // Table may not exist + } - // Get total Auvik tenants count - const auvikTotalResult = await postgresClient.query( - 'SELECT COUNT(*) as total FROM auvik_tenants' - ); + // Get total Auvik tenants count (check if table exists first) + let auvikTotal = auvikMapped; + if (await tableExists('auvik_tenants')) { + try { + const auvikTotalResult = await postgresClient.query( + 'SELECT COUNT(*) as total FROM auvik_tenants' + ); + auvikTotal = parseInt(auvikTotalResult.rows[0]?.total || '0'); + } catch { + // Ignore error + } + } - // Get RMM mapping stats from database - const rmmResult = await postgresClient.query( - 'SELECT COUNT(*) as mapped FROM rmm_site_mappings WHERE autotask_company_id IS NOT NULL' - ); + // Get RMM mapping stats + let rmmMapped = 0; + try { + const rmmResult = await postgresClient.query( + 'SELECT COUNT(*) as mapped FROM rmm_site_mappings WHERE autotask_company_id IS NOT NULL' + ); + rmmMapped = parseInt(rmmResult.rows[0]?.mapped || '0'); + } catch { + // Table may not exist + } - // Get total RMM sites count - const rmmTotalResult = await postgresClient.query( - 'SELECT COUNT(*) as total FROM rmm_sites' - ); + // Get total RMM sites count (check if table exists first) + let rmmTotal = rmmMapped; + if (await tableExists('rmm_sites')) { + try { + const rmmTotalResult = await postgresClient.query( + 'SELECT COUNT(*) as total FROM rmm_sites' + ); + rmmTotal = parseInt(rmmTotalResult.rows[0]?.total || '0'); + } catch { + // Ignore error + } + } // Get quotes count (if quotes table exists) let quotesOpen = 0; let quotesTotal = 0; - try { - const quotesResult = await postgresClient.query( - "SELECT COUNT(*) as open FROM quotes WHERE status = 'open'" - ); - quotesOpen = parseInt(quotesResult.rows[0]?.open || '0'); - - const quotesTotalResult = await postgresClient.query( - 'SELECT COUNT(*) as total FROM quotes' - ); - quotesTotal = parseInt(quotesTotalResult.rows[0]?.total || '0'); - } catch { - // Quotes table may not exist yet + if (await tableExists('quotes')) { + try { + const quotesResult = await postgresClient.query( + "SELECT COUNT(*) as open FROM quotes WHERE status = 'open'" + ); + quotesOpen = parseInt(quotesResult.rows[0]?.open || '0'); + + const quotesTotalResult = await postgresClient.query( + 'SELECT COUNT(*) as total FROM quotes' + ); + quotesTotal = parseInt(quotesTotalResult.rows[0]?.total || '0'); + } catch { + // Ignore error + } } const stats = { @@ -52,12 +94,12 @@ export async function GET(request: NextRequest) { }, mappings: { auvik: { - mapped: parseInt(auvikResult.rows[0]?.mapped || '0'), - unmapped: parseInt(auvikTotalResult.rows[0]?.total || '0') - parseInt(auvikResult.rows[0]?.mapped || '0'), + mapped: auvikMapped, + unmapped: Math.max(0, auvikTotal - auvikMapped), }, rmm: { - mapped: parseInt(rmmResult.rows[0]?.mapped || '0'), - unmapped: parseInt(rmmTotalResult.rows[0]?.total || '0') - parseInt(rmmResult.rows[0]?.mapped || '0'), + mapped: rmmMapped, + unmapped: Math.max(0, rmmTotal - rmmMapped), }, }, quotes: {