Files
cve-dashboard/.kiro/specs/compliance-chart-replacements/requirements.md

9.2 KiB
Raw Blame History

Requirements Document

Introduction

Replace two underperforming compliance dashboard charts with more actionable visualizations. Chart 4 (MTTR by Team) is replaced by an Aging Findings Distribution histogram, and Chart 5 (Most Persistent Findings) is replaced by a Net Change Waterfall chart. Both replacements use data already present in the existing SQLite schema (compliance_items.seen_count and compliance_uploads aggregate columns) and require no database migrations. The four other charts in ComplianceChartsPanel remain unchanged.

Glossary

  • Dashboard: The compliance charts panel rendered by ComplianceChartsPanel.js, containing six chart cards in a responsive grid.
  • Aging_Chart: The new Chart 4 replacement — a stacked bar / histogram showing active findings distributed across age buckets derived from seen_count.
  • Waterfall_Chart: The new Chart 5 replacement — a waterfall chart showing net movement per upload cycle (starting count → +new → +recurring → resolved → ending count).
  • Cycle: A single compliance report upload. Each upload represents one weekly reporting period.
  • Age_Bucket: A grouping of active findings by how many cycles they have been continuously observed: 1 cycle, 23 cycles, 46 cycles, 7+ cycles.
  • Seen_Count: The seen_count column on compliance_items, incremented each cycle an active finding persists. Starts at 1 on first appearance.
  • Compliance_API: The Express router at cve-dashboard/backend/routes/compliance.js serving /api/compliance/* endpoints.
  • ChartCard: The shared wrapper component providing title, subtitle, and dark-themed card styling for each chart in the Dashboard.
  • Recharts: The React charting library used by the Dashboard for all visualizations.
  • Design_System: The dark theme specification defined in DESIGN_SYSTEM.md, including color palette, monospace fonts, and card styling.

Requirements

Requirement 1: Aging Findings Distribution Backend Endpoint

User Story: As a compliance analyst, I want an API endpoint that returns active findings grouped by age bucket, so that the frontend can render the Aging Findings Distribution chart.

Acceptance Criteria

  1. WHEN a GET request is made to the aging endpoint, THE Compliance_API SHALL return active findings from compliance_items grouped into four Age_Buckets: 1 cycle (seen_count = 1), 23 cycles (seen_count between 2 and 3), 46 cycles (seen_count between 4 and 6), and 7+ cycles (seen_count >= 7).
  2. WHEN a GET request is made to the aging endpoint, THE Compliance_API SHALL include a per-team breakdown within each Age_Bucket so the frontend can render stacked segments.
  3. THE Compliance_API SHALL return the response as a JSON object with an array of bucket objects, each containing the bucket label, total count, and a count per team.
  4. WHEN no active findings exist, THE Compliance_API SHALL return an empty array with HTTP status 200.
  5. IF a database error occurs, THEN THE Compliance_API SHALL return HTTP status 500 with a JSON error message.
  6. THE Compliance_API SHALL replace the existing /mttr endpoint path so that no new route paths are introduced and the old MTTR endpoint is removed.

Requirement 2: Aging Findings Distribution Frontend Chart

User Story: As a compliance analyst, I want to see a stacked bar chart showing how many active findings fall into each age bucket, so that I can understand the shape of the current backlog and identify stale findings.

Acceptance Criteria

  1. THE Aging_Chart SHALL render a vertical stacked bar chart using Recharts with one bar group per Age_Bucket (1 cycle, 23 cycles, 46 cycles, 7+ cycles) on the X-axis and finding count on the Y-axis.
  2. THE Aging_Chart SHALL use one stacked color segment per team, using the existing TEAM_COLORS mapping defined in the Dashboard.
  3. THE Aging_Chart SHALL be wrapped in a ChartCard with the title "Aging Findings Distribution" and a subtitle describing the chart purpose.
  4. THE Aging_Chart SHALL use the shared DarkTooltip component to display bucket label, per-team counts, and total on hover.
  5. THE Aging_Chart SHALL render a NoData placeholder when the API returns an empty array.
  6. THE Aging_Chart SHALL occupy the same grid position (Chart 4 slot) previously held by the MTTR chart in the Dashboard layout.
  7. THE Aging_Chart SHALL conform to the Design_System by using monospace axis labels, the standard grid style, and the dark card background gradient.

Requirement 3: Net Change Waterfall Backend Endpoint

User Story: As a compliance analyst, I want an API endpoint that returns per-cycle waterfall data (starting count, new, recurring, resolved, ending count), so that the frontend can render the Net Change Waterfall chart.

Acceptance Criteria

  1. WHEN a GET request is made to the waterfall endpoint, THE Compliance_API SHALL return one row per upload cycle containing: the cycle report date, starting active count, new count, recurring count, resolved count, and ending active count.
  2. THE Compliance_API SHALL compute the starting count for each cycle as the ending count of the previous cycle, with the first cycle starting at zero.
  3. THE Compliance_API SHALL compute the ending count for each cycle as starting_count + new_count + recurring_count - resolved_count.
  4. THE Compliance_API SHALL read new_count, recurring_count, and resolved_count directly from the compliance_uploads table without requiring additional aggregation queries.
  5. WHEN no uploads exist, THE Compliance_API SHALL return an empty array with HTTP status 200.
  6. IF a database error occurs, THEN THE Compliance_API SHALL return HTTP status 500 with a JSON error message.
  7. THE Compliance_API SHALL replace the existing /top-recurring endpoint path so that no new route paths are introduced and the old persistent-findings endpoint is removed.

Requirement 4: Net Change Waterfall Frontend Chart

User Story: As a compliance analyst, I want to see a waterfall chart showing net movement per cycle (starting count → +new → +recurring → resolved → ending count), so that I can immediately tell whether the compliance posture is improving or degrading.

Acceptance Criteria

  1. THE Waterfall_Chart SHALL render a bar chart using Recharts where each cycle shows four visual segments: a transparent base (starting count), a red segment for new findings, an amber segment for recurring findings, and a green downward segment for resolved findings, producing a waterfall effect.
  2. WHEN a user hovers over any segment, THE Waterfall_Chart SHALL display a DarkTooltip showing the cycle date, starting count, new count, recurring count, resolved count, and ending count.
  3. THE Waterfall_Chart SHALL label the X-axis with cycle dates formatted as MM/DD/YY using the existing fmtDate helper.
  4. THE Waterfall_Chart SHALL label the Y-axis with finding counts using monospace axis styling consistent with the Design_System.
  5. THE Waterfall_Chart SHALL render a NoData placeholder when the API returns an empty array.
  6. THE Waterfall_Chart SHALL be wrapped in a ChartCard with the title "Net Change Waterfall" and a subtitle describing the chart purpose.
  7. THE Waterfall_Chart SHALL occupy the same grid position (Chart 5 slot) previously held by the Most Persistent Findings chart in the Dashboard layout.
  8. THE Waterfall_Chart SHALL use #EF4444 for new findings, #F59E0B for recurring findings, and #10B981 for resolved findings, matching the existing color conventions in the Dashboard.

Requirement 5: Frontend Data Fetching Integration

User Story: As a developer, I want the Dashboard to fetch data from the two new endpoints in place of the old ones, so that the panel loads the correct data for the replacement charts without breaking the other four charts.

Acceptance Criteria

  1. THE Dashboard SHALL replace the fetch call to /compliance/mttr with a fetch call to the aging endpoint and store the response in component state.
  2. THE Dashboard SHALL replace the fetch call to /compliance/top-recurring with a fetch call to the waterfall endpoint and store the response in component state.
  3. THE Dashboard SHALL continue to fetch /compliance/trends and /archer-tickets/status-trend without modification.
  4. THE Dashboard SHALL load all four endpoints in parallel using Promise.all on component mount, matching the existing loading pattern.
  5. IF any individual fetch fails, THEN THE Dashboard SHALL render the corresponding chart in its NoData state without affecting the other charts.

Requirement 6: Removal of Obsolete Code

User Story: As a developer, I want the old MTTR and Persistent Findings chart components and endpoints removed, so that the codebase does not contain dead code.

Acceptance Criteria

  1. THE Dashboard SHALL remove the MttrChart component function and all references to the mttr state variable.
  2. THE Dashboard SHALL remove the RecurringChart component function and all references to the recurring state variable.
  3. THE Compliance_API SHALL remove the old /mttr SQL query and handler logic, replacing it with the aging endpoint handler at the same route path.
  4. THE Compliance_API SHALL remove the old /top-recurring SQL query and handler logic, replacing it with the waterfall endpoint handler at the same route path.