Four new dataviz-informed UI primitives (stat tile, ranked bar list, status distribution, meter) shared across all four dashboards, no new charting dependency. 24 tasks across a shared Foundational phase and 4 independently-testable dashboard user stories. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.4 KiB
Implementation Plan: Reporting and Analytics Dashboards UI
Branch: 002-reporting-dashboards-ui | Date: 2026-09-09 | Spec: spec.md
Input: Feature specification from specs/002-reporting-dashboards-ui/spec.md
Summary
Presents supporthub-api's already-complete 015-reporting-dashboards contract (four GET /admin/reports/* endpoints) as a tabbed admin surface, replacing nothing existing —
admin/reports/page.tsx already hosts the SLA Monitor and Escalation Matrix (012-admin-list-
views work); this feature adds Management/Product/Support/AI as four more tabs on that same
page. New reusable dashboard primitives (stat tile, ranked bar list, status distribution bar,
meter) are built once in components/ui and reused across all four dashboards, following the
dataviz skill's methodology: pick the form before color, status colors (already defined in
this project's own design tokens) for status-flavored splits, a single sequential hue for
magnitude rankings, validated in both light and dark mode.
Technical Context
Language/Version: TypeScript, Next.js 14 App Router (unchanged).
Primary Dependencies: None new — TanStack Query (already the standard), the existing
components/ui kit, this project's own Tailwind design tokens. No charting library added
(spec.md Assumptions) — every visual is plain HTML/CSS per the dataviz skill's Tier 0/1
component guidance (a proportional div-based bar needs no SVG/canvas dependency).
Storage: N/A — no client-side persistence; date-range selection is component state (spec.md Assumptions).
Testing: Vitest for the new pure helpers (duration/rate formatting, the "no data" guard);
component tests for each dashboard's loading/empty/error/ready rendering (mocked query client,
matching 001-agent-admin-ui's own established testing pattern); Playwright E2E against the real
running supporthub-api + supporthub-web pair for the full tab-switching, date-range, and
product-selection flow — this session's standing rule of never claiming a frontend scenario done
without exercising it against real, live infrastructure.
Target Platform: Web, (admin) portal only (Constitution Principle III).
Project Type: Frontend — single Next.js app, no new module boundary crossed.
Performance Goals: Each dashboard fetches independently (its own useQuery) so switching
tabs doesn't block on data the current tab doesn't need; date-range changes debounce-free (a
single explicit "Apply" action, not a fetch per keystroke) to avoid hammering the backend while
typing a date.
Constraints: FR-008 — no new/changed backend endpoint; this is presentation-only. FR-004 —
every null rate/average renders as an explicit "No data" treatment, computed once in the
mapping layer (lib/api/reports.ts) so every consuming component gets an already-safe shape,
never a raw null a component might accidentally interpolate into text.
Scale/Scope: One new lib/api/reports.ts (+types), four new features/reports/*-dashboard.tsx
components, four new components/ui primitives (stat tile, ranked bar list, status distribution
bar, meter), one modified admin/reports/page.tsx (adds tabs), one shared date-range control.
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
| Principle / Section | Check | Result |
|---|---|---|
| I. Each Identity Has Exactly One Authority, and the Frontend Is Never It | Not applicable — no identity/access surface touched. | PASS — N/A |
| II. The Backend Is the Sole Source of Business Logic | Every figure (rates, distributions, rankings) is rendered exactly as the backend computed it — this feature does no business-rule computation, only display formatting (e.g. seconds -> "2h 15m"). | PASS |
| III. Strict Portal Boundaries | All new code lives under (admin)/features/reports — no customer- or support-portal import, no shared primitive leaks admin-only data (the new components/ui primitives are generic value/label/color renderers, not admin-shaped). |
PASS |
| IV. Typed API Boundary, No Ad Hoc Fetching | All four dashboards fetched through new lib/api/reports.ts functions wrapped in TanStack Query hooks — no direct fetch/axios in any component. |
PASS |
| V. Configuration Over Hardcoding | Not applicable — no admin-configurable enum rendered by this feature (the confidence bands/status labels are fixed, backend-defined vocabulary, not business policy). | PASS — N/A |
| VI. Accessible, Responsive, Enterprise-Grade UI | New primitives keep density over decoration per this principle's own wording — status colors always paired with a text label (never color-alone, satisfying both this principle's WCAG requirement and the dataviz skill's own non-negotiable), keyboard-reachable tab/date controls, responsive down to a single column. |
PASS |
| VII. Testing Gates | Typecheck/lint clean; new Vitest coverage for the mapping/formatting helpers and each dashboard's query-state rendering; Playwright coverage added for the reports tab-switching flow (not one of the constitution's two named cross-cutting journeys, but this project's own established practice of E2E-verifying every admin feature against a real backend, per 001's own precedent). | PASS |
No violations requiring Complexity Tracking justification.
Project Structure
Documentation (this feature)
specs/002-reporting-dashboards-ui/
├── plan.md
├── data-model.md
├── quickstart.md
└── tasks.md
Source Code (repository root)
supporthub-web/
├── src/
│ ├── components/ui/
│ │ ├── stat-tile.tsx # NEW
│ │ ├── ranked-bar-list.tsx # NEW
│ │ ├── status-distribution.tsx # NEW
│ │ ├── meter.tsx # NEW
│ │ └── index.ts # MODIFIED — export the four above
│ ├── lib/
│ │ ├── api/
│ │ │ ├── reports.ts # NEW — 4 fetch functions
│ │ │ └── types/
│ │ │ └── reports.ts # NEW — response + view-model types
│ │ └── format/
│ │ └── duration.ts # NEW — seconds -> "2h 15m" / "No data"
│ ├── features/reports/
│ │ ├── management-dashboard.tsx # NEW
│ │ ├── product-dashboard.tsx # NEW
│ │ ├── support-dashboard.tsx # NEW
│ │ ├── ai-dashboard.tsx # NEW
│ │ ├── date-range-control.tsx # NEW — shared by Management/Product/AI
│ │ ├── sla-monitor.tsx # UNCHANGED (012's own)
│ │ └── escalation-matrix.tsx # UNCHANGED (012's own)
│ └── app/(admin)/admin/reports/
│ └── page.tsx # MODIFIED — adds 4 tabs alongside the 2 existing sections
└── tests/
├── unit/lib/format/ # duration formatting, no-data guard
├── unit/features/reports/ # per-dashboard query-state rendering
└── e2e/ # reports tab-switching + date-range Playwright spec
Structure Decision: No new route, no new portal — extends the existing (admin)/admin/reports
page and features/reports module already established by 012-admin-list-views' SLA Monitor/
Escalation Matrix work.
Complexity Tracking
No constitution violations — table intentionally omitted.