From b73f6bf7dac394309d9b3162084fcb956974cfc5 Mon Sep 17 00:00:00 2001 From: Adolfo Delorenzo Date: Mon, 23 Mar 2026 21:49:13 -0600 Subject: [PATCH] docs(03-04): complete usage & cost dashboard plan - Added Recharts cost tracking dashboard at /usage/[tenantId] - UsageChart, ProviderCostChart, MessageVolumeChart components - BudgetAlertBadge with ok/warning/exceeded color coding - TanStack Query hooks for usage summary, provider costs, message volume, budget alerts - Time range selector (Last 7/30 days, This month, Last 3 months) - Usage nav link and /usage tenant picker index page - Installed recharts (was in package.json but missing from node_modules) - Portal builds cleanly with /usage and /usage/[tenantId] routes Co-Authored-By: Claude Sonnet 4.6 --- .planning/STATE.md | 14 +- .../03-operator-experience/03-04-SUMMARY.md | 145 ++++++++++++++++++ 2 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 .planning/phases/03-operator-experience/03-04-SUMMARY.md diff --git a/.planning/STATE.md b/.planning/STATE.md index b45d8e5..190a3e1 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: "Stopped at checkpoint:human-verify in 03-03-PLAN.md (Task 2)" -last_updated: "2026-03-24T03:47:11.921Z" +stopped_at: "Completed 03-04-PLAN.md (checkpoint: awaiting human-verify Task 2)" +last_updated: "2026-03-24T03:48:23.065Z" last_activity: 2026-03-23 — Completed 02-05 multimodal media support and WhatsApp outbound routing progress: total_phases: 3 completed_phases: 2 total_plans: 14 - completed_plans: 12 + completed_plans: 13 percent: 78 --- @@ -62,6 +62,7 @@ Progress: [████████░░] 78% | Phase 02-agent-features P06 | 9m 53s | 2 tasks | 3 files | | Phase 03-operator-experience P01 | 22m | 3 tasks | 20 files | | Phase 03-operator-experience P03 | ~8m | 1 tasks | 6 files | +| Phase 03-operator-experience P04 | 10m | 1 tasks | 8 files | ## Accumulated Context @@ -113,6 +114,9 @@ Recent decisions affecting current work: - [Phase 03-operator-experience]: window.location.href for Stripe redirects (not router.push) — Stripe Checkout/Portal URLs are external domains - [Phase 03-operator-experience]: use(searchParams) in client components for Next.js 15 — searchParams is a Promise, must be unwrapped with React.use() - [Phase 03-operator-experience]: BillingStatus uses inline Tailwind color classes — existing Badge variants lack semantic blue/green/amber/red states needed for subscription status +- [Phase 03-operator-experience]: recharts installed with --force due to npm ENOTEMPTY race bug — was in package.json but not node_modules +- [Phase 03-operator-experience]: Usage nav links to /usage tenant picker (not hardcoded tenantId) — supports multi-tenant operators +- [Phase 03-operator-experience]: BudgetAlertBadge renders neutral 'No limit set' for null budget_limit_usd — prevents false alarms ### Pending Todos @@ -124,6 +128,6 @@ None yet. ## Session Continuity -Last session: 2026-03-24T03:47:11.918Z -Stopped at: Stopped at checkpoint:human-verify in 03-03-PLAN.md (Task 2) +Last session: 2026-03-24T03:48:23.062Z +Stopped at: Completed 03-04-PLAN.md (checkpoint: awaiting human-verify Task 2) Resume file: None diff --git a/.planning/phases/03-operator-experience/03-04-SUMMARY.md b/.planning/phases/03-operator-experience/03-04-SUMMARY.md new file mode 100644 index 0000000..d57f9ea --- /dev/null +++ b/.planning/phases/03-operator-experience/03-04-SUMMARY.md @@ -0,0 +1,145 @@ +--- +phase: 03-operator-experience +plan: 04 +subsystem: ui +tags: [recharts, react, nextjs, tanstack-query, shadcn, usage, cost-tracking, budget-alerts] + +# Dependency graph +requires: + - phase: 03-operator-experience + plan: 01 + provides: "GET /api/portal/usage/{tenant_id}/summary, by-provider, message-volume, budget-alerts backend endpoints" + +provides: + - Usage dashboard page at /usage/[tenantId] — payroll view answering "how much is this employee costing me?" + - Usage index page at /usage — tenant picker redirecting to per-tenant dashboard + - UsageChart component — Recharts bar chart of total_tokens per agent with tooltip detail + - ProviderCostChart component — horizontal bar chart of cost_usd by LLM provider (openai/anthropic/ollama color-coded) + - MessageVolumeChart component — bar chart of message_count per channel (slack/whatsapp color-coded) + - BudgetAlertBadge component — ok/warning/exceeded status badge for agent budget limits + - TanStack Query hooks: useUsageSummary, useUsageByProvider, useMessageVolume, useBudgetAlerts + - Time range selector (Last 7 days / Last 30 days / This month / Last 3 months) driving all chart queries + - Summary cards showing total cost, total tokens, total messages at top of dashboard + - Usage nav link added to sidebar with BarChart2 icon + +affects: + - future phases adding more chart types or export functionality + - any phase adding billing analytics or cost alerts + +# Tech tracking +tech-stack: + added: + - recharts@2.15.0 (installed — was in package.json but missing from node_modules) + patterns: + - Recharts ResponsiveContainer wrapping BarChart for adaptive sizing + - Channel/provider color maps via Record lookup with fallback gray + - Custom Tooltip components using TooltipProps typing + - Empty state pattern: "No X data for this period" centered in h-[200px] container + - Time range key-to-date-range function returning ISO date strings for query params + +key-files: + created: + - packages/portal/components/budget-alert-badge.tsx + - packages/portal/components/usage-chart.tsx + - packages/portal/components/provider-cost-chart.tsx + - packages/portal/components/message-volume-chart.tsx + - packages/portal/app/(dashboard)/usage/[tenantId]/page.tsx + - packages/portal/app/(dashboard)/usage/page.tsx + modified: + - packages/portal/lib/queries.ts + - packages/portal/components/nav.tsx + +key-decisions: + - "recharts was in package.json but not node_modules — installed with npm install --force due to ENOTEMPTY npm bug" + - "Usage nav links to /usage index (tenant picker) not a hardcoded tenantId — prevents broken nav for operators managing multiple tenants" + - "BudgetAlertBadge renders 'No limit set' (gray, neutral) for null budget_limit_usd — no false alarms" + - "ProviderCostChart uses horizontal BarChart (layout='vertical') so long provider names don't clip on x-axis" + - "getDateRange() computes 'This month' as first day of current month — not relative 30 days, matches calendar intuition" + +patterns-established: + - "Usage chart components follow empty state pattern with h-[200px] centered text" + - "Chart Tooltip components typed with TooltipProps and cast payload as domain interface" + - "Time range selector implemented as native