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
This commit is contained in:
151
.kiro/specs/ccp-metrics-view-restructure/tasks.md
Normal file
151
.kiro/specs/ccp-metrics-view-restructure/tasks.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# Implementation Plan: CCP Metrics View Restructure
|
||||
|
||||
## Overview
|
||||
|
||||
Restructure the CCP Metrics page from a vertical-first drill-down model to a metric-first model. Two new backend endpoints aggregate metrics across verticals. The frontend replaces VerticalTable/VerticalDetailView with MetricTable/MetricDetailView, removes the "By Vertical" table from AggregatedBurndownChart, and inverts the drill-down state hierarchy.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [x] 1. Add backend endpoints for metric-centric aggregation
|
||||
- [x] 1.1 Implement GET /metrics endpoint in backend/routes/vclMultiVertical.js
|
||||
- Add route handler that queries `vcl_multi_vertical_summary` using only `ALL:` rollup rows from the latest upload per vertical
|
||||
- Aggregate by `metric_id`: SUM non_compliant, compliant, total; MAX metric_desc, category; AVG target
|
||||
- Compute `compliance_pct` as `compliant / total` (0 when total is 0)
|
||||
- Sort by `non_compliant` DESC
|
||||
- Return `{ metrics: [...] }` with empty array when no data exists
|
||||
- Require `requireAuth()` middleware
|
||||
- Return HTTP 500 with `{ "error": "Database error" }` on query failure
|
||||
- _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9_
|
||||
|
||||
- [x] 1.2 Implement GET /metric/:id/verticals endpoint in backend/routes/vclMultiVertical.js
|
||||
- Validate metric ID parameter (reject if > 50 chars with HTTP 400)
|
||||
- Query all rows for the metric from latest uploads
|
||||
- Separate `ALL:` rollup rows from sub-team rows
|
||||
- Build per-vertical entries with nested `sub_teams` arrays
|
||||
- Sort verticals by `non_compliant` DESC
|
||||
- Return `{ metric_id, metric_desc, category, verticals: [...] }` with empty verticals array when metric not found
|
||||
- Require `requireAuth()` middleware
|
||||
- Return HTTP 500 with `{ "error": "Database error" }` on query failure
|
||||
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9_
|
||||
|
||||
- [ ]* 1.3 Write property test: Metrics aggregation uses only rollup rows from latest uploads
|
||||
- **Property 1: Metrics aggregation uses only rollup rows from latest uploads**
|
||||
- Generate random `vcl_multi_vertical_summary` rows with multiple verticals, metrics, uploads, and team configurations
|
||||
- Assert the endpoint returns exactly one entry per distinct `metric_id` with totals matching only `ALL:`-prefixed rows from the latest upload per vertical
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- **Validates: Requirements 3.1, 3.3**
|
||||
|
||||
- [ ]* 1.4 Write property test: Metrics computed fields are mathematically correct
|
||||
- **Property 2: Metrics computed fields are mathematically correct**
|
||||
- Assert `compliance_pct` equals `compliant / total` (or 0 when total is 0) for each metric
|
||||
- Assert `target` equals the arithmetic mean of target values across verticals for each metric
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- **Validates: Requirements 3.4, 3.5**
|
||||
|
||||
- [ ]* 1.5 Write property test: Metrics response is sorted by non-compliant descending
|
||||
- **Property 3: Metrics response is sorted by non-compliant descending**
|
||||
- Assert each entry's `non_compliant` is >= the next entry's `non_compliant`
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- **Validates: Requirements 3.6**
|
||||
|
||||
- [ ]* 1.6 Write property test: Metric-verticals breakdown is complete and correct
|
||||
- **Property 4: Metric-verticals breakdown is complete and correct**
|
||||
- Assert one vertical entry per vertical that has the metric in its latest upload
|
||||
- Assert each entry's `sub_teams` contains exactly the non-rollup team rows for that metric/vertical
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- **Validates: Requirements 4.1, 4.3**
|
||||
|
||||
- [ ]* 1.7 Write property test: Metric-verticals response is sorted by non-compliant descending
|
||||
- **Property 5: Metric-verticals response is sorted by non-compliant descending**
|
||||
- Assert each vertical entry's `non_compliant` is >= the next entry's `non_compliant`
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- **Validates: Requirements 4.4**
|
||||
|
||||
- [x] 2. Checkpoint - Backend endpoints verified
|
||||
- Ensure all tests pass, ask the user if questions arise.
|
||||
|
||||
- [x] 3. Remove "By Vertical" table from AggregatedBurndownChart
|
||||
- [x] 3.1 Remove the "By Vertical" contribution table JSX from AggregatedBurndownChart in frontend/src/components/pages/CCPMetricsPage.js
|
||||
- Remove the entire `{data.by_vertical && data.by_vertical.length > 0 && (...)}` block that renders the per-vertical table below the bar chart
|
||||
- Preserve the summary header (total non-compliant, blockers, in-progress, projected clear date) and bar chart
|
||||
- Preserve all loading, error, empty-state, and all-blockers display behaviors
|
||||
- _Requirements: 1.1, 1.2, 1.3_
|
||||
|
||||
- [x] 4. Implement MetricTable component and replace VerticalTable
|
||||
- [x] 4.1 Create MetricTable component in frontend/src/components/pages/CCPMetricsPage.js
|
||||
- Render one row per metric from the `/metrics` endpoint response
|
||||
- Columns: Metric ID, Description, Category, Compliant, Non-Compliant, Total, Compliance %, Target %
|
||||
- Sort rows by non-compliant descending (server-side, already sorted)
|
||||
- Rows are clickable — clicking triggers `onSelectMetric(metricId)`
|
||||
- Handle empty state (no metrics data)
|
||||
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5_
|
||||
|
||||
- [x] 4.2 Replace VerticalTable usage with MetricTable in the overview render logic
|
||||
- Add fetch call to `GET /api/compliance/vcl-multi/metrics` in the overview data loading
|
||||
- Pass fetched metrics data to MetricTable
|
||||
- Wire `onSelectMetric` to set `selectedMetric` state
|
||||
- _Requirements: 2.4, 2.5_
|
||||
|
||||
- [x] 5. Implement MetricDetailView and update drill-down state
|
||||
- [x] 5.1 Create MetricDetailView component in frontend/src/components/pages/CCPMetricsPage.js
|
||||
- Fetch data from `GET /metric/:id/verticals` on mount
|
||||
- Display header with metric ID, description, category
|
||||
- Display aggregated stats cards (total, compliant, non-compliant, compliance %)
|
||||
- Display table of verticals with columns: vertical name, compliant, non-compliant, total, compliance %
|
||||
- Clicking a vertical row calls `onSelectVertical(vertical, verticalData)`
|
||||
- Include "Back to Overview" button that calls `onBack`
|
||||
- Handle loading, error, and empty states
|
||||
- _Requirements: 5.1, 5.2, 5.3, 5.4, 6.2_
|
||||
|
||||
- [x] 5.2 Restructure drill-down state in CCPMetricsPage main component
|
||||
- Change state model from `selectedVertical → selectedMetric → selectedTeam` to `selectedMetric → selectedVertical → selectedTeam`
|
||||
- Add state variables: `selectedMetric`, `selectedMetricData`, `selectedVertical`, `selectedVerticalData`, `selectedTeam`
|
||||
- Update render logic: no metric = Overview (MetricTable), metric only = MetricDetailView, metric+vertical = MetricSubTeamView, all three = MetricDeviceList
|
||||
- Wire back-navigation handlers at each level (clear appropriate state to go up one level)
|
||||
- Pass `selectedVerticalData.sub_teams` to MetricSubTeamView as `metricData`
|
||||
- _Requirements: 5.4, 5.5, 5.6, 5.7, 5.8, 6.1, 6.2, 6.3, 6.4, 6.5_
|
||||
|
||||
- [ ]* 5.3 Write property test: Drill-down state determines rendered view
|
||||
- **Property 6: Drill-down state determines rendered view**
|
||||
- Generate random combinations of `(selectedMetric, selectedVertical, selectedTeam)` state values
|
||||
- Assert exactly one view is rendered for each combination following the state hierarchy rules
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- **Validates: Requirements 6.1, 6.5**
|
||||
|
||||
- [ ] 6. Verify backward compatibility of existing endpoints
|
||||
- [ ]* 6.1 Write integration tests verifying existing endpoints are unchanged
|
||||
- Verify `GET /vertical/:code/metrics` returns same response shape
|
||||
- Verify `GET /vertical/:code/metric/:metricId/devices` returns same response shape
|
||||
- Verify `GET /vertical/:code/burndown` returns same response shape
|
||||
- Verify `GET /stats` still returns `vertical_breakdown` and `metric_breakdown` fields
|
||||
- Test file: `backend/__tests__/ccp-metrics-view-restructure.property.test.js`
|
||||
- _Requirements: 7.1, 7.2, 7.3, 7.4_
|
||||
|
||||
- [x] 7. Final checkpoint - Ensure all tests pass
|
||||
- Ensure all tests pass, ask the user if questions arise.
|
||||
|
||||
## Notes
|
||||
|
||||
- Tasks marked with `*` are optional and can be skipped for faster MVP
|
||||
- Each task references specific requirements for traceability
|
||||
- Checkpoints ensure incremental validation
|
||||
- Property tests validate universal correctness properties from the design document
|
||||
- The existing `MetricSubTeamView` and `MetricDeviceList` components are reused with minor prop adjustments — no new component creation needed for those
|
||||
- All backend endpoints are added to the existing `backend/routes/vclMultiVertical.js` file
|
||||
- All frontend changes are within `frontend/src/components/pages/CCPMetricsPage.js`
|
||||
- Property-based tests use `fast-check` (already in project dependencies)
|
||||
|
||||
## Task Dependency Graph
|
||||
|
||||
```json
|
||||
{
|
||||
"waves": [
|
||||
{ "id": 0, "tasks": ["1.1", "1.2"] },
|
||||
{ "id": 1, "tasks": ["1.3", "1.4", "1.5", "1.6", "1.7", "3.1"] },
|
||||
{ "id": 2, "tasks": ["4.1"] },
|
||||
{ "id": 3, "tasks": ["4.2", "5.1"] },
|
||||
{ "id": 4, "tasks": ["5.2"] },
|
||||
{ "id": 5, "tasks": ["5.3", "6.1"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user