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
203 lines
18 KiB
Markdown
203 lines
18 KiB
Markdown
# Requirements Document
|
|
|
|
## Introduction
|
|
|
|
Historical tracking for resolution dates and remediation plans on compliance items. When a user changes the resolution_date or remediation_plan for a device, the previous value is preserved as an audit trail entry with a timestamp and the identity of the user who made the change. The most recent values remain directly queryable on the compliance_items table so existing VCL reporting queries continue to work without modification.
|
|
|
|
This spec also covers per-metric scoping of resolution_date and remediation_plan (GitLab issue #19). Previously these fields were edited at the hostname level (one value applied uniformly to all active metrics for a device). The per-metric extension allows analysts to set different resolution dates and remediation plans for individual metrics within the same device, matching the pattern already established by compliance notes.
|
|
|
|
## Glossary
|
|
|
|
- **Compliance_Item**: A row in the `compliance_items` table representing a single non-compliant device/metric pair.
|
|
- **Resolution_Date**: A DATE field on a compliance item indicating when remediation is expected to complete.
|
|
- **Remediation_Plan**: A TEXT field (max 2000 characters) describing the planned remediation approach.
|
|
- **History_Entry**: A row in the `compliance_item_history` table capturing a previous value of resolution_date or remediation_plan before it was overwritten.
|
|
- **Change_Reason**: An optional text field on a History_Entry describing why the change was made.
|
|
- **Detail_Panel**: The ComplianceDetailPanel UI component that displays device-level compliance information and allows editing of metadata fields.
|
|
- **VCL_Report**: The multi-vertical compliance reporting system that uses resolution_date for burndown forecasts and blocked/in-progress donut charts.
|
|
- **Current_Value**: The value stored directly on the compliance_items row, representing the most recent resolution_date or remediation_plan.
|
|
- **Metric_Selector**: The UI control in the Detail_Panel that allows the user to choose which metric(s) a remediation plan update applies to. Displays active metrics as selectable options with category-colored chips.
|
|
- **Active_Metric**: A compliance item with `status = 'active'` for the selected hostname — a metric currently failing for that device.
|
|
- **Metric_Chip**: A small colored badge displaying a metric ID, used throughout the compliance UI to visually identify metrics by category color.
|
|
- **Metadata_API**: The `PATCH /api/compliance/items/:hostname/metadata` endpoint that updates resolution_date and remediation_plan on compliance items.
|
|
|
|
## Requirements
|
|
|
|
### Requirement 1: Persist History on Field Change
|
|
|
|
**User Story:** As a compliance analyst, I want previous resolution dates and remediation plans to be preserved when I make changes, so that I have an audit trail of what was planned and when plans changed.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN a user updates the resolution_date for a hostname via the metadata PATCH endpoint, THE History_Service SHALL insert a History_Entry containing the previous resolution_date value, the field name, the hostname, the timestamp of the change, the username of the user who made the change, and the change_reason if provided.
|
|
2. WHEN a user updates the remediation_plan for a hostname via the metadata PATCH endpoint, THE History_Service SHALL insert a History_Entry containing the previous remediation_plan value, the field name, the hostname, the timestamp of the change, the username of the user who made the change, and the change_reason if provided.
|
|
3. WHEN the previous value is NULL and the user sets a new value, THE History_Service SHALL insert a History_Entry with the old_value recorded as NULL.
|
|
4. WHEN the new value is identical to the current value, THE History_Service SHALL NOT create a History_Entry.
|
|
5. WHEN a bulk update changes resolution_date or remediation_plan for multiple hostnames, THE History_Service SHALL insert one History_Entry per hostname per changed field.
|
|
6. THE History_Service SHALL accept an optional change_reason field in the metadata PATCH request body.
|
|
|
|
### Requirement 2: History Storage Schema
|
|
|
|
**User Story:** As a system administrator, I want history entries stored in a dedicated table with proper indexing, so that history queries are fast and do not impact existing compliance_items queries.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE Database SHALL store history entries in a `compliance_item_history` table with columns: id (serial primary key), hostname (text, not null), field_name (text, not null), old_value (text), new_value (text), change_reason (text), changed_by (text, not null), changed_at (timestamptz, default NOW()).
|
|
2. THE Database SHALL index the `compliance_item_history` table on (hostname, field_name) for efficient per-device history lookups.
|
|
3. THE Database SHALL index the `compliance_item_history` table on (changed_at) for chronological queries.
|
|
4. THE compliance_items table SHALL continue to store the current resolution_date and remediation_plan directly as columns, unchanged from the existing schema.
|
|
|
|
### Requirement 3: Reporting Isolation
|
|
|
|
**User Story:** As a VCL report consumer, I want burndown forecasts and donut charts to use only the current resolution_date, so that historical changes do not cause double-counting or incorrect projections.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE VCL_Report SHALL read resolution_date exclusively from the compliance_items table for burndown and donut calculations.
|
|
2. THE VCL_Report SHALL NOT join or reference the compliance_item_history table for any reporting query.
|
|
3. WHEN multiple History_Entries exist for a hostname, THE VCL_Report SHALL use only the Current_Value from compliance_items.resolution_date for forecasting.
|
|
|
|
### Requirement 4: History Retrieval API
|
|
|
|
**User Story:** As a compliance analyst, I want to retrieve the change history for a device's resolution date and remediation plan, so that I can see who changed what and when.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN a client requests the detail for a hostname, THE Compliance_API SHALL return the history of resolution_date and remediation_plan changes alongside the current values and notes.
|
|
2. THE Compliance_API SHALL return history entries sorted by changed_at in descending order (most recent first).
|
|
3. THE Compliance_API SHALL return a maximum of 10 history entries per hostname.
|
|
4. THE Compliance_API SHALL include the fields: field_name, old_value, new_value, change_reason, changed_by, and changed_at for each History_Entry.
|
|
5. IF no history entries exist for a hostname, THE Compliance_API SHALL return an empty array for the history field.
|
|
|
|
### Requirement 5: History Display in Detail Panel
|
|
|
|
**User Story:** As a compliance analyst, I want to see the history of changes to resolution date and remediation plan in the device detail panel, so that I can understand how plans have evolved over time.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE Detail_Panel SHALL display a "Change History" section showing all History_Entries for the selected hostname.
|
|
2. WHEN a History_Entry exists, THE Detail_Panel SHALL display the field that changed, the old value, the new value, who made the change, when the change occurred, and the change reason if one was provided.
|
|
3. THE Detail_Panel SHALL display history entries in reverse chronological order (most recent change at the top).
|
|
4. WHEN no history entries exist, THE Detail_Panel SHALL display a message indicating no changes have been recorded.
|
|
5. THE Detail_Panel SHALL format resolution_date values as YYYY-MM-DD and remediation_plan values as truncated text with a tooltip or expandable view for long entries.
|
|
6. THE Detail_Panel SHALL include a text input for change_reason when saving resolution_date or remediation_plan changes.
|
|
|
|
### Requirement 6: Bulk Update History Tracking
|
|
|
|
**User Story:** As a compliance analyst, I want bulk xlsx updates to also track history, so that mass changes to resolution dates and remediation plans are auditable.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN the bulk update commit endpoint applies changes to resolution_date or remediation_plan, THE History_Service SHALL create History_Entries for each hostname where the value changed.
|
|
2. THE History_Service SHALL record the changed_by as the username of the user who initiated the bulk update.
|
|
3. WHEN a bulk update row contains the same value as the current value for a hostname, THE History_Service SHALL NOT create a History_Entry for that field.
|
|
|
|
### Requirement 7: Database Migration
|
|
|
|
**User Story:** As a developer, I want the history table created via a standard migration script, so that it can be applied to existing deployments without manual intervention.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE Migration SHALL create the `compliance_item_history` table if it does not already exist.
|
|
2. THE Migration SHALL create the required indexes on the `compliance_item_history` table.
|
|
3. THE Migration SHALL be idempotent and safe to run multiple times without error.
|
|
4. THE Migration SHALL NOT modify the existing compliance_items table structure.
|
|
|
|
### Requirement 8: Per-Metric Metadata API
|
|
|
|
**User Story:** As a compliance analyst, I want to set resolution dates and remediation plans for specific metrics within a device, so that I can track different remediation timelines for different compliance failures on the same hostname.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE Metadata_API SHALL accept an optional `metric_id` field (string) in the request body to scope the update to a single metric for the given hostname.
|
|
2. THE Metadata_API SHALL accept an optional `metric_ids` field (array of strings) in the request body to scope the update to multiple specific metrics for the given hostname.
|
|
3. WHEN `metric_ids` is provided, THE Metadata_API SHALL update only the compliance_items rows matching the specified hostname AND metric_id values.
|
|
4. WHEN `metric_id` is provided (single string), THE Metadata_API SHALL update only the compliance_items row matching the specified hostname AND metric_id.
|
|
5. IF both `metric_id` and `metric_ids` are provided, THEN THE Metadata_API SHALL use `metric_ids` and ignore `metric_id`.
|
|
6. WHEN neither `metric_id` nor `metric_ids` is provided, THE Metadata_API SHALL update all active compliance_items for the hostname, preserving backward compatibility with the existing hostname-level behavior.
|
|
7. IF a provided metric_id does not correspond to an active compliance_item for the hostname, THEN THE Metadata_API SHALL return a 400 error identifying the invalid metric_id.
|
|
8. WHEN `metric_ids` is provided, THE Metadata_API SHALL validate that each entry is a non-empty string of 100 characters or fewer.
|
|
|
|
### Requirement 9: Per-Metric Metric Selector UI
|
|
|
|
**User Story:** As a compliance analyst, I want a metric selector in the detail panel when editing remediation plans, so that I can choose which metrics a resolution date or remediation plan applies to — matching the pattern used for notes.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN the Detail_Panel is open for a hostname with more than one Active_Metric, THE Detail_Panel SHALL display a Metric_Selector above the resolution date and remediation plan inputs.
|
|
2. WHEN the Detail_Panel is open for a hostname with exactly one Active_Metric, THE Detail_Panel SHALL pre-select that metric and display the Metric_Selector as a single non-removable selection.
|
|
3. THE Metric_Selector SHALL allow the user to select one or more Active_Metrics simultaneously.
|
|
4. THE Metric_Selector SHALL display each option using the Metric_Chip component with the metric's category color, so that metrics are visually distinguishable.
|
|
5. WHEN the hostname has more than one Active_Metric, THE Metric_Selector SHALL display a "Select All" toggle that selects all Active_Metrics when activated.
|
|
6. WHEN all Active_Metrics are already selected, THE "Select All" toggle SHALL change to "Deselect All" and deselect all Active_Metrics when activated.
|
|
7. WHEN the Detail_Panel first opens for a hostname with multiple Active_Metrics, THE Metric_Selector SHALL pre-select all Active_Metrics by default, preserving the existing hostname-level editing experience.
|
|
|
|
### Requirement 10: Per-Metric Field Display
|
|
|
|
**User Story:** As a compliance analyst, I want to see the current resolution date and remediation plan for the selected metric(s), so that I know what values are already set before making changes.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN a single metric is selected in the Metric_Selector, THE Detail_Panel SHALL populate the resolution date and remediation plan inputs with the current values from that specific compliance_item row.
|
|
2. WHEN multiple metrics are selected and all share the same resolution_date value, THE Detail_Panel SHALL display that shared value in the resolution date input.
|
|
3. WHEN multiple metrics are selected and they have different resolution_date values, THE Detail_Panel SHALL display the resolution date input as empty with placeholder text indicating "Multiple values".
|
|
4. WHEN multiple metrics are selected and all share the same remediation_plan value, THE Detail_Panel SHALL display that shared value in the remediation plan input.
|
|
5. WHEN multiple metrics are selected and they have different remediation_plan values, THE Detail_Panel SHALL display the remediation plan input as empty with placeholder text indicating "Multiple values".
|
|
6. WHEN the user saves with "Multiple values" placeholder visible and the input left empty, THE Detail_Panel SHALL NOT send that field in the PATCH request, preserving existing per-metric values.
|
|
|
|
### Requirement 11: Per-Metric History Tracking
|
|
|
|
**User Story:** As a compliance analyst, I want the change history to record which specific metric was changed, so that the audit trail reflects per-metric remediation plan changes accurately.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE compliance_item_history table SHALL include a `metric_id` column (text, nullable) to record which metric the change applies to.
|
|
2. WHEN a per-metric update changes a field value, THE History_Service SHALL record the metric_id in the History_Entry.
|
|
3. WHEN a hostname-level update (no metric_id specified) changes a field value, THE History_Service SHALL record the metric_id as NULL in the History_Entry, indicating the change applied to all metrics.
|
|
4. THE History_Entry SHALL record the old_value and new_value per metric when a per-metric update is performed, reflecting the actual previous value of that specific compliance_item row.
|
|
5. WHEN a per-metric update targets multiple metrics with different current values, THE History_Service SHALL insert one History_Entry per metric that actually changed, each with its own old_value.
|
|
6. THE Compliance_API SHALL include the metric_id field in history entries returned to the client.
|
|
|
|
### Requirement 12: Per-Metric History Display
|
|
|
|
**User Story:** As a compliance analyst, I want the change history section to show which metric each change applied to, so that I can distinguish between hostname-wide changes and metric-specific changes.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN a History_Entry has a non-null metric_id, THE Detail_Panel SHALL display the associated Metric_Chip next to the history entry.
|
|
2. WHEN a History_Entry has a null metric_id, THE Detail_Panel SHALL display "All metrics" label next to the history entry to indicate a hostname-level change.
|
|
3. THE Detail_Panel SHALL continue to display all history entries for the hostname in reverse chronological order, regardless of metric_id.
|
|
|
|
### Requirement 13: Per-Metric Reporting
|
|
|
|
**User Story:** As a VCL report consumer, I want burndown forecasts to use per-metric resolution dates, so that the forecast accurately reflects when each individual compliance failure is expected to be resolved.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE VCL_Report SHALL read resolution_date from each individual compliance_items row (per hostname+metric_id pair) for burndown calculations, rather than using a single hostname-level value.
|
|
2. THE VCL_Report SHALL count each compliance_item row with a null resolution_date as a separate blocker in the donut chart.
|
|
3. THE VCL_Report SHALL bucket each compliance_item row by its own resolution_date month for the burndown forecast chart.
|
|
4. WHEN deduplicating by hostname for aggregated views, THE VCL_Report SHALL use the latest (MAX) resolution_date among all active metrics for that hostname.
|
|
|
|
### Requirement 14: Per-Metric History Migration
|
|
|
|
**User Story:** As a developer, I want the history table extended with a metric_id column via a migration script, so that per-metric history tracking can be deployed to existing environments.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. THE Migration SHALL add a nullable `metric_id` column (text) to the `compliance_item_history` table.
|
|
2. THE Migration SHALL create an index on (hostname, metric_id) for efficient per-metric history lookups.
|
|
3. THE Migration SHALL be idempotent and safe to run multiple times without error.
|
|
4. THE Migration SHALL NOT alter or backfill existing history rows — pre-existing entries retain a NULL metric_id indicating they were hostname-level changes.
|
|
|
|
### Requirement 15: Backward Compatibility
|
|
|
|
**User Story:** As an existing user of the bulk upload and API workflows, I want hostname-level updates to continue working without modification, so that existing integrations and scripts are not broken by the per-metric change.
|
|
|
|
#### Acceptance Criteria
|
|
|
|
1. WHEN the Metadata_API receives a request without `metric_id` or `metric_ids`, THE Metadata_API SHALL update all active compliance_items for the hostname, matching the pre-existing behavior.
|
|
2. WHEN the bulk update commit endpoint processes a row, THE Metadata_API SHALL continue to apply resolution_date and remediation_plan to all active metrics for that hostname.
|
|
3. THE Detail_Panel SHALL default to "Select All" metrics when first opened, so that saving without changing the metric selection produces the same hostname-level update behavior as before.
|
|
4. WHEN all metrics are selected and the user saves, THE Metadata_API SHALL NOT include metric_ids in the request body, triggering the hostname-level update path for backward compatibility.
|