4.3 KiB
Implementation Plan: Archive Finding Clarity
Overview
Enhance the Ivanti Archive Findings panel to display finding IDs, label severity as historical, detect related active findings server-side, and apply visual icon/border distinctions based on resolution status. Changes span backend/routes/ivantiArchive.js (matching logic + enriched response) and frontend/src/App.js (card rendering updates). No new components, endpoints, or migrations.
Tasks
-
1. Add
findRelatedActivefunction and enrich the GET/handler inbackend/routes/ivantiArchive.js-
1.1 Add the
findRelatedActive(archive, activeFindings)helper function- Add function above
createIvantiArchiveRouteror inside the module scope - Filter active findings where
hostNameexactly matchesarchive.host_name - AND the archive's
finding_titleis a case-insensitive substring of the active finding'stitle, or vice versa - AND the active finding's
idis NOT equal toarchive.finding_id - If multiple matches, return the one with the highest
severityas{ id, title, severity } - If no matches, return
null - Requirements: 3.1, 3.2, 3.3, 3.5
- Add function above
-
1.2 Modify the
GET /handler to parse findings cache and enrich archive records- After fetching archive rows, query
ivanti_findings_cache(id=1) forfindings_json - Parse
findings_jsononce withJSON.parse; default to empty array if NULL, missing row, or parse error - Log a warning on parse failure, do not throw
- For each archive record, call
findRelatedActive(archive, parsedFindings)and attach the result asrelated_active - Return the enriched archives array in the existing
{ archives, total }response shape - Requirements: 3.1, 3.4, 6.1, 6.2
- After fetching archive rows, query
-
-
2. Checkpoint — Verify backend changes
- Ensure the backend starts without errors, ask the user if questions arise.
-
3. Update archive card rendering in
frontend/src/App.js-
3.1 Add
AlertTriangleandCheckCircleto the lucide-react import- Locate the existing lucide-react import statement in
App.js - Add
AlertTriangleandCheckCircleif not already imported - Requirements: 5.1, 5.2
- Locate the existing lucide-react import statement in
-
3.2 Add Finding ID display below the finding title
- Inside the
archiveList.map()block, add a new line below the title<span> - Render
a.finding_idin monospace font,0.6remsize, muted color#64748B - If
finding_idlength exceeds 20 characters, truncate displayed text to 20 chars + ellipsis - Set the full
finding_idas thetitleattribute for hover tooltip - Requirements: 1.1, 1.2, 1.3
- Inside the
-
3.3 Change severity badge to "Last seen: X.X" format
- In the severity
<span>within the archive card, replace{a.last_severity?.toFixed(1) ?? '—'}withLast seen: {a.last_severity?.toFixed(1) ?? '—'} - Null or zero severity displays as "Last seen: —"
- Requirements: 2.1, 2.2, 2.3
- In the severity
-
3.4 Add conditional "Similar finding active" badge
- When
a.related_activeis non-null, render a badge below the host info line - Badge text: "Similar finding active" with the related finding's ID and severity
- Style with accent color
#0EA5E9, monospace font,0.6remsize - When
a.related_activeis null, render nothing - Requirements: 4.1, 4.2, 4.3
- When
-
3.5 Add icon and left border color based on
related_active- When
a.related_activeis non-null: renderAlertTriangleicon and set left border to3px solid #F59E0B(amber) - When
a.related_activeis null: renderCheckCircleicon and set left border to3px solid #10B981(green) - Place the icon at the left side of the card header row, before the title
- Apply consistently regardless of archive lifecycle state (ARCHIVED, RETURNED, CLOSED)
- Requirements: 5.1, 5.2, 5.3
- When
-
-
4. Final checkpoint — Verify full feature
- Ensure the frontend compiles without errors, ask the user if questions arise.
Notes
- No automated tests — feature is validated manually on the dev server per user preference
- No new components, endpoints, or database migrations required
- The
findRelatedActivefunction parses the findings cache once per request for performance (Requirement 6.2) - Each task references specific requirements for traceability