fix: scope FP workflow counts donut by BU
- Rewrite /fp-workflow-counts endpoint to query ivanti_findings table directly with optional teams ILIKE filter (replaces pre-computed JSON blob) - Frontend passes getActiveTeamsParam() to FP counts fetch - FP counts refresh on scope toggle change alongside open/closed counts - Both FP Finding Status and FP Workflow Status donuts now respect BU scope
This commit is contained in:
@@ -1222,18 +1222,56 @@ function createIvantiFindingsRouter(db, requireAuth) {
|
||||
*
|
||||
* Return FP finding counts and unique workflow ID counts (open + closed),
|
||||
* broken down by workflow status.
|
||||
* Accepts optional `teams` query parameter to scope to specific BUs.
|
||||
*
|
||||
* @query {string} [teams] - Comma-separated team names (e.g. 'STEAM,ACCESS-ENG')
|
||||
* @returns {Object} 200 - { findingCounts: Object, findingTotal: number, idCounts: Object, idTotal: number }
|
||||
* @returns {Object} 500 - { error: string } on database error
|
||||
*/
|
||||
router.get('/fp-workflow-counts', async (req, res) => {
|
||||
try {
|
||||
const { rows } = await pool.query('SELECT fp_workflow_counts_json, fp_id_counts_json FROM ivanti_counts_cache WHERE id=1');
|
||||
const row = rows[0];
|
||||
let findingCounts = {};
|
||||
let idCounts = {};
|
||||
try { findingCounts = JSON.parse(row?.fp_workflow_counts_json || '{}'); } catch (_) {}
|
||||
try { idCounts = JSON.parse(row?.fp_id_counts_json || '{}'); } catch (_) {}
|
||||
const teamsParam = req.query.teams;
|
||||
let whereExtra = '';
|
||||
const params = [];
|
||||
let paramIndex = 1;
|
||||
|
||||
if (teamsParam) {
|
||||
const teams = teamsParam.split(',').map(t => t.trim()).filter(Boolean);
|
||||
if (teams.length > 0) {
|
||||
const patterns = teams.map(t => `%${t}%`);
|
||||
whereExtra = ` AND bu_ownership ILIKE ANY($${paramIndex++}::text[])`;
|
||||
params.push(patterns);
|
||||
}
|
||||
}
|
||||
|
||||
// Finding counts: number of findings per workflow state
|
||||
const findingResult = await pool.query(
|
||||
`SELECT workflow_state, COUNT(*) as count
|
||||
FROM ivanti_findings
|
||||
WHERE workflow_id IS NOT NULL ${whereExtra}
|
||||
GROUP BY workflow_state`,
|
||||
params
|
||||
);
|
||||
const findingCounts = {};
|
||||
findingResult.rows.forEach(r => {
|
||||
const state = r.workflow_state || 'Unknown';
|
||||
findingCounts[state] = parseInt(r.count);
|
||||
});
|
||||
|
||||
// ID counts: number of unique workflow IDs per state
|
||||
const idResult = await pool.query(
|
||||
`SELECT workflow_state, COUNT(DISTINCT workflow_id) as count
|
||||
FROM ivanti_findings
|
||||
WHERE workflow_id IS NOT NULL ${whereExtra}
|
||||
GROUP BY workflow_state`,
|
||||
params
|
||||
);
|
||||
const idCounts = {};
|
||||
idResult.rows.forEach(r => {
|
||||
const state = r.workflow_state || 'Unknown';
|
||||
idCounts[state] = parseInt(r.count);
|
||||
});
|
||||
|
||||
res.json({
|
||||
findingCounts,
|
||||
findingTotal: Object.values(findingCounts).reduce((a, b) => a + b, 0),
|
||||
|
||||
Reference in New Issue
Block a user