Add aggregated burndown forecast to CCP Metrics overview page
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user