Skip to content

feat: integration audit cleanups (single-step signup, TTS locale, dead-param scrub) - #8

Merged
joaocarvoli merged 7 commits into
mainfrom
feat/integration-audit-fixes
May 18, 2026
Merged

feat: integration audit cleanups (single-step signup, TTS locale, dead-param scrub)#8
joaocarvoli merged 7 commits into
mainfrom
feat/integration-audit-fixes

Conversation

@joaocarvoli

Copy link
Copy Markdown
Member

Summary

Integration audit of translation-helper-ui + tripod-backend paired against the legacy translation-helper/ app. This is the frontend side.

  • feat(auth): Signup was a two-step form; Step 2 collected organization, role, avatar — but the submit handler only shipped {email, password, display_name}. Backend User has nowhere to persist the rest. Reduced to a single step with the fields the backend actually consumes.
  • feat(chat): /audio/speak now receives language_code from the UI's current locale. Backend langdetect needed ≥12 chars; short replies were flipping to English playback even in pt-BR/es/fr sessions.
  • chore(api): sync AgentInfo and TranscribeResponse types with the slimmed-down backend (no more short/icon/starters/duration_sec).
  • chore: extract TH_APP_KEY constant (was hardcoded 3×), simplify SSE error parse path in streamChatMessage, derive rotateAgent's ID list from AGENTS instead of a duplicate hardcoded array.

Backend companion PR: https://github.com/shemaobt/tripod-api/pull/new/feat/translation-helper-audit

Test plan

  • npm run build (tsc + Vite) green
  • npm run lint — 0 errors (7 pre-existing warnings unchanged)
  • Manual: sign up a fresh user → confirm single-step form → confirm access request created → admin approves in tripod-console → log back in → can chat
  • Manual: switch UI to pt-BR, click Listen on a short assistant reply → playback in Portuguese (was English)
  • Manual: trigger an SSE error (e.g. backend down mid-stream) → toast surfaces backend's error message rather than generic "Streaming error"

🤖 Generated with Claude Code

joaocarvoli and others added 7 commits May 17, 2026 14:04
Signup was a two-step form: Step 1 (name + email + password) → Step 2
(organization, role select, avatar). But the submit handler only
shipped {email, password, display_name}; organization, role, and
avatar were silently dropped, and the backend User model has no
fields for them today.

Reduce to single-step (name + email + password). Removes the unused
RoleOptionKey type and ROLE_OPTION_KEYS export from agents.ts. If
these fields are needed later we can add them back together with the
backend schema, instead of asking users to fill them into the void.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The /audio/speak endpoint runs langdetect when language_code is
absent, but its 0.85 confidence threshold + 12-char minimum mean that
short replies (the typical Listen target) flop to the en-US fallback.
The UI already knows the locale — pass it.

Also drops the unused voice_name plumbing (no UI surface ever set it).

ttsLanguageCode() maps our i18n locales (en, pt-BR, es, fr) to the
BCP-47 codes the backend's VOICE_MAP understands.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
GET /api/translation-helper/agents now returns only id/name/description/
prompt_version (icons/shorts/starters were never read off the response
— they live in agents.ts because they need i18n). Mirror that on the
type. Same for duration_sec, which the backend never populated.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The literal 'translation-helper' was hardcoded in three places. Move
it to src/lib/constants.ts so future apps (or a rename) only have to
edit one site.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Previous code wrapped the throw inside the JSON.parse try/catch, then
re-threw from the catch — works, but the control flow is hard to
follow. Parse the JSON first, then throw outside the try.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
useChat hardcoded ['storyteller', 'conversation', 'oral', 'health',
'backtrans'] alongside the AGENTS array — drift the moment a new
agent lands. Export AGENT_IDS from agents.ts and use it.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Gemini outputs markdown (**bold**, headings, lists, etc.) but
AssistantMessage was rendering the content as raw text — readers saw
the literal asterisks instead of formatted output (see screenshot).

Adds a small dependency-free markdown renderer (MarkdownContent) that
handles headings, paragraphs, bold, italic, lists (ul/ol),
blockquotes, code blocks, inline code, links, and horizontal rules.
Stream-safe: unclosed **bold leaves the literal characters in place
until the closing pair arrives.

AssistantMessage runs the renderer only when children is a string, so
user messages and the streaming indicator are unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@joaocarvoli
joaocarvoli merged commit 014b75d into main May 18, 2026
2 checks passed
@joaocarvoli
joaocarvoli deleted the feat/integration-audit-fixes branch May 18, 2026 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant