/** * Server-side data resolver for the dashboard PDF report. * * Each section is gated on its widget id being present in * `config.widgetIds`, so a report that only includes the pipeline * funnel runs ONE query instead of the full dashboard panel. Keeps * cold-call latency low even when the actual port has hundreds of * berths. * * Lives in its own file (not inside dashboard.service.ts) so the * report-builder concerns — what widget ids map to what fetcher, * which fields the PDF shape requires — stay scoped to the * report-side surface, not the dashboard UI. */ import { getKpis, getPipelineCounts, getBerthStatusDistribution, getHotDeals, getSourceConversion, } from './dashboard.service'; import type { DashboardReportData } from '@/lib/pdf/reports/dashboard-report'; // Pure data/types now live in `dashboard-report-widgets.ts` so the // client-side export button can import them without dragging this // file's DB-touching imports into the browser bundle. Re-exported // here so existing consumers keep working. export { PDF_DASHBOARD_WIDGET_IDS, PDF_DASHBOARD_WIDGETS, type PdfDashboardWidgetId, type PdfDashboardWidgetOption, } from './dashboard-report-widgets'; export async function resolveDashboardReportData( portId: string, widgetIds: string[], ): Promise { const want = new Set(widgetIds); // Each fetcher returns its own shape; default to undefined to // signal "don't render this section" downstream. const data: DashboardReportData = {}; if (want.has('kpi_overview')) { data.kpis = await getKpis(portId); } if (want.has('pipeline_funnel')) { data.pipelineCounts = await getPipelineCounts(portId); } if (want.has('berth_status')) { const dist = await getBerthStatusDistribution(portId); // `dist` shape from the service is already the totals dict; pass // straight through. If the service changes shape, the type-check // here will trip. data.berthStatus = dist; } if (want.has('source_conversion')) { data.sourceConversion = await getSourceConversion(portId); } if (want.has('hot_deals')) { const deals = await getHotDeals(portId, 5); data.hotDeals = deals.map((d) => ({ id: d.id, clientName: d.clientName, mooringNumber: d.mooringNumber, stage: d.stage, lastContact: d.lastContact, })); } return data; }