# 05 — Web App (Next.js) Map > Surface: `apps/web` > Stack: Next.js 15 App Router + React 19 + MUI (via `@d3ro/ui`) + Supabase > Role: cloud console; the reference surface for server-shared data UX --- ## 1. Route tree (`src/app/`) Root layout: `ThemeProvider → I18nProvider → AuthProvider`. | Route | Type | Feature | |---|---|---| | `/` | server | Redirects: session → `/dashboard`, else `/login` (also `/login` when Supabase unconfigured) | | `/login` | client | OAuth (Google/GitHub/Apple) + email/password | | `/accept-invite` | client | Team invite acceptance (`?token=` → `team-accept`); stores pending token if logged out | | `/download` | client | Download center + release history; desktop installers marked "release pending"; client SHA-256 verify tool | | `/releases` | server | Re-exports `/download` | | `/auth/callback` | route handler | OAuth code → session exchange | | `(app)/record` | server | `` real-time record/STT | | `(app)/commands` | client | Custom instruction CRUD/reorder/activate/execute | | `(app)/dashboard` | client | Stats (sessions, time, words, streak), tier, recent history | | `(app)/actions` | server | NL command → LLM parse → action (``) | | `(app)/meetings` | server | Meetings list | | `(app)/meetings/[id]` | server | Meeting detail: audio player, live transcript (Realtime), memos, generated docs | | `(app)/knowledge` | server | RAG doc list + add + semantic search (search "planned V2-M+1") | | `(app)/teams` | server | Teams list + create | | `(app)/teams/[id]` | server | Team detail: members, owner-only invite, team meetings | | `(app)/chat` | server | Talk AI chat (``) | | `(app)/dictionary` | client | Pronunciation dictionary CRUD | | `(app)/history` | client | History list: search, favorites, pagination, copy/delete | | `(app)/history/[id]` | client | History detail: edit title/original/polished, favorite, delete | | `(app)/billing` | client | Plans + Payple/Stripe checkout, manage/portal | `(app)/layout.tsx` is the auth guard + shared ``. --- ## 2. Components (`src/components/`) | Group | Components | |---|---| | `actions/` | `action-runner.tsx` (LLM parse → action: create_meeting/search_knowledge/create_memo/send_team_invite) | | `record/` | `mic-recorder.tsx` (MediaRecorder + level analyser → `transcribeWebAudio`) | | `dashboard/` | `meetings-trend-chart.tsx` (recharts) | | `billing/` | `billing-checkout-options`, `checkout-button` (Stripe), `payple-checkout-button`, `payple-client`, `payple-manage-button`, `portal-button` | | `meetings/` | `document-editor`, `generate-document-button`, `live-transcript-list` (Realtime), `markdown-preview` (Mermaid), `meeting-audio-player` (signed URL), `memo-form` | | `chat/` | `chat-panel.tsx` | | `teams/` | `create-team-form`, `invite-member-form`, `activity-feed` (team notes + realtime) | | `knowledge/` | `add-knowledge-form` (text or `.txt`/`.md` file, newline-aware chunking, `embed-chunks` on submit), `knowledge-search` (semantic via `search-knowledge`) | | `layout/` | `sidebar.tsx` (nav, theme selector, logout, i18n) | | `providers/` | `auth-provider`, `i18n-provider`, `theme-mode-context`, `theme-provider` | --- ## 3. Clients (`src/lib/`) | File | Purpose | |---|---| | `billing-catalog.ts` | Parse/validate billing catalog (schema v1, pro/pro_plus, Payple/Stripe prices) | | `command-client.ts` | Custom instruction client (types, error codes, execute) | | `dashboard-client.ts` | Dashboard snapshot loader | | `dictionary-client.ts` | Dictionary CRUD/pagination/search + `serializeDictionary` / `parseDictionaryFile` / `importDictionaryFile` (JSON/CSV) | | `history-client.ts` | History list/get/update/delete, revision-safe | | `supabase-browser.ts` | Re-export `@d3ro/api-client/supabase-browser` | | `supabase-server.ts` | Next `cookies()` wrapper | | `web-stt-client.ts` | Web STT via `stt-proxy`, 25 MB limit, `WebSttError` codes | --- ## 4. Tests Playwright specs in `apps/web/e2e/`: billing, payple-checkout, dashboard-dictionary-commands, history, web-stt-client, smoke. --- ## 5. Web status summary - Full App Router console: auth (email + OAuth), record/STT, history (list+detail), commands, actions, meetings (list+detail+docs), knowledge (add+search), teams (list+detail+invite), chat, dictionary, billing, download/releases. - Backed by Supabase tables + Edge Functions (`stt-proxy`, `llm-proxy`, `team-invite`, `team-accept`, `stripe-checkout`, `payple-checkout`, `payple-manage`, `search-knowledge`, `generate-meeting-document`). - No literal `TODO`/`FIXME` markers; remaining smaller items (see [`11-gap-backlog.md`](./11-gap-backlog.md) `WEB-*`): - Teams `member_count` is `0` in MVP (separate query needed) — `teams/page.tsx`. - Action runner team-invite uses a manual redirect safety path instead of a live invite (`action-runner.tsx`). - `/download` shows "artifact not yet published" for the current desktop release. - Knowledge file upload, semantic search, dictionary import/export, and the team activity feed are now implemented (`[x]` in the catalog).