feat(postgres): rewrite Ivanti findings to individual rows

- Replace 2.6MB JSON blob with individual rows in ivanti_findings table
- Batch upsert via INSERT ... ON CONFLICT in chunks of 100
- Sync stores both open AND closed findings as rows with state column
- Per-BU closed counts now possible via SQL GROUP BY
- GET /findings queries indexed table with optional ILIKE BU filter
- GET /counts returns per-BU open+closed via GROUP BY state
- Notes and overrides are columns on ivanti_findings (no separate tables)
- Removed: readState, readStateWithNotes, _findingsCache, initTables
- Preserved: extractFinding, archive detection, FP workflow counts, anomaly log
- Response shape unchanged — frontend works without modification
This commit is contained in:
Jordan Ramos
2026-05-06 12:12:34 -06:00
parent 33927b150b
commit e30ad79f2a
2 changed files with 839 additions and 905 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -193,7 +193,7 @@ app.use('/api/archer-tickets', createArcherTicketsRouter());
app.use('/api/ivanti/workflows', createIvantiWorkflowsRouter());
// Ivanti / RiskSense host findings routes (all authenticated users)
// NOTE: Still passes pool as db until task 8 migrates this route
// Pool imported directly inside the module; first arg kept for signature compat
app.use('/api/ivanti/findings', createIvantiFindingsRouter(pool, requireAuth));
// Ivanti queue routes — per-user staging queue for FP / Archer workflows