docs(015-reporting-dashboards): task breakdown
28 tasks across a shared Foundational phase (schema, config, shared rate/date-range helpers, module scaffolding) and 4 independently-testable dashboard user stories. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
4a159725c2
commit
814d9d7b17
@@ -0,0 +1,188 @@
|
||||
---
|
||||
description: "Task list for 015-reporting-dashboards"
|
||||
---
|
||||
|
||||
# Tasks: Reporting and Analytics Dashboards
|
||||
|
||||
**Input**: Design documents from `specs/015-reporting-dashboards/`
|
||||
|
||||
**Prerequisites**: [plan.md](./plan.md), [spec.md](./spec.md), [research.md](./research.md),
|
||||
[data-model.md](./data-model.md),
|
||||
[contracts/reports-api-contract.md](./contracts/reports-api-contract.md),
|
||||
[quickstart.md](./quickstart.md)
|
||||
|
||||
**Organization**: Tasks are grouped by user story (US1 = P1 Management, US2 = P1 Product,
|
||||
US3 = P2 Support, US4 = P2 AI). All four share the Foundational phase (schema, config, shared
|
||||
helpers, module scaffolding) but are otherwise independent of each other.
|
||||
|
||||
## Format: `[ID] [P?] [Story] Description`
|
||||
|
||||
All file paths are relative to `supporthub-api/` (repo root).
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Foundational (Blocking Prerequisites)
|
||||
|
||||
- [ ] T001 Add `REPORTING_DEFAULT_WINDOW_DAYS` (default `30`),
|
||||
`REPORTING_SLA_RISK_THRESHOLD_MINUTES` (default `60`), and `REPORTING_TOP_N_LIMIT`
|
||||
(default `10`) to `src/config/env.ts`, exposed via a new `reportingConfig` in
|
||||
`src/config/reporting.ts` (or added to an existing config file, matching this codebase's
|
||||
own per-feature config-file convention)
|
||||
- [ ] T002 Add the `ErrorCodeLookup` model to `prisma/schema.prisma` per data-model.md, generate
|
||||
the migration via `prisma migrate diff --from-url <db-url> --to-schema-datamodel
|
||||
./prisma/schema.prisma --script`, hand-write it into
|
||||
`prisma/migrations/<timestamp>_add_error_code_lookup/migration.sql`, apply via `prisma
|
||||
migrate deploy` against the throwaway test database (depends on T001 only in that both
|
||||
are Foundational — no code dependency)
|
||||
- [ ] T003 Add `ai-support/knowledge/repository/error-code-lookup.repository.ts` —
|
||||
`create(errorCodeId, productId)`, exported from the knowledge module's repository index
|
||||
(depends on T002)
|
||||
- [ ] T004 [P] Call the new repository's `create(...)` from
|
||||
`ai-support/knowledge/service/error-codes.service.ts`'s existing
|
||||
`findKnownIssuesByErrorCode`, alongside (not replacing) 014's own
|
||||
`knownErrorLookupsCounter.inc(...)` call at that same call site (depends on T003)
|
||||
- [ ] T005 [P] Add `platform/reports/mapper/date-range.ts` — parses/validates `from`/`to` query
|
||||
params, defaulting via T001's `reportingConfig.defaultWindowDays`, throwing
|
||||
`ValidationError` when `from > to` (depends on T001)
|
||||
- [ ] T006 [P] Add `platform/reports/mapper/rate.ts` — a shared `computeRate(numerator,
|
||||
denominator): number | null` and `computeAverageSeconds(durations: number[]): number |
|
||||
null` pair, both returning `null` (never `NaN`/`0`) when there's no qualifying data
|
||||
(research.md §3) — no dependency, pure functions
|
||||
- [ ] T007 Scaffold `platform/reports/schema/` (query-param zod schema using T005's date-range
|
||||
parsing), `platform/reports/controller/reports.controller.ts` (empty methods to be filled
|
||||
in per user story below), `platform/reports/routes/reports.routes.ts` registering all four
|
||||
routes behind `requireRole('ADMIN')`, and update `platform/reports/index.ts` to export the
|
||||
new public surface, replacing `generateSummaryReport`'s stub entirely (depends on T005,
|
||||
T006)
|
||||
|
||||
**Checkpoint**: Config, schema, shared helpers, and module scaffolding in place. Each dashboard
|
||||
can now be built independently.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: User Story 1 - Management sees organization-wide support health (Priority: P1)
|
||||
|
||||
**Goal**: `GET /admin/reports/management` returns real figures per data-model.md's
|
||||
`ManagementDashboard` shape.
|
||||
|
||||
**Independent Test**: Quickstart Scenario 1.
|
||||
|
||||
### Tests for User Story 1
|
||||
|
||||
- [ ] T008 [P] [US1] Unit tests for T006's `computeRate`/`computeAverageSeconds` (empty input ->
|
||||
`null`; a real mix -> the correct value) in
|
||||
`tests/unit/platform/reports/rate-helpers.test.ts`
|
||||
|
||||
### Implementation for User Story 1
|
||||
|
||||
- [ ] T009 [US1] Add `platform/reports/repository/management.repository.ts` — one method per
|
||||
research.md §2's Management table row (ticket counts by status, SLA-run outcome counts,
|
||||
response/resolution duration row-fetches for T006 to average) (depends on T007)
|
||||
- [ ] T010 [US1] Add `ReportsService.getManagementDashboard(range)` composing T009's repository
|
||||
calls into the `ManagementDashboard` shape, reusing the `Resolution.resolvedBy` convention
|
||||
(research.md §4) for the AI-vs-human split (depends on T009)
|
||||
- [ ] T011 [US1] Wire `GET /admin/reports/management` to the controller/service (depends on T010)
|
||||
- [ ] T012 [US1] Integration test covering Quickstart Scenario 1 (real tickets in various
|
||||
terminal states, a met and a breached SLA run, verified figure-by-figure; a no-activity
|
||||
range returns all-zero counts and all-null rates) in
|
||||
`tests/integration/platform-reports/management-dashboard.test.ts` (depends on T011)
|
||||
|
||||
**Checkpoint**: Quickstart Scenario 1 passes.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 2 - See support broken down by product (Priority: P1)
|
||||
|
||||
**Goal**: `GET /admin/reports/product/:externalProductId` returns real figures per
|
||||
`ProductDashboard`.
|
||||
|
||||
**Independent Test**: Quickstart Scenario 2.
|
||||
|
||||
### Implementation for User Story 2
|
||||
|
||||
- [ ] T013 [P] [US2] Add `platform/reports/repository/product.repository.ts` — ticket/problem
|
||||
queries scoped by `productId`, plus a query against T003's `ErrorCodeLookup` table for
|
||||
the top-N ranking (`reportingConfig.topNLimit`) (depends on T007)
|
||||
- [ ] T014 [US2] Add `ReportsService.getProductDashboard(externalProductId, range)`, 404-ing via
|
||||
`NotFoundError` when the product doesn't resolve (FR-006) before running any aggregation
|
||||
query (depends on T013)
|
||||
- [ ] T015 [US2] Wire `GET /admin/reports/product/:externalProductId` (depends on T014)
|
||||
- [ ] T016 [US2] Integration test covering Quickstart Scenario 2 (two products' data never
|
||||
cross-contaminating each other's figures; an unknown product 404s) in
|
||||
`tests/integration/platform-reports/product-dashboard.test.ts` (depends on T015)
|
||||
|
||||
**Checkpoint**: Quickstart Scenario 2 passes.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 3 - Support sees team workload and performance (Priority: P2)
|
||||
|
||||
**Goal**: `GET /admin/reports/support` returns real figures per `SupportDashboard`.
|
||||
|
||||
**Independent Test**: Quickstart Scenario 3.
|
||||
|
||||
### Implementation for User Story 3
|
||||
|
||||
- [ ] T017 [P] [US3] Add `platform/reports/repository/support.repository.ts` — current
|
||||
`Assignment` workload-by-agent query, `SLARun` at-risk/breached queries (`resolutionDueAt`
|
||||
within `reportingConfig.slaRiskThresholdMinutes` of now, per research.md §2) (depends on
|
||||
T007)
|
||||
- [ ] T018 [US3] Add `ReportsService.getSupportDashboard(range)` (depends on T017)
|
||||
- [ ] T019 [US3] Wire `GET /admin/reports/support` (depends on T018)
|
||||
- [ ] T020 [US3] Integration test covering Quickstart Scenario 3 (real per-agent assignment
|
||||
counts; a near-due-but-not-breached run counted as at-risk, distinct from breached) in
|
||||
`tests/integration/platform-reports/support-dashboard.test.ts` (depends on T019)
|
||||
|
||||
**Checkpoint**: Quickstart Scenario 3 passes.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 4 - See how well the AI is performing (Priority: P2)
|
||||
|
||||
**Goal**: `GET /admin/reports/ai` returns real figures per `AiDashboard`.
|
||||
|
||||
**Independent Test**: Quickstart Scenario 4.
|
||||
|
||||
### Tests for User Story 4
|
||||
|
||||
- [ ] T021 [P] [US4] Unit test: the confidence-distribution bucketing reuses
|
||||
`decideConfidenceBand` (005-ai-support) against `aiConfig` defaults, not a reimplemented
|
||||
threshold check, in `tests/unit/platform/reports/confidence-distribution.test.ts`
|
||||
|
||||
### Implementation for User Story 4
|
||||
|
||||
- [ ] T022 [US4] Add `platform/reports/repository/ai.repository.ts` — `AISupportSession` outcome
|
||||
counts, `AIDiagnosis` confidence fetch, `AIKnowledgeReference` presence-per-session query,
|
||||
`AIAction`/`AIActionResult` outcome counts (depends on T007)
|
||||
- [ ] T023 [US4] Add `ReportsService.getAiDashboard(range)`, bucketing confidence via
|
||||
`decideConfidenceBand` + `aiConfig.defaultHighConfidence`/`defaultLowConfidence`
|
||||
(research.md §7) (depends on T022, T021)
|
||||
- [ ] T024 [US4] Wire `GET /admin/reports/ai` (depends on T023)
|
||||
- [ ] T025 [US4] Integration test covering Quickstart Scenario 4 (real AI sessions to mixed
|
||||
outcomes, mixed tool results, a spread of diagnosis confidence values) in
|
||||
`tests/integration/platform-reports/ai-dashboard.test.ts` (depends on T024)
|
||||
|
||||
**Checkpoint**: Quickstart Scenario 4 passes. All four dashboards work independently and
|
||||
together — this feature's full scope.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Polish & Cross-Cutting Concerns
|
||||
|
||||
- [ ] T026 [P] Update `specs/015-reporting-dashboards/checklists/requirements.md` Notes with any
|
||||
implementation-time findings
|
||||
- [ ] T027 Run `npx tsx scripts/check-architecture.ts` and `npm run lint`/`npm run typecheck`
|
||||
- [ ] T028 Full regression: `npm run test:unit` then the full integration suite against real
|
||||
Docker-provisioned Postgres/Redis, confirming nothing outside this feature regressed
|
||||
(particularly `error-codes.service.ts`'s own existing tests, now touched by T004)
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Execution Order
|
||||
|
||||
- **Foundational (Phase 1)**: No dependencies — BLOCKS all four user stories
|
||||
- **User Story 1 (Phase 2)**: Depends on Foundational — independent of US2/US3/US4
|
||||
- **User Story 2 (Phase 3)**: Depends on Foundational — independent of US1/US3/US4
|
||||
- **User Story 3 (Phase 4)**: Depends on Foundational — independent of US1/US2/US4
|
||||
- **User Story 4 (Phase 5)**: Depends on Foundational — independent of US1/US2/US3
|
||||
- **Polish (Phase 6)**: Depends on all four user stories
|
||||
Reference in New Issue
Block a user