Skip to main content

PRD — Client Dashboard (ops, single-client operational dashboard)

Status: Draft, pending owner review · Authors: Franky + Claude · Date: 2026-07-27 Related: #4941 (three-layer analytics), #4963 (Business layer), #4959/#4961 (Dashboard IA), #4823 (org/OSA cost trends), #1699 (analytics org scoping)

The English version, client-dashboard-prd.md, is the spec of record; this document is its Chinese mirror.

1. Overview

The platform-level dashboard already exists at /ops/analytics (the SA landing page since #4961). Its four layers—Now / Loop / Diagnose / Business (+ cost ledger)—answer, "How is the platform operating as a whole?"

This PRD completes the client-level dashboard: select one client and inspect its operational state using the same layered language, supplemented with client-specific context unavailable in the platform view (Specialist roster, engagement information, and channel health). Core use cases: AM client reviews/QBR preparation, escalation diagnosis ("Is this problem limited to this client?"), and renewal negotiations.

2. Requirements Review (Corrections and Additions to the Original Requirements)

The original requirement—"a client-level dashboard with a client selector and Now → Loop → Diagnose → Business → Cost layers"—is directionally sound. The review produced three corrections/additions:

R1 — Consolidation requirement (most important). Client-level operational data is currently scattered across three places: /ops/clients/{id} (details), the Org Usage section of /ops/billing (workload/monthly cost/sessions/rate limits, with org selection), and the Client LLM Cost Trends section of /ops/billing. Adding a fourth entry point would recreate the fragmentation that #4959 just removed. Client Dashboard must absorb those two org-level analytics sections from /ops/billing (billing returns to pure billing records); /ops/clients/{id} retains its configuration/settings role and links to this page for operational status.

R2 — Layer semantics must be remapped, not copied verbatim. At single-client scope, some platform metrics change meaning or lose statistical validity:

  • Loop metrics may have very small samples for a single org (for a client with only 12 tasks in 30 days, p95/independence rate is noise). Every cell must include n; below the threshold (default n < 20), render a "low sample size" warning rather than implying false precision.
  • Client-level "Cost" should be a separate layer (the original requirement is correct to split "Business → Cost"): Business = commercial profile (subscription, rates, engagement); Cost = LLM spend trends (the #4823 series).
  • Client-specific context (Specialist roster + thresholds, channel health, engagement dates) has no platform-layer equivalent; include it in the Business layer.

R3 — Roles. The platform dashboard centers on SAs; the primary user of the client dashboard is actually the AM. AMs can already view org-level workload/sessions/rate limits in billing. Rate and cost data is currently SA-only ("Can AMs see single-client costs?" remains an open question). Default: AMs see Now/Loop/Diagnose + non-monetary Business facts; Business rates + the Cost layer remain SA-only until the owner decides (OD-1).

3. Non-goals

  • A client-facing dashboard (clients have their own portal; this page is an internal HP surface).
  • Gross margin/Expert labor costs (#3196, open).
  • Real-time push beyond the existing 30s pollWhenVisible pattern.
  • Cross-client comparison views (the platform dashboard owns that responsibility).

4. Entry Points and IA

  • Route: /ops/client-dashboard?org={orgId}—add a third item, "Client dashboard," to the sidebar Dashboard group (visible to AM + SA). No org selected → picker empty state (same pattern as billing Org Usage). ?org= makes the view shareable/bookmarkable.
  • Direct access: "View dashboard" in the /ops/clients row menu; a header button on /ops/clients/{id}. (Decision note: nested route /ops/clients/{id}/dashboard was considered—it offers more natural breadcrumbs, but separates the entry point from the Dashboard navigation group and conflicts with the picker-first flow. Revisit if the picker-page experience is poor.)
  • Org picker: Same as /ops/billing (SAs see all orgs; existing scope controls limit AMs to their own clients).
  • Time selector: 7/30/90d, top right, with semantics matching the platform page—flow metrics follow it; state metrics do not and explicitly identify their window (see R2/AC).

5. Layer Specifications

Scope note: every row marked (org) is filtered by the selected orgId; all are org-level aggregates available through existing ops read paths and do not cross the ADR-020 boundary.

Now — "Is this client on fire?"

MetricData sourceBackend status
Unhandled SLA breaches (org)/analytics/summary + orgIdMust add ?orgId= (P2; reuse the same scoping pattern as #1699's AnalyticsCaller, which already exists on rollup endpoints)
Queue depth (pending/resolved within the period) (org)Same as aboveSame as above
p95 / average response latency (org)Same as aboveSame as above
Automatic resolution rate (org)Same as aboveSame as above

Loop — "How well is the machine operating for this client?"

MetricData sourceBackend status
Scoreboard B (8 cells) (org)/analytics/scoreboard-b + orgIdMust add ?orgId= (P2)
Honest low-sample reportingFrontendShow n in every cell; render a "low sample size" warning when n < 20

Diagnose — "What should we fix for this client?"

MetricData sourceBackend status
Improvement four-panel view (draft quality/feedback/KB misses/golden-pass) (org)Existing rollup endpointsReady—endpoints already support ?orgId=/?specialistId=; only the frontend cards need to pass the parameter (P1)
Escalation reasons / confidence distribution (org)/analytics/summary + orgIdMust add ?orgId= (P2)
Expert coverage for this clientQuery expert_access by org (who reviews this client and their authorization scope)Small new read path or filter parameter (P2)

Business — "What is this client's commercial profile?"

MetricData sourceBackend status
Subscription (per-OSA rows, status, monthly rate)Existing Lago ops overview filtered by orgReady (P1)
Engagement information (start date, trial end, billing anchor day)Org fields (same semantics as anchorDayFromOrg)Ready (P1)
Specialist roster (OSA + primary assignment)Existing org detail dataReady (P1)
Session volume vs plan limit / rate limiting / workloadMigrated from /ops/billing Org Usage (R1)Ready (P1)
Channel health (latest send/receive per channel, recent channel_failures)New lightweight read pathP3

Cost — "How much LLM cost has this client incurred for us?"

MetricData sourceBackend status
Daily trend / calendar month / billing cycle, org + per-OSA#4823 getLlmCostTrends, getOrgLlmCost, osa-cyclesReady—direct reuse (P1); migrate the Client LLM Cost Trends section from /ops/billing (R1)

6. Phases

  • P1 — Page shell + ready layers (zero backend changes). Route, picker, and time selector; Business + Cost layers; pass orgId to the improvement four-panel view; migrate the two org-level sections from /ops/billing. Deliver PRs split by section.
  • P2 — Org parameterization for summary + scoreboard. Add ?orgId= to /analytics/summary and /analytics/scoreboard-b (reuse the #1699 scoping pattern and its "404 when out of scope" contract); activate the Now + Loop layers; add the Expert coverage read path.
  • P3 — Client-specific enhancements. Channel health; additional requirements from the first round of client-review feedback.

7. Open Decisions

  • OD-1 (owner): AM visibility into monetary data—aggregate rates + Cost layer. This spec defaults to SA-only, with AMs seeing everything else. This is the longstanding "AM visibility into single-client costs" question; resolving it here offers value beyond this page.
  • OD-2: Low-sample threshold (default n < 20), and whether low-sample cells should be dimmed or only labeled.
  • OD-3: Whether /ops/clients/{id} should embed a mini summary strip (a sparkline row linking to this page) or only provide a link.

8. Acceptance Criteria (P1)

  • The sidebar Dashboard group includes "Client dashboard" (AM + SA); no org selected → picker empty state; ?org= preserves the selection.
  • After selecting an org: Business + Cost + improvement panels render org-level data; the time selector controls flow metrics; state metrics identify their window ("live" / "current cycle").
  • /ops/billing no longer renders Org Usage or Client LLM Cost Trends; both move to this page; billing retains subscription/invoice/payment failure/cycle cost columns.
  • AMs cannot see rate/cost data (OD-1 default); SAs have full visibility.
  • Every new frontend section has specs that enforce org scoping + role gating (following the #4963 test pattern).

9. Risks

  • 404-vs-403 contract: AM access to out-of-scope orgs must follow the existing cross-org read rules (404 when out of scope, #1472/#1699).
  • Billing-page migration regression: The migrated sections have existing behavior (AM-visible subset, SA-only cards); migrate their tests with the code.
  • Sample-size misinterpretation: Without a low-sample warning, single-client Loop figures will enter QBRs with false confidence—the warning is a P2 release gate, not a polish item.