71 lines
4.3 KiB
Markdown
71 lines
4.3 KiB
Markdown
# 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
|
|
|
|
- [x] 1. Add `findRelatedActive` function and enrich the GET `/` handler in `backend/routes/ivantiArchive.js`
|
|
- [x] 1.1 Add the `findRelatedActive(archive, activeFindings)` helper function
|
|
- Add function above `createIvantiArchiveRouter` or inside the module scope
|
|
- Filter active findings where `hostName` exactly matches `archive.host_name`
|
|
- AND the archive's `finding_title` is a case-insensitive substring of the active finding's `title`, or vice versa
|
|
- AND the active finding's `id` is NOT equal to `archive.finding_id`
|
|
- If multiple matches, return the one with the highest `severity` as `{ id, title, severity }`
|
|
- If no matches, return `null`
|
|
- _Requirements: 3.1, 3.2, 3.3, 3.5_
|
|
|
|
- [x] 1.2 Modify the `GET /` handler to parse findings cache and enrich archive records
|
|
- After fetching archive rows, query `ivanti_findings_cache` (id=1) for `findings_json`
|
|
- Parse `findings_json` once with `JSON.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 as `related_active`
|
|
- Return the enriched archives array in the existing `{ archives, total }` response shape
|
|
- _Requirements: 3.1, 3.4, 6.1, 6.2_
|
|
|
|
- [x] 2. Checkpoint — Verify backend changes
|
|
- Ensure the backend starts without errors, ask the user if questions arise.
|
|
|
|
- [x] 3. Update archive card rendering in `frontend/src/App.js`
|
|
- [x] 3.1 Add `AlertTriangle` and `CheckCircle` to the lucide-react import
|
|
- Locate the existing lucide-react import statement in `App.js`
|
|
- Add `AlertTriangle` and `CheckCircle` if not already imported
|
|
- _Requirements: 5.1, 5.2_
|
|
|
|
- [x] 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_id` in monospace font, `0.6rem` size, muted color `#64748B`
|
|
- If `finding_id` length exceeds 20 characters, truncate displayed text to 20 chars + ellipsis
|
|
- Set the full `finding_id` as the `title` attribute for hover tooltip
|
|
- _Requirements: 1.1, 1.2, 1.3_
|
|
|
|
- [x] 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) ?? '—'}` with `Last seen: {a.last_severity?.toFixed(1) ?? '—'}`
|
|
- Null or zero severity displays as "Last seen: —"
|
|
- _Requirements: 2.1, 2.2, 2.3_
|
|
|
|
- [x] 3.4 Add conditional "Similar finding active" badge
|
|
- When `a.related_active` is 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.6rem` size
|
|
- When `a.related_active` is null, render nothing
|
|
- _Requirements: 4.1, 4.2, 4.3_
|
|
|
|
- [x] 3.5 Add icon and left border color based on `related_active`
|
|
- When `a.related_active` is non-null: render `AlertTriangle` icon and set left border to `3px solid #F59E0B` (amber)
|
|
- When `a.related_active` is null: render `CheckCircle` icon and set left border to `3px 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_
|
|
|
|
- [x] 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 `findRelatedActive` function parses the findings cache once per request for performance (Requirement 6.2)
|
|
- Each task references specific requirements for traceability
|