V1 Web PWA · Surface walkthrough

Tara — analytics dashboard

A per-surface walkthrough of the V1 Web PWA customer surface: layout, states, interactions, data, and cross-references.

walked
9sections4 minread

On this page

Context. surface customer · domain tara · route /domains/tara/analytics · auth signed-in · source apps/oshun/web/src/app/domains/tara/analytics/page.tsx

Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; 2026-06-29 targeted Playwright coverage added for real BFF-backed empty and populated analytics states, auth-hydration retry, range switching, CSV export, chart/title semantics, UTC weekday heatmap labels, reduced-motion CSS, scoped axe scans, and route back-stack. Evidence: apps/oshun/web/e2e/tara-analytics.spec.ts

Purpose#

The Tara analytics surface under /domains/tara/*. It renders the member's real sit-completion analytics from /v1/tara/analytics: minutes, sessions, completion rate, most-practiced sittings, UTC weekday/hour heatmap, and practice rhythm calendar, with a CSV export for the active range. It no longer fabricates seeded-random practice history for members with no data.

Entry points#

  • Tara hub — no current source link from /tara to this route was found in the focused 2026-06-29 pass; treat the hub affordance as an open linkage gap
  • Direct URL / bookmark — yes
  • Domain back-stackrouter.back() is wired into the dashboard's onBack prop (provided by this page wrapper)
  • No middleware-specific gating — the page is a 'use client' wrapper with no route-local auth guard; the BFF analytics endpoint is authenticated

Layout regions#

page.tsx is a 'use client' thin wrapper that renders <TaraAnalyticsDashboard onBack={() => router.back()} />.

Inside TaraAnalyticsDashboard (apps/.../TaraAnalyticsDashboard.tsx):

  • Header / back button — back affordance (onBack) at top-left
  • Summary stat row — Clock / Target / Flame / TrendingUp lucide icons with numeric headline values
  • Meditation minutes bar chart — CSS-driven daily bars derived from the member's real completion rows
  • Session completion ring — SVG donut/ring (stroke-dashoffset animated via tara-dash-ring-fill keyframes)
  • Most practiced sittings — horizontal CSS bars from bySitting
  • Time-of-day heatmap — UTC Sunday-Saturday × 24-hour grid
  • Practice rhythm calendar — daily markers across the active window
  • CSV export action — downloads the visible window of metrics

States#

  • Loaded with real completions — seeded E2E users complete Tara sits via the real /v1/tara/sittings/:id/complete BFF route; the dashboard then reads /v1/tara/analytics and mirrors the same totals, streak, category, heatmap, and daily-point model
  • Auth-hydration retry — dashboard retries the initial unauthenticated no-token race before settling; authenticated users do not get a false empty dashboard from an early 401
  • Empty member/v1/tara/analytics returns hasData: false; the UI renders "No practice yet" instead of fabricated history
  • Empty practice day — zero-minute bars and rhythm cells remain in the generated contiguous range; the populated E2E confirms a real practiced day and exported zero rows around it
  • Window switcher — This week / This month / All time buttons update data-time-range and aria-pressed
  • CSV export success — active range downloads tara-analytics-<range>-<YYYY-MM-DD>.csv with header Date,Minutes,Sessions,Completed,Total
  • Reduced motionprefers-reduced-motion: reduce collapses dashboard animations/transitions; E2E verifies bar animation duration is <= 1ms
  • Auth gate — BFF reads require auth; route-local page guard remains the customer shell/middleware boundary
  • BFF/database failure — failed fetch keeps the honest empty model, but there is no explicit user-facing error state

Interactions#

Header / back#

  • Back (button)
    • Function: calls router.back() (provided as onBack from this page)
    • Aria-label: "Back to previous page"

Charts (interactive)#

  • Bar / cell hover titles — minute bars and heatmap cells expose native title text with date/hour and real minutes/session counts
  • Window selector — This week / This month / All time segmented buttons update the active range
  • CSV export (Download icon button) — triggers a CSV file download of the active window
  • Keyboard tooltip alternative — chart titles are native hover text, not a focusable disclosure pattern

Data & contracts#

  • Reads: BFF GET /v1/tara/analytics
    • Source table: real sit completions recorded by POST /v1/tara/sittings/:id/complete
    • Model builder: apps/oshun/bff/src/tara/analytics.ts
    • UI mapping: daily, bySitting, and weekdayHour
  • Writes: no server writes from the dashboard; CSV export writes a local browser download only
  • Realtime: None.
  • Caching: BFF replies cache-control: no-store; page is a client component
  • Auth/role check: BFF collectionsAuthGuard plus customer shell/middleware
  • Telemetry: None observed in this view.

Current E2E evidence#

  • apps/oshun/web/e2e/tara-analytics.spec.ts creates fresh signed-in users, reads /v1/tara/analytics directly, and verifies hasData: false renders the empty state with no stat cards.
  • The same spec records three real sit completions through /v1/tara/sittings/:id/complete, re-reads /v1/tara/analytics, and proves the browser dashboard matches the returned totals: 27 minutes, 3 sessions, 1-day rhythm, 100% completion, practiced day, per-sitting category rows, and weekday/hour heatmap cell.
  • It verifies range selection (This week), CSV download filename and content, reduced-motion animation duration, minute/heatmap title semantics, scoped axe scans for empty and populated states, and route-header back navigation.

Cross-references#

Open questions / known gaps#

  • Dashboard reads from real /v1/tara/analytics; seeded-random dashboard history has been removed.
  • CSV export contract documented and tested: Date,Minutes,Sessions,Completed,Total
  • Confirm the relationship between /domains/tara/analytics and the polished /tara surface — source search found no current hub link
  • Decide whether BFF/database failures should render an explicit error panel instead of the same honest empty state
  • Decide whether chart hover titles need a keyboard-accessible tooltip or data-table alternative