Backend: restructured /vertical/:code/metrics endpoint to return metrics
with nested sub_teams arrays. Each metric now has the ALL: rollup as the
primary row and individual team breakdowns (ACCESS-OPS, STEAM, etc.) as
sub_teams. Also returns a teams array for the filter UI.
Frontend: VerticalDetailView now supports two interaction modes:
- Expand/collapse: click the arrow on any metric row to reveal sub-team
breakdown inline (teal-highlighted rows beneath the parent)
- Team filter: click a team button to filter the entire table to show
only that team's numbers per metric
Both modes avoid double-counting by using the ALL: rollup for totals
and only showing sub-team data as supplementary detail.
The Summary sheet in each vertical spreadsheet contains both sub-team rows
(ACCESS-OPS, STEAM, INTELDEV, etc.) AND a rollup row (ALL: NTS-AEO) per
metric. The rollup row already includes all sub-team totals, so summing
all rows was double-counting every device.
Fixed in three places:
- GET /stats endpoint: added AND team LIKE 'ALL:%' filter
- persistMultiVerticalUpload snapshot creation: only sum ALL: entries
- GET /vertical/:code/metrics category aggregation: only use ALL: rows
Also ran a one-time data fix to correct existing compliance_snapshots.
The compliance_items table only contains non-compliant devices (detail
sheet rows). Compliant devices are never inserted — they only exist in
the Summary sheet totals. This caused Compliant to show 0 and
Compliance % to show 0% for all verticals.
Fix: stats endpoint now reads from vcl_multi_vertical_summary (parsed
Summary sheet data) for total/compliant/non-compliant counts. Snapshot
creation also uses summary data for accurate trend charting.
The compliance_items table is still used for:
- Donut chart (blocked vs in-progress based on resolution_date)
- Burndown forecast (devices with/without resolution dates)
- Device drill-down (actual non-compliant device list)