Files
cve-dashboard/.kiro/specs/compliance-list-stale-after-sidebar-edit/bugfix.md
Jordan Ramos a61d254ff9 Sync .kiro/ from master — v2.2.0 release batch
New specs: archer-template-library, ccp-metrics-view-restructure,
compliance-list-stale-after-sidebar-edit, compliance-metric-estimated-resolution-date,
compliance-remediation-display-fix, flexible-jira-ticket-creation,
forecast-burndown-chart, granite-loader-export, ivanti-queue-clear-completed-fix,
multi-item-jira-ticket, queue-collapsible-sections, vendor-issue-type-dropdown

New steering: archer-template-gen.md

Updated: migration-registration-check hook, remediation-plan-history spec,
gitlab-workflow, tech, versioning steering files
2026-06-04 11:27:31 -06:00

45 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Bugfix Requirements Document
## Introduction
GitLab issue [#23](http://steam-gitlab.charterlab.com/steam/cve-dashboard/-/issues/23) — "[Bug] Update Res Date/Remed Plan in list after updating in sidebar" (reported by nkapur on the AEO Compliance page).
After a user sets a resolution date and/or remediation plan in the host detail sidebar (`ComplianceDetailPanel`) and closes it, the new value does not appear in the host list on `CompliancePage` until the list is refreshed by some other action (changing filters, switching teams, switching tabs, completing an upload, adding a note, or clicking the manual refresh button).
This is purely a frontend state-refresh issue. The predecessor spec `compliance-remediation-display-fix` already fixed the list endpoint (`GET /api/compliance/items?team=X&status=Y`) to include `resolution_date` and `remediation_plan` in the SELECT and propagate them through `groupByHostname()`, so the backend list endpoint already returns the correct data. The defect is that `CompliancePage` never re-fetches the device list after a sidebar metadata save, so the in-memory `devices` state (populated by `fetchDevices`) keeps the stale value until one of the existing refresh triggers fires. The backend is out of scope for this fix.
Relevant code:
- `frontend/src/components/pages/CompliancePage.js` renders `<ComplianceDetailPanel>` (around lines 696702) with `onClose={() => setSelectedHost(null)}` (clears selection, no list refresh) and `onNoteAdded={refresh}` (where `refresh` runs `fetchSummary` + `fetchDevices`, but `onNoteAdded` is only invoked when a note is added or deleted).
- `frontend/src/components/pages/ComplianceDetailPanel.js` has `handleSaveMetadata()` which `PATCH`es `/api/compliance/items/:hostname/metadata` then calls its own `fetchDetail()` to refresh the panel, but never invokes any parent callback after a metadata save. As a result the parent list held in `CompliancePage` state is never re-fetched after a resolution date / remediation plan edit.
## Bug Analysis
### Current Behavior (Defect)
1.1 WHEN the user saves a resolution date and/or remediation plan in the sidebar via `handleSaveMetadata()` (`PATCH /api/compliance/items/:hostname/metadata` succeeds) THEN the system refreshes only the panel's own detail (`fetchDetail()`) and does not notify the parent `CompliancePage`, so `fetchDevices` is never re-issued.
1.2 WHEN the user closes the sidebar after a successful metadata save via `onClose` THEN the system only clears `selectedHost` (`setSelectedHost(null)`) and does not trigger any list refresh, so the parent `devices` state retains the pre-edit value.
1.3 WHEN the host list row re-renders after a sidebar metadata save without an intervening refresh THEN the system displays the stale Resolution Date / Remediation Plan value (or "—") because `devices` in `CompliancePage` state still holds the value from the last `fetchDevices` call.
### Expected Behavior (Correct)
2.1 WHEN the user saves a resolution date and/or remediation plan in the sidebar via `handleSaveMetadata()` and the `PATCH` succeeds THEN the system SHALL invoke a parent refresh callback (mirroring the existing `onNoteAdded` pattern) that re-issues `fetchDevices` so the parent list reflects the updated values.
2.2 WHEN the parent list has been re-fetched following a successful sidebar metadata save THEN the system SHALL display the updated Resolution Date / Remediation Plan value in the corresponding host list row without requiring a manual filter change, team change, tab change, or manual refresh.
### Unchanged Behavior (Regression Prevention)
3.1 WHEN a user adds or deletes a note in the sidebar THEN the system SHALL CONTINUE TO invoke the existing `onNoteAdded` refresh callback exactly as before.
3.2 WHEN a user changes team, changes the active/resolved tab, completes an upload, or clicks the manual refresh button THEN the system SHALL CONTINUE TO refresh the list via the existing `fetchSummary` + `fetchDevices` triggers.
3.3 WHEN a metadata save fails (the `PATCH` returns a non-OK response and `handleSaveMetadata()` sets `metaError`) THEN the system SHALL CONTINUE TO surface the error in the panel and SHALL NOT require the list to display changed values for a save that did not persist.
3.4 WHEN the user closes the sidebar without having saved any metadata change THEN the system SHALL CONTINUE TO clear the selection as before, and no unnecessary behavioral regression SHALL be introduced for the no-change case.
3.5 WHEN the host list renders hostname, IP address, device type, failing metrics, and seen count THEN the system SHALL CONTINUE TO display these fields correctly with no change in behavior.
3.6 WHEN the sidebar saves metadata THEN the system SHALL CONTINUE TO call its own `fetchDetail()` so the panel's in-place view and history remain correct.