Files
cve-dashboard/.kiro/specs/remediation-plan-history/tasks.md
2026-05-19 15:01:25 -06:00

3.3 KiB

Tasks — Remediation Plan History

Task 1: Create migration for compliance_item_history table [Requirement 2, 7]

  • Create backend/migrations/add_compliance_item_history.js with the schema from the design doc
  • [~] Table: compliance_item_history (id, hostname, field_name, old_value, new_value, change_reason, changed_by, changed_at)
  • [~] Add CHECK constraint on field_name: IN ('resolution_date', 'remediation_plan')
  • [~] Add index on (hostname, field_name)
  • [~] Add index on (changed_at)
  • [~] Register in migrations/run-all.js
  • [~] Run migration and verify table exists

Task 2: Modify PATCH /items/:hostname/metadata to record history [Requirement 1, 6]

  • [~] In backend/routes/compliance.js, locate the PATCH metadata handler
  • [~] Accept new optional change_reason field (max 500 chars, validated)
  • [~] Before updating compliance_items, SELECT current resolution_date and remediation_plan for the hostname
  • [~] For each field where old !== new, INSERT into compliance_item_history (hostname, field_name, old_value, new_value, change_reason, changed_by)
  • [~] Skip history insert if old === new (no-op changes)
  • [~] Wrap history insert + item update in a transaction
  • [~] Handle NULL → value and value → NULL transitions
  • [~] Add audit log entry with old/new values
  • [~] Verify existing response shape is preserved

Task 3: Extend GET /items/:hostname to return history [Requirement 4]

  • [~] In the existing /items/:hostname handler, add a query: SELECT id, field_name, old_value, new_value, change_reason, changed_by, changed_at FROM compliance_item_history WHERE hostname = $1 ORDER BY changed_at DESC LIMIT 10
  • [~] Add history array to the response object
  • [~] If query fails, return empty array (graceful degradation) and log error
  • [~] Verify response includes history alongside existing metrics and notes

Task 4: Modify bulk update commit to track history [Requirement 6]

  • [~] In the bulk update flow (POST /vcl/bulk-commit), before updating each hostname's resolution_date or remediation_plan, query current values
  • [~] For each changed field, INSERT into compliance_item_history with changed_by = req.user.username
  • [~] Skip if value is unchanged
  • [~] No change_reason for bulk updates (set to NULL)

Task 5: Add change_reason input and history section to ComplianceDetailPanel [Requirement 5]

  • [~] Add changeReason state and a single-line text input between the Save button and Notes section
  • [~] Pass change_reason in the PATCH request body when saving
  • [~] Clear changeReason after successful save
  • [~] Add "Change History" section below the remediation plan area
  • [~] Fetch history from the GET /items/:hostname response
  • [~] Display entries: field icon, old → new, username, date, reason (if present)
  • [~] Resolution dates formatted as YYYY-MM-DD, NULL shown as "—"
  • [~] Remediation plan values truncated to 60 chars with title tooltip
  • [~] Show "No changes recorded" when history is empty
  • [~] Run npm run build after changes

Task 6: Verify VCL burndown is unaffected [Requirement 3]

  • [~] Confirm burndown query in vclMultiVertical.js reads from compliance_items.resolution_date only
  • [~] Confirm donut query uses MAX(resolution_date) grouped by hostname
  • [~] Set a resolution date, change it multiple times, verify device appears once in burndown
  • [~] No code changes expected — verification only