Files
cve-dashboard/.kiro/specs/forecast-burndown-chart/requirements.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

17 KiB
Raw Blame History

Requirements Document

Introduction

This feature adds a per-metric forecast burndown chart to the CCP Metrics page. Unlike the existing aggregated burndown (which rolls up across all verticals by hostname), this chart focuses on individual compliance metrics (e.g., 2.3.5, 2.3.6, 5.2.5) and combines historical compliance data with forward-looking remediation projections in a single stacked bar + line chart. The chart displays actual historical data on the left side and forecasted future data on the right side, separated by a bold vertical divider. A metric selector allows users to switch between metrics. The chart reads from the same compliance_items table that the AEO Compliance page writes to, so device-level edits (resolution_date changes) dynamically feed into the forecast.

Glossary

  • Forecast_Burndown_API: The backend endpoint that returns combined historical and forecast burndown data for a specific compliance metric, identified by metric_id.
  • Metric_Selector: A dropdown or picker UI component that allows the user to choose which compliance metric to display in the chart.
  • Historical_Data: Monthly compliance snapshots from the past 3 months plus the current month, showing actual total asset counts, non-compliant device counts, and compliance percentages as recorded at each snapshot point.
  • Forecast_Data: Projected future monthly data points computed from active non-compliant devices with scheduled resolution_date values, assuming total asset count remains constant and all remediation plans complete on schedule.
  • Compliance_Percentage: The ratio of compliant devices to total devices for a given metric, expressed as a percentage (0%100%).
  • Total_Assets: The total number of devices in scope for a given metric at a point in time.
  • Non_Compliant_Count: The number of devices that are non-compliant for a given metric at a point in time.
  • Divider_Line: A bold vertical line on the chart separating actual historical data (left) from forecasted future data (right).
  • CCP_Metrics_Page: The page component (CCPMetricsPage.js) where the forecast burndown chart is displayed.
  • Compliance_Items_Table: The compliance_items PostgreSQL table that tracks non-compliant devices with fields including hostname, metric_id, status, resolution_date, vertical, and team.

Requirements

Requirement 1: Per-Metric Forecast Burndown API Endpoint

User Story: As a compliance analyst, I want an API endpoint that returns combined historical and forecast burndown data for a specific metric, so that the frontend can render a chart showing past compliance trends and projected future remediation.

Acceptance Criteria

  1. WHEN a GET request is made to /api/compliance/vcl-multi/metric/:metricId/forecast-burndown, THE Forecast_Burndown_API SHALL return a JSON response containing metric_id, historical, forecast, and current_snapshot fields within 3 seconds.
  2. THE Forecast_Burndown_API SHALL compute historical as an array of exactly 4 monthly data points (the current month plus the 3 preceding months in chronological order), where each data point contains month (YYYY-MM), total_assets, non_compliant, and compliance_pct.
  3. THE Forecast_Burndown_API SHALL derive historical total_assets and non_compliant counts from the compliance_snapshots table filtered by the vertical associated with the requested metricId in compliance_items (determined by querying the vertical column of active devices matching that metric_id), combined with per-metric device counts from compliance_items for that snapshot period.
  4. THE Forecast_Burndown_API SHALL compute forecast as an array of projected future monthly data points, where each data point contains month (YYYY-MM), total_assets, non_compliant, and compliance_pct.
  5. THE Forecast_Burndown_API SHALL project forecast data by assuming the current total_assets count remains constant and that each non-compliant device with a resolution_date in a future month will become compliant in that month.
  6. THE Forecast_Burndown_API SHALL compute current_snapshot containing total_assets, non_compliant, compliant, compliance_pct, blockers (count of devices with no resolution_date), and with_dates (count of devices with a resolution_date).
  7. THE Forecast_Burndown_API SHALL require authentication via requireAuth() middleware.
  8. IF the metricId parameter does not match any active devices in compliance_items (where status = 'active' and vertical IS NOT NULL), THEN THE Forecast_Burndown_API SHALL return a 200 response with empty historical and forecast arrays and current_snapshot with all numeric fields set to 0.
  9. THE Forecast_Burndown_API SHALL return forecast data extending forward until all devices with resolution dates are projected to be remediated, or for a maximum of 12 months from the current date, whichever comes first.
  10. IF the database query fails or an internal error occurs while processing the request, THEN THE Forecast_Burndown_API SHALL return a 500 response with a JSON body containing an error field indicating the failure reason.

Requirement 2: Available Metrics List Endpoint

User Story: As a frontend developer, I want an API endpoint that returns the list of distinct metrics with active non-compliant devices, so that the metric selector can be populated with valid options.

Acceptance Criteria

  1. WHEN a GET request is made to /api/compliance/vcl-multi/metrics-list, THE Forecast_Burndown_API SHALL return a 200 response containing a JSON array of objects, each containing metric_id (string) and device_count (integer representing the number of distinct hostnames with status active for that metric) fields.
  2. THE Forecast_Burndown_API SHALL include only metrics that have at least one active non-compliant device in compliance_items where vertical IS NOT NULL.
  3. THE Forecast_Burndown_API SHALL sort the returned array by metric_id in ascending alphanumeric order.
  4. THE Forecast_Burndown_API SHALL require authentication via requireAuth() middleware.
  5. IF no metrics have active non-compliant devices with a non-null vertical, THEN THE Forecast_Burndown_API SHALL return a 200 response containing an empty JSON array.
  6. IF the database query fails, THEN THE Forecast_Burndown_API SHALL return a 500 response with a JSON object containing an error field.

Requirement 3: Forecast Computation Logic

User Story: As a developer, I want a pure helper function that computes forecast burndown data for a given metric from device records and historical snapshots, so that the computation is testable in isolation.

Acceptance Criteria

  1. THE computeMetricForecastBurndown helper function SHALL accept a currentDevices array (each element containing at minimum hostname and resolution_date fields, where resolution_date is either a YYYY-MM-DD string or null), a totalAssets count (non-negative integer), and a historicalSnapshots array (each element containing month as YYYY-MM, total_assets, non_compliant, and compliance_pct), and return an object with historical, forecast, and current_snapshot fields.
  2. FOR ALL valid inputs, THE computeMetricForecastBurndown function SHALL satisfy the invariant: current_snapshot.blockers + current_snapshot.with_dates = current_snapshot.non_compliant.
  3. FOR ALL valid inputs where total_assets > 0, THE computeMetricForecastBurndown function SHALL compute compliance_pct as ROUND((total_assets - non_compliant) / total_assets * 100, 1) for each data point.
  4. FOR ALL forecast data points, THE computeMetricForecastBurndown function SHALL produce monotonically non-increasing non_compliant counts (each month has equal or fewer non-compliant devices than the previous month).
  5. FOR ALL forecast data points, THE computeMetricForecastBurndown function SHALL produce monotonically non-decreasing compliance_pct values.
  6. THE computeMetricForecastBurndown function SHALL hold total_assets constant across all forecast data points, using the current month's total as the baseline.
  7. WHEN the currentDevices array is empty, THE computeMetricForecastBurndown function SHALL return an empty forecast array and current_snapshot with all zero values except total_assets.
  8. FOR ALL forecast months, THE computeMetricForecastBurndown function SHALL compute non_compliant as the count of devices whose resolution_date is after that month (devices not yet remediated) plus blockers (devices with no resolution_date).
  9. THE computeMetricForecastBurndown function SHALL generate forecast data points extending forward month-by-month until all devices with resolution dates are projected to be remediated, or for a maximum of 12 months from the current date, whichever comes first.
  10. IF totalAssets is 0, THEN THE computeMetricForecastBurndown function SHALL return compliance_pct of 0 for all data points in historical, forecast, and current_snapshot.
  11. IF totalAssets is less than the number of elements in currentDevices, THEN THE computeMetricForecastBurndown function SHALL use the count of currentDevices as non_compliant without clamping to totalAssets.

Requirement 4: Forecast Burndown Chart Component

User Story: As a senior leader viewing the CCP Metrics page, I want to see a combined historical and forecast burndown chart for each metric, so that I can visualize past compliance trends and projected future remediation timelines.

Acceptance Criteria

  1. THE Forecast_Burndown_Chart SHALL be displayed on the CCP_Metrics_Page in a dedicated section below the Metric_Selector.
  2. THE Forecast_Burndown_Chart SHALL render a stacked bar chart where blue bars represent Total_Assets (100% height baseline) and orange bars represent Non_Compliant_Count.
  3. THE Forecast_Burndown_Chart SHALL render a green line overlay showing Compliance_Percentage as a trend line with percentage labels at each data point.
  4. THE Forecast_Burndown_Chart SHALL display a left Y-axis scaled to the maximum Total_Assets value for device counts, and a right Y-axis scaled from 0% to 100% for Compliance_Percentage.
  5. THE Forecast_Burndown_Chart SHALL display the X-axis labeled with months (YYYY-MM format), showing up to 16 data points (up to 4 historical months plus up to 12 forecast months).
  6. THE Forecast_Burndown_Chart SHALL render a bold vertical Divider_Line separating Historical_Data (left side) from Forecast_Data (right side), positioned between the last historical data point and the first forecast data point.
  7. THE Forecast_Burndown_Chart SHALL render forecast bars and line segments with 50% opacity to visually distinguish projections from actuals.
  8. THE Forecast_Burndown_Chart SHALL display raw device count labels inside the bars (total assets count in blue bars, non-compliant count in orange bars).
  9. THE Forecast_Burndown_Chart SHALL display compliance percentage values as labels on the green trend line at each data point.
  10. WHEN the Forecast_Burndown_API returns both empty historical and empty forecast arrays for a selected metric, THE Forecast_Burndown_Chart SHALL display a message indicating no data is available for that metric.
  11. WHEN the user selects a different metric from the Metric_Selector, THE Forecast_Burndown_Chart SHALL fetch updated data from the Forecast_Burndown_API and re-render the chart with the new metric's data.
  12. WHILE the Forecast_Burndown_API request is in flight, THE Forecast_Burndown_Chart SHALL display a loading indicator in place of the chart content.
  13. IF the Forecast_Burndown_API request fails, THEN THE Forecast_Burndown_Chart SHALL display an inline error message with an AlertCircle icon and the error description, styled with a red border consistent with the existing error display pattern on the CCP_Metrics_Page.
  14. WHEN the Forecast_Burndown_API returns a non-empty historical array but an empty forecast array, THE Forecast_Burndown_Chart SHALL render only the historical bars and trend line without a Divider_Line or forecast section.

Requirement 5: Metric Selector Component

User Story: As a compliance analyst, I want a metric picker that lets me choose which metric's forecast burndown to view, so that I can analyze remediation progress for individual compliance requirements.

Acceptance Criteria

  1. THE Metric_Selector SHALL be displayed above or adjacent to the Forecast_Burndown_Chart on the CCP_Metrics_Page.
  2. THE Metric_Selector SHALL populate its options by fetching the available metrics list from the metrics-list endpoint on page load.
  3. THE Metric_Selector SHALL display each metric option showing the metric_id and the count of active non-compliant devices.
  4. WHEN the user selects a metric, THE Metric_Selector SHALL trigger a data fetch for that metric's forecast burndown and update the chart.
  5. WHEN the Metric_Selector finishes loading the metrics list and defaults to the first metric in the sorted list, THE Metric_Selector SHALL automatically trigger a data fetch for that default metric's forecast burndown and update the chart.
  6. WHILE the metrics list is loading, THE Metric_Selector SHALL display a loading indicator and remain non-interactive until the fetch completes or fails.
  7. IF the metrics list endpoint returns an empty array, THEN THE Metric_Selector SHALL display a message indicating no metrics with active non-compliant devices exist.
  8. IF the metrics list endpoint request fails, THEN THE Metric_Selector SHALL display an inline error message consistent with the existing error display pattern on the CCP_Metrics_Page.
  9. WHILE the forecast burndown data is loading after a metric selection, THE Metric_Selector SHALL remain interactive, and if the user selects a different metric before the previous fetch completes, THE Metric_Selector SHALL discard the previous in-flight response and use only the result from the most recent selection.

Requirement 6: Dynamic Data Integration with AEO Compliance Page

User Story: As a compliance analyst, I want the forecast burndown chart to reflect device-level edits made on the AEO Compliance page in real time, so that when I update a device's resolution_date for a metric, the forecast projection updates accordingly on the next chart load.

Acceptance Criteria

  1. THE Forecast_Burndown_API SHALL query the compliance_items table directly (not a cached copy), so that edits made via the AEO Compliance page's PATCH /items/:hostname/metadata endpoint are reflected in the next API call made after the PATCH response completes.
  2. WHEN a user changes a device's resolution_date on the AEO Compliance page for a specific metric, THE Forecast_Burndown_API SHALL include that updated date in its forecast computation on the next request for that metric.
  3. WHEN a device's status changes from active to resolved on the AEO Compliance page, THE Forecast_Burndown_API SHALL exclude that device from the non-compliant count on the next request.
  4. IF a device's resolution_date is cleared (set to NULL) on the AEO Compliance page, THEN THE Forecast_Burndown_API SHALL count that device as a blocker in the current_snapshot.blockers count and exclude it from month-by-month forecast remediation projections on the next request.
  5. IF a device's resolution_date is changed to a date in a month that has already passed relative to the current date, THEN THE Forecast_Burndown_API SHALL treat that device as projected to be remediated in the current month (not exclude it from non-compliant count until its status changes to resolved).
  6. THE Forecast_Burndown_API SHALL use the current state of compliance_items as the source of truth for the current snapshot and forecast projections, with no application-level caching between requests.

Requirement 7: Historical Data Derivation

User Story: As a compliance analyst, I want the chart to show actual historical compliance data for the past 3 months, so that I can see the real trend leading into the forecast.

Acceptance Criteria

  1. THE Forecast_Burndown_API SHALL derive historical data from the compliance_snapshots table, which records monthly total_devices, compliant, and non_compliant counts per vertical, for the 3 calendar months immediately preceding the current month.
  2. THE Forecast_Burndown_API SHALL compute per-metric historical non_compliant count at each snapshot point by multiplying the vertical's snapshot non_compliant count by the ratio of the metric's non-compliant devices to the vertical's total non-compliant devices (as recorded in compliance_items for that period), rounding to the nearest integer.
  3. IF the vertical's total non_compliant count is 0 at a historical snapshot point, THEN THE Forecast_Burndown_API SHALL set the metric's non_compliant count to 0 for that data point.
  4. THE Forecast_Burndown_API SHALL use the vertical's snapshot total_devices as the metric's total_assets for each historical data point.
  5. WHEN no historical snapshots exist for a metric's vertical, THE Forecast_Burndown_API SHALL return an empty historical array.
  6. THE Forecast_Burndown_API SHALL include the current month as the most recent historical data point, computed from live compliance_items data rather than a stored snapshot.
  7. THE Forecast_Burndown_API SHALL return historical data points in chronological order (oldest first).