Fix forecast burndown chart data issues

- Fix Date object handling for resolution_date from PostgreSQL
- Fix totalAssets using per-metric summary (vcl_multi_vertical_summary)
  instead of vertical-level compliance_snapshots total_devices
- Fix duplicate current month in chart (forecast starts from next month)
- Fix multi-vertical metrics summing across all relevant verticals
- Fix bar stacking: orange (non-compliant) on bottom, blue (compliant)
  on top, both sharing same baseline (stacked to total)
- Add fill props to Bar components for correct legend colors
- Backfill historical snapshots with per-metric totalAssets
This commit is contained in:
Jordan Ramos
2026-05-20 17:28:20 -06:00
parent f9770872ba
commit e45deccdb7
3 changed files with 79 additions and 41 deletions

View File

@@ -476,7 +476,11 @@ function computeMetricForecastBurndown(currentDevices, totalAssets, historicalSn
const buckets = {};
for (const device of currentDevices) {
if (device.resolution_date == null) continue;
const resMonth = device.resolution_date.slice(0, 7); // YYYY-MM
// Handle both Date objects (from PostgreSQL) and YYYY-MM-DD strings
const dateStr = device.resolution_date instanceof Date
? device.resolution_date.toISOString().slice(0, 7)
: String(device.resolution_date).slice(0, 7);
const resMonth = dateStr; // YYYY-MM
if (resMonth < currentMonthStr) {
// Past-due: treat as remediated in current month
buckets[currentMonthStr] = (buckets[currentMonthStr] || 0) + 1;
@@ -485,11 +489,16 @@ function computeMetricForecastBurndown(currentDevices, totalAssets, historicalSn
}
}
// Generate forecast months starting from current month, up to 12 months max
// Generate forecast months starting from NEXT month, up to 12 months max
const forecast = [];
let remainingNonCompliant = nonCompliant;
for (let i = 0; i < 12; i++) {
// Account for devices remediated in the current month (past-due dates bucketed here)
if (buckets[currentMonthStr]) {
remainingNonCompliant -= buckets[currentMonthStr];
}
for (let i = 1; i <= 12; i++) {
const forecastYear = currentYear + Math.floor((currentMonth + i) / 12);
const forecastMonth = (currentMonth + i) % 12;
const monthStr = formatMonth(forecastYear, forecastMonth);