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
This commit is contained in:
root 2026-02-02 21:50:23 -05:00
parent db4d431d26
commit d3eeb4cab3

View file

@ -1,6 +1,18 @@
import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';
async function tableExists(tableName: string): Promise<boolean> {
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: {