Add aggregated burndown forecast to CCP Metrics overview page

This commit is contained in:
Jordan Ramos
2026-05-15 17:08:55 -06:00
parent 4d255209fd
commit 492780fd90
5 changed files with 979 additions and 2 deletions

View File

@@ -7,7 +7,7 @@ const fs = require('fs');
const { spawn } = require('child_process');
const pool = require('../db');
const { requireAuth, requireGroup } = require('../middleware/auth');
const { parseVerticalFilename, computeVerticalBurndown, isValidDateString, categorizeNonCompliant } = require('../helpers/vclHelpers');
const { parseVerticalFilename, computeVerticalBurndown, isValidDateString, categorizeNonCompliant, deduplicateByHostname, computeAggregatedBurndown } = require('../helpers/vclHelpers');
const logAudit = require('../helpers/auditLog');
const PARSER_SCRIPT = path.join(__dirname, '../scripts/parse_compliance_xlsx.py');
@@ -1240,6 +1240,54 @@ function createVCLMultiVerticalRouter(upload) {
}
});
// -----------------------------------------------------------------------
// GET /burndown — Aggregated cross-vertical burndown forecast
// -----------------------------------------------------------------------
/**
* GET /burndown
* Returns aggregated burndown forecast across all verticals.
* Deduplicates devices by hostname (earliest non-null resolution_date).
*
* @method GET
* @route /burndown
*
* @response 200
* {
* total_non_compliant: number,
* blockers: number,
* with_dates: number,
* monthly_forecast: Object<string, number>,
* projected_clear_date: string|null,
* by_vertical: Array<{ vertical: string, total: number, blockers: number, with_dates: number }>
* }
* @response 500 { error: string }
*/
router.get('/burndown', async (req, res) => {
try {
const { rows } = await pool.query(
`SELECT hostname, resolution_date, vertical
FROM compliance_items
WHERE vertical IS NOT NULL AND status = 'active'`
);
const devices = deduplicateByHostname(rows);
const burndown = computeAggregatedBurndown(devices);
res.json({
total_non_compliant: burndown.total,
blockers: burndown.blockers,
with_dates: burndown.with_dates,
monthly_forecast: burndown.monthly,
projected_clear_date: burndown.projected_clear_date,
by_vertical: burndown.by_vertical,
});
} catch (err) {
console.error('[VCL Multi] GET /burndown error:', err.message);
res.status(500).json({ error: 'Database error' });
}
});
return router;
}