Files
support_backend/specs/015-reporting-dashboards/checklists/requirements.md
T
saqib mirandClaude Sonnet 5 d65683641a feat(015-reporting-dashboards): four real reporting/analytics endpoints
Wires the pre-scaffolded, unused platform/reports module (ReportsService
.generateSummaryReport previously returned {}) into four real, admin-
gated dashboards matching docs/09-testing-observability-cicd.md's own
table:

- GET /admin/reports/management: total cases, AI-resolved, human-
  escalated, resolved/open, SLA compliance/breaches, escalation count,
  average response/resolution time.
- GET /admin/reports/product/:externalProductId: support volume,
  problem-category breakdown, recurring problems, AI-resolution/human-
  escalation rate, top error codes.
- GET /admin/reports/support: current per-agent workload, SLA at-risk/
  breached counts, escalation count, response/resolution performance.
- GET /admin/reports/ai: AI resolution/human-handoff rate, failed-
  troubleshooting-then-escalated rate, knowledge-match rate, confidence
  distribution (reusing 005-ai-support's own decideConfidenceBand),
  tool invocation success/failure.

Every rate/average is number|null -- null means no qualifying data in
range, never a computed NaN or a misleading 0. Adds one new durable
table, ErrorCodeLookup, since 014-full-observability's own equivalent
metric is a process-lifetime Prometheus counter unusable for a
historical "top errors" report.

Verified end-to-end against real Postgres/Redis: every figure checked
against hand-computed expected values, including a no-activity range
(all-zero counts, all-null rates) and cross-product isolation.

Also fixes a real regression the new ErrorCodeLookup FK caused in the
pre-existing known-issues.test.ts (its afterAll deleted ErrorCode rows
before the now-referencing lookup rows).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 11:59:38 +05:30

6.0 KiB

Specification Quality Checklist: Reporting and Analytics Dashboards

Purpose: Validate specification completeness and quality before proceeding to planning Created: 2026-09-09 Feature: spec.md

Content Quality

  • No implementation details (languages, frameworks, APIs)
  • Focused on user value and business needs
  • Written for non-technical stakeholders
  • All mandatory sections completed

Requirement Completeness

  • No [NEEDS CLARIFICATION] markers remain
  • Requirements are testable and unambiguous
  • Success criteria are measurable
  • Success criteria are technology-agnostic (no implementation details)
  • All acceptance scenarios are defined
  • Edge cases are identified
  • Scope is clearly bounded
  • Dependencies and assumptions identified

Feature Readiness

  • All functional requirements have clear acceptance criteria
  • User scenarios cover primary flows
  • Feature meets measurable outcomes defined in Success Criteria
  • No implementation details leak into specification

Notes

  • This is docs/10-implementation-roadmap.md's own Phase 11, third sub-area, per explicit user direction (013 was the security pass, 014 was full observability). Backend-first scope (Assumptions) follows the same pattern already established three times this session (010-identity-auth, 011-agent-ticket-queue, and 014-full-observability's own frontend-free scope) — a supporthub-web dashboard UI is a natural, separate follow-on, not re-litigated here via a fresh question.
  • The pre-scaffolded-but-inert platform/reports module (ReportsService.generateSummaryReport currently returns {}) and the ANALYTICS queue stub (src/jobs/analytics, logs only) were both confirmed via direct code inspection before writing this spec — the same "provisioned before this session's rebuild but never wired up" pattern found repeatedly this session. This feature wires up the former; the Assumptions section explicitly keeps the latter out of scope (synchronous queries, no pre-aggregation job, for this first cut).
  • All items pass; no revision iterations were needed. No [NEEDS CLARIFICATION] markers were required — every open question (default date window, SLA-risk threshold, top-N limit) had a reasonable, documented, CONFIGURABLE default (see Assumptions), matching the roadmap's own "never hardcode a placeholder value and ship it as final" instruction.

Implementation Notes (post-build)

  • Named the Product dashboard's own repository class ProductReportRepository (not ProductRepository) once it became clear resolving externalProductId -> Product should reuse catalog/products' own already-public productsRepository.findByExternalProductId rather than duplicating that lookup — avoids a name collision and keeps "one authority per concern" (Constitution Principle I's spirit) for product resolution.
  • ManagementRepository and SupportRepository both needed byte-identical first-response-duration and resolution-duration queries. Extracted into a shared SharedReportRepository both compose, rather than duplicating the Prisma query (or the averaging helper alone) twice — discovered while writing the second repository and seeing the copy-paste, not planned upfront in research.md.
  • "Top errors"/"most common errors" resolution-back-to-code logic moved into ErrorCodesService.getTopErrorCodesForProduct (a new method on the module that already owns ErrorCode), rather than the reports module reaching into errorCodesRepository/ errorCodeLookupRepository directly — cleaner module-boundary ownership than research.md's original per-repository sketch implied.
  • The AI dashboard's "failed troubleshooting then escalated" figure (spec.md User Story 4) has no single stored flag anywhere in this codebase — classifyStepOutcome's per-step verdicts are never persisted as their own durable record. Implemented as a documented proxy instead: an escalated session with toolCallCount > 0 attempted troubleshooting before giving up, one with zero attempts escalated immediately. Documented directly in ai.repository.ts's own code comment, the same "honest, documented simplification" precedent research.md §7 already set for the confidence-distribution bucketing.
  • Three of this module's public exports needed adding to their owning modules' top-level index.ts (not previously exposed): decideConfidenceBand/ConfidenceBand and knowledgeReferenceRepository from ai-support/sessions, matching the "extend an existing module's public surface for a later feature" precedent already used repeatedly this session (004's productsRepository, 009's problemsRepository).
  • Found a real regression during T028's full regression pass: known-issues.test.ts (004- product-knowledge, pre-existing) calls findKnownIssuesByErrorCode and its own afterAll deleted ErrorCode rows before this feature's new ErrorCodeLookup FK (RESTRICT) existed — once T004 started writing a lookup row on every call, that cleanup order started failing with an FK violation. Fixed by deleting ErrorCodeLookup rows first in that test's own afterAll. This feature's own new test files never delete ErrorCode rows at all, so they weren't affected the same way (leftover rows there are the same accepted throwaway-data tradeoff already established elsewhere this session).
  • Confirmed (not caused by this feature — the exact pre-existing issue 014-full-observability's own checklist already documented and root-caused via git checkout comparison) that this feature's own new integration test files, which also name their test products TEST_*, occasionally hit the same shared deriveProductCode "TEST" prefix collision under vitest's concurrent file execution when run alongside other TEST_*-prefixed files. Every dashboard test passes reliably run individually or in small groups; the intermittent 500 in a full combined run is the same known, out-of-scope, 003-ticketing concern.