Spaces:
Sleeping
Sleeping
frontend/ β Next.js 14 (App Router) UI
The chat UI, profile builder, scorecard, and admin panel. Single-page-ish β almost everything lives in src/app/page.tsx with src/lib/ carrying the API client, the EN β ΰ€Ήΰ€Ώΰ€ i18n table, and the live-conversation hook.
For Claude / agent-specific rules (e.g. the "this is NOT the Next.js you know" note) see AGENTS.md in this folder β CLAUDE.md is an alias of it.
Entry points
| File | Role |
|---|---|
src/app/page.tsx |
The chat surface. Hosts the Message component (which mounts the in-DOM <audio> element for TTS), the toolbar (Live toggle + push-to-talk), the tab switcher (Chat / Profile Builder / Scorecard / Admin), and every view's render. |
src/app/layout.tsx |
Root layout + font wiring (Geist via next/font). |
src/app/globals.css |
Tailwind v4 entrypoint + the shadcn/ui token layer (ADR-013). |
src/lib/api.ts |
Typed API client. Generated types via openapi-typescript from the FastAPI OpenAPI schema (ADR-015). |
src/lib/useLiveConversation.ts |
The continuously-open-mic VAD hook that powers Live mode + barge-in. State persists in localStorage.insurance_live_pref (ADR-028). |
src/lib/useStreamingVoice.ts |
KI-168 hybrid voice capture. Runs Web Speech API (interim transcripts streamed live to the chat input) and MediaRecorder (authoritative audio blob) in parallel; on browser silence-detect the blob is POSTed to /api/transcribe (Sarvam Saarika STT). Auto-submits the Sarvam transcript; falls back to the Web Speech transcript only if Sarvam errors. KI-173 heartbeat + KI-174 visibilitychange / focus revival hooks keep the mic alive across tab / app switches. |
src/lib/i18n.ts |
EN β ΰ€Ήΰ€Ώΰ€ strings + the 13-term GLOSSARY mirrored to kb/methodology/glossary.json. |
Voice UX invariants (ADR-028)
- One default voice mode + one fallback. Live mode is the default; the toolbar pill toggles it (green = on, red = off). The π€ push-to-talk button suspends Live for one turn β captures with VAD silence-cutoff β resumes Live if the user preference is still on.
- Hands-free mode was removed in KI-027. Any reference to it in code or docs is stale.
- Hybrid capture (KI-168). Web Speech API drives the live interim transcript on the chat input;
MediaRecordercaptures the authoritative blob in parallel. On browser silence-detect the blob is POSTed to/api/transcribe(Sarvam) for the authoritative transcript; Web Speech is the fallback only if Sarvam errors. Seesrc/lib/useStreamingVoice.ts. - Mic survives tab / app switches (KI-173 / KI-174). Heartbeat keeps the mic stream alive while the tab is backgrounded;
visibilitychange/focusrevival hooks reattach the mic on tab return. - Bot TTS plays via the in-DOM
<audio>element insideMessage(autoplay-on-mount via ref'duseEffect). Never usenew Audio(url).play()β those detached instances are invisible to thedocument.querySelectorAll("audio").pause()call in the barge-in handler, so they keep playing under the user's speech.
Tooling
| Concern | Where |
|---|---|
| Build / dev / lint | package.json scripts (dev, build, lint). |
| Lint config | eslint.config.mjs. |
| TS config | tsconfig.json. |
| Postcss / Tailwind | postcss.config.mjs. |
| Next config | next.config.ts. |
| Static assets | public/. |
Develop locally
cd frontend
npm install # or pnpm / bun
npm run dev # localhost:3000 β points at the FastAPI on :8000 by default
Point at a different backend with NEXT_PUBLIC_BACKEND_URL=... (see src/lib/api.ts).