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

4.8 KiB
Raw Blame History

Bugfix Requirements Document

Introduction

GitLab issue #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 PATCHes /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.