V1 Web PWA · Surface walkthrough

Tara — search

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

walked
9sections3 minread

On this page

Context. surface customer · domain tara · route /domains/tara/search · auth signed-in · source apps/oshun/web/src/app/domains/tara/search/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-28 focused automated walk (Playwright + real dev infra) — idle, recent-memory, debounce/loading, synonym expansion, spelling suggestion, empty result, reduced-motion CSS, back navigation, Enter persistence, clear/remove controls, and routed course/teacher/collection result opens verified. Evidence: apps/oshun/web/e2e/tara-scoped-search.spec.ts

Purpose#

A Tara-scoped full-text search that complements the shell-wide /search view. Searches inside the Tara content set with debounced input, spelling suggestions ("Did you mean…?"), highlighted snippets, trending queries, recent-query memory, and result sections for Meditations / Courses / Teachers / Collections.

Entry points#

  • Tara hub — verify the search affordance on /tara that links here
  • Direct URL / bookmark — yes
  • Domain back-stackrouter.back() wired into onBack

Layout regions#

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

Inside TaraSearchEngine (TaraSearchEngine.tsx):

  • Header — back button + Search icon header
  • Search input — text input with DEBOUNCE_MS = 250, clear button (×)
  • Spelling suggestion banner — "Did you mean …?" when SpellingSuggestion is produced
  • Trending searchesTrendingSearch[] chips (up / stable / new indicators)
  • Recent searches — from localStorage['tara-recent-searches'] (max MAX_RECENT_SEARCHES = 10)
  • Result sections — Meditations / Courses / Teachers / Collections, each with highlighted matches (SEARCH_STYLES tse-highlight-pulse keyframe, disabled under prefers-reduced-motion: reduce)
  • Empty / loading / error statesLoader2 spinner, AlertCircle error, empty-query landing

States#

  • Idle (no query) — trending + recent searches visible; no result sections
  • Typing (debounce)Loader2 spinner; shimmer skeleton via tse-shimmer keyframe
  • Results populated — sections render in declared order
  • Spelling suggestion — banner offers a corrected query; tapping it replaces the input
  • Empty result — landing copy advising to try different keywords
  • Error state — no implemented runtime error branch exists in TaraSearchEngine; AlertCircle is used for spelling suggestions, not a failed-search error
  • Recent persisted — query strings stored in localStorage['tara-recent-searches']
  • Synonym expansionSYNONYM_MAP expands terms (meditation, mindfulness, session, practice, …) — verify hits are highlighted

Interactions#

  • Back (button) — router.back() via onBack

Search input#

  • Input (text)
    • Function: updates query; 250 ms debounce before computing results
  • Clear (×) (button) — clears query
  • Submit on Enter — persists the current query to recent searches; results still follow the 250 ms debounce

Spelling suggestion banner#

  • Apply suggestion — replaces query with suggested string
  • Chip click — populates query

Recent chip#

  • Chip click — populates query
  • Clear recent — "Clear all" empties localStorage['tara-recent-searches']

Result row (per section)#

  • Open — meditation — search IDs (med-001med-012) still do not map to a real Tara sitting/player route, so rows expose no href
  • Open — coursecrs-001crs-006 map to /domains/tara/courses/tara-course-001/domains/tara/courses/tara-course-006
  • Open — teachertch-001tch-006 map to /domains/tara/teachers/tara-teacher-001/domains/tara/teachers/tara-teacher-006
  • Open — collection — collection rows map to /domains/tara/collections?collection=<id>
  • Highlighted match spantse-highlight-pulse keyframe; honors reduced motion (verify)

Data & contracts#

  • Reads:
    • Tara fixture data (@/lib/tara/tara-simulation-data)
    • localStorage['tara-recent-searches']
  • Writes:
    • localStorage['tara-recent-searches'] — bounded to 10 entries
  • Realtime: None.
  • Caching: client-only
  • Auth/role check: shell middleware
  • Telemetry: None observed in this view.

Automation Evidence#

  • apps/oshun/web/e2e/tara-scoped-search.spec.ts
    • walks idle, recent-memory, debounce, synonym, suggestion, empty, and reduced-motion states
    • routes mapped result rows into real Tara destination pages and preserves the back affordance
  • apps/oshun/web/src/components/domains/tara/TaraSearchEngine.tsx
    • stable data-tara-search-* hooks for states, controls, result sections, rows, route hrefs, and reduced-motion assertions

Cross-references#

Open questions / known gaps#

  • Confirm whether /domains/tara/search should route through the same /v1/search?domain=tara BFF endpoint that /search uses, or remain a local fixture-driven engine
  • Trending-search calculation is hard-coded in TRENDING_SEARCHES; no BFF trending endpoint is read by this route
  • Reduced-motion handling is covered for highlighted matches and animated search rows via prefers-reduced-motion: reduce
  • Tara-scoped recents intentionally use tara-recent-searches; shell-wide search continues to use oshun-search-recent-v1
  • Meditation results need a canonical player-route mapping before their row click can open a real destination