docs(002-reporting-dashboards-ui): feature spec and quality checklist

Presentation-only follow-on to supporthub-api's already-complete
015-reporting-dashboards, per the same backend-first pattern used
throughout this session. Plan applies the dataviz skill methodology
given the user's explicit request for production-level design.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
saqib mir
2026-09-09 12:10:37 +05:30
co-authored by Claude Sonnet 5
parent 76bb6f326b
commit e7e6e853d5
2 changed files with 230 additions and 0 deletions
@@ -0,0 +1,42 @@
# Specification Quality Checklist: Reporting and Analytics Dashboards UI
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-09-09
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Backend counterpart (`supporthub-api`'s 015-reporting-dashboards) is already complete and
committed — this feature is presentation-only, per the same backend-first pattern already
used for every prior feature spanning both repos this session.
- The user asked explicitly for "production-level design" — this feature's plan.md accordingly
applies this project's `dataviz` skill methodology (form selection before color, status colors
reserved for status-flavored distributions, sequential single-hue for magnitude rankings,
validated against both light and dark mode) rather than an ad hoc visual treatment.
- All items pass; no revision iterations were needed. No [NEEDS CLARIFICATION] markers were
required.
+188
View File
@@ -0,0 +1,188 @@
# Feature Specification: Reporting and Analytics Dashboards UI
**Feature Branch**: `002-reporting-dashboards-ui`
**Created**: 2026-09-09
**Status**: Draft
**Input**: User description: "Reporting and analytics dashboards UI: a production-quality admin surface presenting the four dashboards (Management, Product, Support, AI) supporthub-api's 015-reporting-dashboards feature now exposes — date-range filtering, stat tiles, distributions, and ranked lists, following this project's established loading/empty/error/ready query-state discipline and design system."
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Admin sees organization-wide health at a glance (Priority: P1)
An admin opens the reports area and immediately sees, for a chosen date range, how support is
doing overall: total cases, how many were resolved and by whom (AI vs. a human), how many are
still open, whether SLA is being met, and average response/resolution time.
**Why this priority**: This is the dashboard the roadmap's own top-level success criteria map to
most directly — it's the first thing anyone opens the reports area to see.
**Independent Test**: Can be fully tested by loading the Management tab against a backend with
known data and confirming every figure on screen matches the API response exactly, with correct
loading/empty/error presentation.
**Acceptance Scenarios**:
1. **Given** the backend has ticket/SLA/escalation data for the default period, **When** the
admin opens the Management dashboard, **Then** every stat tile and the SLA compliance figure
show the real values from `GET /admin/reports/management`, not placeholder text.
2. **Given** the admin changes the date range, **When** the new range is applied, **Then** the
dashboard re-fetches and every figure updates to match the new range.
3. **Given** a rate or average is `null` (no qualifying data), **When** the dashboard renders,
**Then** it shows an explicit "No data" treatment, never `NaN`, `undefined`, or a bare `0`
that could be misread as a real zero.
4. **Given** the backend request fails, **When** the dashboard renders, **Then** it shows the
established error state (never a blank screen or a silently stale view).
---
### User Story 2 - Admin drills into one product's support health (Priority: P1)
An admin picks a product and sees that product's own support volume, problem-category
breakdown, AI/human resolution split, and most frequent error codes — never another product's
data mixed in.
**Why this priority**: Per-product visibility is as fundamental as the org-wide view for a
platform serving multiple SaaS products, and pairs directly with the Management view.
**Independent Test**: Can be fully tested by selecting two different products against a backend
with data for both and confirming each product's own figures show only its own data.
**Acceptance Scenarios**:
1. **Given** a product is selected, **When** the Product dashboard loads, **Then** support
volume, the problem-category breakdown, and the AI/human resolution rates all reflect only
that product.
2. **Given** the admin switches products, **When** the new product's data loads, **Then** the
previous product's figures are fully replaced, never blended or stale.
3. **Given** a product has no error-code lookups in range, **When** the dashboard renders,
**Then** the "top errors" section shows an explicit empty state, not a blank gap.
---
### User Story 3 - Admin sees team workload and SLA risk (Priority: P2)
An admin sees current per-agent workload and which tickets are approaching or past their SLA
due date, alongside response/resolution performance for the period.
**Why this priority**: Operational, day-to-day utility rather than a new class of information —
P2 relative to the two org/product-level views above.
**Independent Test**: Can be fully tested against a backend with known assignment/SLA data and
confirming per-agent workload and at-risk/breached counts match exactly.
**Acceptance Scenarios**:
1. **Given** agents have current open assignments, **When** the Support dashboard loads,
**Then** each agent's workload is shown, ranked by load.
2. **Given** some SLA runs are at risk and others already breached, **When** the dashboard
renders, **Then** the two counts are visually distinct, never merged into one figure.
---
### User Story 4 - Admin sees how well the AI is performing (Priority: P2)
An admin sees the AI's resolution rate, human-handoff rate, knowledge-match rate, confidence
distribution, and tool success/failure for the period.
**Why this priority**: Validates the AI-first design's premise for a narrower audience than the
org/product views — P2.
**Independent Test**: Can be fully tested against a backend with known AI session/diagnosis/tool
data and confirming every figure matches.
**Acceptance Scenarios**:
1. **Given** AI sessions resolved and escalated in the period, **When** the AI dashboard loads,
**Then** the resolution/handoff rates and the confidence distribution (proceed/ask/escalate)
match the real session data.
2. **Given** tool invocations succeeded and failed, **When** the dashboard renders, **Then** the
success/failure split is shown with each outcome visually distinct and labeled, never color
alone.
---
### Edge Cases
- What happens while a request is in flight? A loading state distinct from both "empty" and
"error" — the existing `getQueryState` discipline, never a flash of zeroed-out figures.
- What happens if the selected date range is invalid (`from` after `to`)? The date-range control
itself prevents choosing an invalid range; if the backend still rejects one, the error state
shows the backend's own message.
- What happens on a narrow viewport? Every dashboard degrades to a single-column layout — stat
tiles stack, ranked lists remain fully readable, nothing is clipped or requires horizontal
scroll.
- What happens in dark mode? Every figure, bar, and status color remains legible and uses this
project's existing dark-mode tokens — not a separate, unvalidated color set.
- What happens with a very long category/error-code name in a ranked list? It truncates with an
accessible full-text affordance (title attribute at minimum), never breaking the layout or
overlapping the value.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: System MUST present all four dashboards (Management, Product, Support, AI) from
`specs/002-reporting-dashboards-ui`'s own admin reports area, each independently loadable.
- **FR-002**: The Management, Product, and AI dashboards MUST support a date-range filter
(`from`/`to`), re-fetching on change; the Support dashboard's workload/risk figures are
current-state (per the backend contract) and are not range-filtered, matching
`supporthub-api`'s own `SupportDashboard.generatedAt` framing.
- **FR-003**: The Product dashboard MUST require a product to be selected before fetching, and
MUST show the backend's own error when an unknown product is requested.
- **FR-004**: Every rate/average field that the backend returns as `null` MUST render as an
explicit "No data" treatment — never `NaN`, a blank cell, or a `0` indistinguishable from a
real zero value.
- **FR-005**: Every data view MUST follow the project's established `getQueryState` discipline
(loading/empty/error/ready), never conflating any two of those states.
- **FR-006**: Ranked lists (problem categories, top errors, agent workload) MUST be sorted
descending by the backend's own ordering and MUST visually encode magnitude (not just list the
numbers as plain text) per this project's data-visualization standard.
- **FR-007**: Status-flavored distributions (AI confidence bands, tool success/failure, SLA
met/breached) MUST use this project's existing status colors (success/warning/destructive)
consistently with their real-world meaning, MUST include a visible legend/label (never color
alone), and MUST remain legible and validated in both light and dark mode.
- **FR-008**: This feature MUST NOT introduce any new backend endpoint or change any existing
one — it is a pure presentation layer over `supporthub-api`'s already-complete
015-reporting-dashboards contract.
- **FR-009**: The reports area MUST remain reachable only to an authenticated admin session,
consistent with every other admin surface in this application.
### Key Entities
- **Dashboard view-model**: The frontend-side shape each dashboard's API response is mapped into
for rendering — never persisted, recomputed on every fetch.
- **Date range selection**: UI-local state (`from`/`to`) driving the Management/Product/AI
dashboards' queries; not synced to a URL param in this first cut (Assumptions).
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: An admin can answer "how is support doing," "how is this product doing," "who's
overloaded," and "is the AI helping" each within one screen, with no figure requiring a
separate lookup to interpret.
- **SC-002**: Every figure on every dashboard is independently verifiable against the backend's
own response for the same request — no discrepancy, no client-side recomputation that could
drift from what the API actually returned.
- **SC-003**: The reports area is fully usable — legible, correctly laid out, no clipped or
overlapping content — from a narrow mobile viewport up through a large desktop screen, and in
both light and dark mode.
## Assumptions
- Scope is presentation only, per the user's own explicit direction to build the backend first
(015-reporting-dashboards, already complete) and the frontend as a distinct follow-on —
consistent with every prior feature this session that spanned both repos.
- Date-range selection is local component state, not persisted to the URL or local storage in
this first cut — a shareable/bookmarkable link to a specific range is a reasonable future
enhancement, not required here.
- The Product dashboard's product picker reuses the existing product list already available to
the admin UI (`GET /admin/products`, 012-admin-list-views) rather than introducing a new
lookup endpoint.
- "Visually encode magnitude" (FR-006) means a simple proportional bar behind/beside each ranked
row — not a full charting library. This project has no charting dependency today, and
introducing one for a handful of ranked lists and status splits would be disproportionate to
the need (this session's own "don't add complexity beyond what the task requires" standard).