Fix forecast deduplication for multi-vertical metrics

Devices appearing in multiple verticals were counted multiple times,
causing non_compliant > totalAssets and negative compliance percentages.
Deduplicate by hostname before passing to the forecast helper.
This commit is contained in:
Jordan Ramos
2026-05-20 17:53:29 -06:00
parent e45deccdb7
commit ae2b7e0433

View File

@@ -1673,11 +1673,19 @@ function createVCLMultiVerticalRouter(upload) {
compliance_pct: currentMonthCompliancePct, compliance_pct: currentMonthCompliancePct,
}); });
// 8. Prepare currentDevices for the helper (only need hostname and resolution_date) // 8. Prepare currentDevices for the helper — deduplicate by hostname
const currentDevices = activeDevices.map(d => ({ // A device may appear in multiple verticals; count it once, keeping the
hostname: d.hostname, // earliest resolution_date (or null if any row has no date)
resolution_date: d.resolution_date || null, const deviceMap = {};
})); for (const d of activeDevices) {
if (!deviceMap[d.hostname]) {
deviceMap[d.hostname] = { hostname: d.hostname, resolution_date: d.resolution_date || null };
} else if (d.resolution_date && !deviceMap[d.hostname].resolution_date) {
// If any row has a resolution_date and current doesn't, use it
deviceMap[d.hostname].resolution_date = d.resolution_date;
}
}
const currentDevices = Object.values(deviceMap);
// 9. Pass data to computeMetricForecastBurndown helper // 9. Pass data to computeMetricForecastBurndown helper
const result = computeMetricForecastBurndown(currentDevices, totalAssets, historicalSnapshots); const result = computeMetricForecastBurndown(currentDevices, totalAssets, historicalSnapshots);