-
Notifications
You must be signed in to change notification settings - Fork 17
ECHO-620 add Italian language support in the app #399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis PR adds Italian (it-IT) language support comprehensively across frontend and backend systems, including locale configurations, UI translations, onboarding cards, dynamic language validation, and Italian-language prompt templates for transcription and conversation processing. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~40 minutes
Possibly related PRs
Suggested labels
LGTM — solid, comprehensive language-support addition. The pattern consistency across all the locale mappings and template files shows discipline; dynamic language validation beats hard-coded lists. Only thing to eyeball: make sure the it-IT.ts translation payload isn't missing any keys that other locales have. 🚀 Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
echo/frontend/src/components/project/ProjectQRCode.tsx (1)
31-58: Optional: add a defensive fallback for unknownproject.languagevalues.Right now, if
project.languageisn’t one of the mapped keys,languageCodeends upundefinedand the share URL becomes.../undefined/.... Since you’re touching this map anyway, you can cheaply harden it:- const languageCode = { + const languageCode = { de: "de-DE", "de-DE": "de-DE", en: "en-US", "en-US": "en-US", es: "es-ES", "es-ES": "es-ES", fr: "fr-FR", "fr-FR": "fr-FR", it: "it-IT", "it-IT": "it-IT", nl: "nl-NL", "nl-NL": "nl-NL", - }[ - project.language as - | "en" - | "nl" - | "de" - | "fr" - | "es" - | "it" - | "en-US" - | "nl-NL" - | "de-DE" - | "fr-FR" - | "es-ES" - | "it-IT" - ]; + }[ + project.language as + | "en" + | "nl" + | "de" + | "fr" + | "es" + | "it" + | "en-US" + | "nl-NL" + | "de-DE" + | "fr-FR" + | "es-ES" + | "it-IT" + ] ?? "en-US";Keeps existing behavior for known languages and avoids
/undefined/if something unexpected slips through.echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx (1)
35-42: Italian topic locale is wired; dates are still English-only if you care to go further.Adding
it: "it-IT"keeps locale selection consistent with the rest of the verification stack and lets Italian topic labels resolve correctly. If you ever want fully localized timestamps too, consider routingformatArtefactTimethrough a locale-aware formatter (or this same mapping) so the “Approved …” date string also respects Italian.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (33)
echo/frontend/lingui.config.ts(1 hunks)echo/frontend/src/components/announcement/utils/dateUtils.ts(2 hunks)echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx(1 hunks)echo/frontend/src/components/language/LanguagePicker.tsx(1 hunks)echo/frontend/src/components/layout/Header.tsx(2 hunks)echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx(1 hunks)echo/frontend/src/components/participant/hooks/useOnboardingCards.ts(3 hunks)echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx(1 hunks)echo/frontend/src/components/participant/verify/VerifySelection.tsx(1 hunks)echo/frontend/src/components/project/ProjectPortalEditor.tsx(2 hunks)echo/frontend/src/components/project/ProjectQRCode.tsx(2 hunks)echo/frontend/src/config.ts(1 hunks)echo/frontend/src/hooks/useLanguage.ts(1 hunks)echo/frontend/src/locales/de-DE.po(60 hunks)echo/frontend/src/locales/en-US.po(61 hunks)echo/frontend/src/locales/es-ES.po(60 hunks)echo/frontend/src/locales/fr-FR.po(60 hunks)echo/frontend/src/locales/it-IT.ts(1 hunks)echo/frontend/src/locales/nl-NL.po(62 hunks)echo/server/dembrane/api/project.py(2 hunks)echo/server/dembrane/seed.py(7 hunks)echo/server/dembrane/service/project.py(1 hunks)echo/server/dembrane/transcribe.py(2 hunks)echo/server/prompt_templates/context_conversations.it.jinja(1 hunks)echo/server/prompt_templates/default_whisper_prompt.it.jinja(1 hunks)echo/server/prompt_templates/generate_conversation_summary.it.jinja(1 hunks)echo/server/prompt_templates/get_reply_brainstorm.it.jinja(1 hunks)echo/server/prompt_templates/get_reply_summarize.it.jinja(1 hunks)echo/server/prompt_templates/get_reply_system.it.jinja(1 hunks)echo/server/prompt_templates/summary.it.jinja(1 hunks)echo/server/prompt_templates/system_chat.it.jinja(1 hunks)echo/server/prompt_templates/system_report.it.jinja(1 hunks)echo/server/prompt_templates/translate_transcription.it.jinja(1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
echo/frontend/**/src/{routes,components}/**/*.tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
echo/frontend/**/src/{routes,components}/**/*.tsx: Compose Mantine primitives (Stack,Group,ActionIcon, etc.) while layering Tailwind utility classes viaclassName, alongside toast feedback via@/components/common/Toaster
For Tailwind classes that need dynamic values, replace with inlinestyleprops using CSS variables instead of hardcoded hex values
Files:
echo/frontend/src/components/project/ProjectQRCode.tsxecho/frontend/src/components/layout/Header.tsxecho/frontend/src/components/participant/ParticipantOnboardingCards.tsxecho/frontend/src/components/participant/verify/VerifiedArtefactsList.tsxecho/frontend/src/components/participant/verify/VerifySelection.tsxecho/frontend/src/components/language/LanguagePicker.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/project/ProjectPortalEditor.tsx
echo/frontend/**/src/**/*.{css,tsx,ts}
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
Use CSS variables
var(--app-background)andvar(--app-text)instead of hardcoded colors like#F6F4F1or#2D2D2Cto ensure theme changes propagate
Files:
echo/frontend/src/components/project/ProjectQRCode.tsxecho/frontend/src/components/announcement/utils/dateUtils.tsecho/frontend/src/hooks/useLanguage.tsecho/frontend/src/components/layout/Header.tsxecho/frontend/src/components/participant/ParticipantOnboardingCards.tsxecho/frontend/src/components/participant/verify/VerifiedArtefactsList.tsxecho/frontend/src/components/participant/verify/VerifySelection.tsxecho/frontend/src/components/language/LanguagePicker.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/locales/it-IT.tsecho/frontend/src/components/project/ProjectPortalEditor.tsxecho/frontend/src/components/participant/hooks/useOnboardingCards.tsecho/frontend/src/config.ts
echo/frontend/**/src/{theme.tsx,components,routes}/**/*.tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
When adding new Mantine components, reference the global Mantine theme in
src/theme.tsxwith customprimarycolor palette and component defaults, preferring CSS variables in styles over hardcoded hex values
Files:
echo/frontend/src/components/project/ProjectQRCode.tsxecho/frontend/src/components/layout/Header.tsxecho/frontend/src/components/participant/ParticipantOnboardingCards.tsxecho/frontend/src/components/participant/verify/VerifiedArtefactsList.tsxecho/frontend/src/components/participant/verify/VerifySelection.tsxecho/frontend/src/components/language/LanguagePicker.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/project/ProjectPortalEditor.tsx
echo/frontend/**/src/{components,routes}/**/*.tsx
📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)
UI mutations should surface inline feedback: pair toasts with contextual Mantine
Alertcomponents inside modals/forms for errors or warnings
Files:
echo/frontend/src/components/project/ProjectQRCode.tsxecho/frontend/src/components/layout/Header.tsxecho/frontend/src/components/participant/ParticipantOnboardingCards.tsxecho/frontend/src/components/participant/verify/VerifiedArtefactsList.tsxecho/frontend/src/components/participant/verify/VerifySelection.tsxecho/frontend/src/components/language/LanguagePicker.tsxecho/frontend/src/components/conversation/VerifiedArtefactsSection.tsxecho/frontend/src/components/project/ProjectPortalEditor.tsx
echo/server/dembrane/**/*.py
📄 CodeRabbit inference engine (echo/.cursor/rules/async-threadpool.mdc)
echo/server/dembrane/**/*.py: Always wrap blocking I/O calls usingrun_in_thread_poolfromdembrane.async_helpersin backend code. Wrap calls todirectus.*,conversation_service.*,project_service.*, S3 helpers, and CPU-heavy utilities like token counting or summary generation if they are sync. Do not wrap already-async functions or LightRAG calls (e.g.,rag.aquery,rag.ainsert).
Prefer converting endpoints toasync defandawaitresults rather than using synchronous functions
echo/server/dembrane/**/*.py: Config changes live indembrane/settings.py; add new env vars as fields onAppSettings, expose grouped accessors (e.g.,feature_flags,directus) if multiple modules read them, and fetch config at runtime withsettings = get_settings()—never import env vars directly
Embeddings usesettings.embedding; populateEMBEDDING_*env vars (model, key/base URL/version) before callingdembrane.embedding.embed_text
Files:
echo/server/dembrane/service/project.pyecho/server/dembrane/seed.pyecho/server/dembrane/api/project.pyecho/server/dembrane/transcribe.py
echo/server/dembrane/{api,service}/**/*.py
📄 CodeRabbit inference engine (echo/server/AGENTS.md)
For API handlers, favor Directus queries over raw SQLAlchemy sessions when reading project/conversation data to keep behavior consistent with the admin console
Files:
echo/server/dembrane/service/project.pyecho/server/dembrane/api/project.py
echo/server/dembrane/{tasks,api/**/*.py}
📄 CodeRabbit inference engine (echo/server/AGENTS.md)
When a Dramatiq actor needs to invoke an async FastAPI handler (e.g.,
dembrane.api.conversation.summarize_conversation), run the coroutine viarun_async_in_new_loopfromdembrane.async_helpersinstead of calling it directly or withasyncio.runto avoid clashing with nested event loops
Files:
echo/server/dembrane/api/project.py
echo/server/dembrane/transcribe.py
📄 CodeRabbit inference engine (echo/server/AGENTS.md)
Replace polling with webhook approach (TODO in
dembrane/transcribe.py:179)
Files:
echo/server/dembrane/transcribe.py
echo/server/dembrane/{tasks,transcribe}.py
📄 CodeRabbit inference engine (echo/server/AGENTS.md)
S3 audio paths used in verification/transcription flows should be loaded via the shared file service (
_get_audio_file_object) so Gemini always receives fresh bytes—signed URLs may expire mid-request
Files:
echo/server/dembrane/transcribe.py
🧠 Learnings (16)
📓 Common learnings
Learnt from: ussaama
Repo: Dembrane/echo PR: 205
File: echo/frontend/src/lib/query.ts:1444-1506
Timestamp: 2025-07-10T12:48:20.683Z
Learning: ussaama prefers string concatenation over template literals for simple cases where readability is clearer, even when linting tools suggest template literals. Human readability takes precedence over strict linting rules in straightforward concatenation scenarios.
📚 Learning: 2025-12-05T00:33:58.885Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/server/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:58.885Z
Learning: Applies to echo/server/dembrane/api/chat.py : Fill module stub, add RAG shortcut when quotes exist, implement Directus project fetch, conversation endpoint completion, admin auth checks (TODOs in `dembrane/api/chat.py`)
Applied to files:
echo/server/prompt_templates/generate_conversation_summary.it.jinja
📚 Learning: 2025-08-13T14:08:51.893Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 265
File: echo/server/prompt_templates/context_conversations.de.jinja:9-10
Timestamp: 2025-08-13T14:08:51.893Z
Learning: In the conversation data structure (echo/server/prompt_templates), conversation.created_at and conversation.duration fields always exist and are never None, so conditional rendering checks are not needed in Jinja templates.
Applied to files:
echo/server/prompt_templates/generate_conversation_summary.it.jinjaecho/server/prompt_templates/context_conversations.it.jinja
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/settings/**/*.tsx : Provide ergonomic navigation in settings-like routes: breadcrumb + back action (ActionIcon + navigate(-1)) with relevant iconography is the default
Applied to files:
echo/frontend/src/components/layout/Header.tsxecho/frontend/src/locales/fr-FR.poecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.poecho/frontend/src/locales/nl-NL.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/**/*.tsx : Use Lingui macros `t` from `lingui/core/macro` and `Trans` from `lingui/react/macro` for localizing UI strings in routed screens
Applied to files:
echo/frontend/src/components/layout/Header.tsxecho/frontend/src/locales/it-IT.tsecho/frontend/src/locales/fr-FR.poecho/frontend/lingui.config.tsecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.poecho/frontend/src/locales/nl-NL.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/auth/**/*.tsx : Auth surfaces reuse `HeaderView` by passing `isAuthenticated`/`loading` props—avoid rolling bespoke headers inside layouts
Applied to files:
echo/frontend/src/components/layout/Header.tsx
📚 Learning: 2025-08-19T10:14:31.647Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 266
File: echo/frontend/src/components/chat/ChatAccordion.tsx:214-221
Timestamp: 2025-08-19T10:14:31.647Z
Learning: In the Echo frontend codebase using Lingui, i18n IDs in Trans components (e.g., `<Trans id="any.string.here">`) can be arbitrary strings and don't need to follow specific naming conventions. They are just references used in .po files, and the actual translations need to be manually defined in the locale files.
Applied to files:
echo/frontend/src/locales/it-IT.tsecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.po
📚 Learning: 2025-10-28T13:47:02.926Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 350
File: echo/frontend/src/components/participant/ParticipantConversationText.tsx:82-85
Timestamp: 2025-10-28T13:47:02.926Z
Learning: In text mode (echo/frontend/src/components/participant/ParticipantConversationText.tsx), participants only submit PORTAL_TEXT chunks (no audio). The “Finish” button is shown only after at least one text message is saved to Directus.
Applied to files:
echo/frontend/src/locales/it-IT.tsecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.poecho/frontend/src/locales/nl-NL.po
📚 Learning: 2025-07-10T12:47:06.269Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 205
File: echo/frontend/src/locales/nl-NL.po:1246-1247
Timestamp: 2025-07-10T12:47:06.269Z
Learning: .po files (gettext internationalization files) are auto-generated by i18n tools like lingui/cli and should not be manually edited. The format of component paths and line numbers in these files is determined by the tool configuration, not manually written. Do not suggest manual edits to .po files.
Applied to files:
echo/frontend/src/locales/fr-FR.poecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.poecho/frontend/src/locales/nl-NL.po
📚 Learning: 2025-05-30T15:37:46.279Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/locales/fr-FR.po:1298-1301
Timestamp: 2025-05-30T15:37:46.279Z
Learning: In French localization files, UI terms like "Portail" should maintain their proper capitalization according to French language conventions, even if it appears inconsistent with lowercase usage in other translations. French capitalization rules for UI terms should be respected over assumed consistency patterns.
Applied to files:
echo/frontend/src/locales/fr-FR.po
📚 Learning: 2025-05-30T15:36:40.131Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/locales/fr-FR.po:521-523
Timestamp: 2025-05-30T15:36:40.131Z
Learning: In the French localization file (fr-FR.po), "Dembrane Echo" is intentionally translated as "Echo Dembrane" for better French language flow and natural sound. This is not an error but a deliberate localization choice.
Applied to files:
echo/frontend/src/locales/fr-FR.po
📚 Learning: 2025-05-30T15:38:44.413Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/components/project/ProjectPortalEditor.tsx:409-464
Timestamp: 2025-05-30T15:38:44.413Z
Learning: Badge-based selectors in ProjectPortalEditor.tsx: Keyboard navigation enhancements for accessibility are considered optional improvements rather than critical issues. The user acknowledges these suggestions but doesn't prioritize them as blockers.
Applied to files:
echo/frontend/src/locales/fr-FR.poecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.poecho/frontend/src/locales/nl-NL.po
📚 Learning: 2025-08-08T10:39:31.114Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 259
File: echo/frontend/src/components/layout/ParticipantLayout.tsx:33-33
Timestamp: 2025-08-08T10:39:31.114Z
Learning: In echo/frontend/src/components/layout/ParticipantLayout.tsx, prefer using simple pathname.includes("start") and pathname.includes("finish") to control the settings button visibility. No need to switch to segment-based matching or add a useEffect to auto-close the modal for these routes, per ussaama’s preference in PR #259.
Applied to files:
echo/frontend/src/locales/fr-FR.poecho/frontend/src/locales/es-ES.poecho/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.poecho/frontend/src/locales/nl-NL.po
📚 Learning: 2025-09-16T08:34:38.109Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 293
File: echo/frontend/src/components/chat/ChatTemplatesMenu.tsx:15-16
Timestamp: 2025-09-16T08:34:38.109Z
Learning: In ChatTemplatesMenu.tsx, titles are preferred over IDs for template selection logic since titles are unique one-liners and work effectively as identifiers. IDs were added primarily for better list rendering rather than selection purposes.
Applied to files:
echo/frontend/src/locales/de-DE.poecho/frontend/src/locales/en-US.po
📚 Learning: 2025-12-05T00:33:58.885Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/server/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:58.885Z
Learning: Applies to echo/server/dembrane/transcribe.py : Replace polling with webhook approach (TODO in `dembrane/transcribe.py:179`)
Applied to files:
echo/server/dembrane/transcribe.py
📚 Learning: 2025-06-06T05:43:44.935Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 180
File: echo/frontend/src/locales/es-ES.ts:1-1
Timestamp: 2025-06-06T05:43:44.935Z
Learning: When users indicate they have already addressed translation issues in locale files, verify the current state before assuming the issue persists. Translation files are often updated in bulk and previously flagged English text may have been properly localized.
Applied to files:
echo/frontend/src/locales/en-US.po
🧬 Code graph analysis (2)
echo/server/dembrane/api/project.py (1)
echo/server/dembrane/service/project.py (1)
get_allowed_languages(10-12)
echo/server/dembrane/transcribe.py (2)
echo/server/tests/service/test_conversation_service.py (1)
project(21-30)echo/server/dembrane/service/project.py (1)
get_allowed_languages(10-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ci-check-server
🔇 Additional comments (36)
echo/server/prompt_templates/default_whisper_prompt.it.jinja (1)
1-1: Italian whisper prompt is clean and production-readySimple, natural Italian, no variables, no Jinja gotchas. Zero surface area for bugs here. LGTM.
echo/server/prompt_templates/translate_transcription.it.jinja (1)
1-5: Translation instructions and Jinja bindings look solidVariables are wired cleanly, the Italian copy clearly forbids summarizing/omitting content, and the “return only translated text” constraint is explicit. This will behave exactly like the other locale prompts. LGTM.
echo/server/prompt_templates/get_reply_system.it.jinja (1)
1-30: System reply prompt is a faithful Italian portContext sections, placeholder tags, and final behavioral instructions (1–3 sentences, “noi/nostro”, acknowledge uncertainty) are all present and coherent in Italian. No structural issues in the Jinja, so this should drop in cleanly alongside the other locales. LGTM.
echo/server/prompt_templates/context_conversations.it.jinja (1)
1-32: Conversation context template matches data model and prior patternsHeader switch for overview vs full transcripts, iteration over
conversations, and conditionalsummaryvstranscriptplus optionalartifactsall mirror the existing templates. Usingconversation.created_atandconversation.durationwithout null checks is aligned with how this data is modeled. Based on learnings, this is exactly what we want. LGTM.echo/server/dembrane/seed.py (1)
266-273: Italian language + verification topics are wired into seeding correctlyAdding
"it-IT"toDEFAULT_DIRECTUS_LANGUAGESplus the new"it-IT"labels on allDEFAULT_VERIFICATION_TOPICSentries slots perfectly into the existing reconciliation pipeline:_build_desired_topic_translations,_ensure_verification_topic_translations, andreconcile_default_verification_topicswill pick these up automatically. No extra Directus calls, and all existing ones stay behindrun_in_thread_poolas per backend async guidelines. As per coding guidelines, this is exactly the shape we want. LGTM.Also applies to: 323-455
echo/server/prompt_templates/system_report.it.jinja (1)
1-54: System report template is well-structured and conservativeTranscript export block and the Italian instructions for generating a Q&A-style Markdown article are clear, tightly scoped to the provided content, and explicitly forbid hallucinated info (
Non introdurre informazioni o opinioni non presenti...). Output contract (no<br>, article wrapped in<article>with Markdown inside) is crisp. This is exactly the kind of prompt hygiene we want in production. LGTM.echo/frontend/src/locales/nl-NL.po (1)
106-1890: .po updates look consistent with new Italian + portal-editor flowsThe Dutch catalog has the expected new entries and reference updates for the added UX (Italian language option, portal editor copy, verify flows, header “Help us translate”, QR code sharing, etc.). Given this file is generated by Lingui and managed via tooling, there’s nothing to tweak manually here. Based on learnings, we treat this as source-of-truth output from the i18n pipeline. LGTM.
echo/frontend/src/config.ts (1)
29-36: SUPPORTED_LANGUAGES now correctly exposes ItalianAdding
"it-IT"toSUPPORTED_LANGUAGESkeeps the frontend in lockstep with the new server-side language + seeding config and the Lingui locale addition. No knock-on effects: everything consuming this constant now automatically understands Italian as first-class. LGTM, ship it.echo/frontend/src/components/announcement/utils/dateUtils.ts (1)
2-12: Italian locale mapping matches existing pattern.Importing
itand adding"it-IT"tolocaleMapis symmetric with the other locales, soformatDatewill pick up Italian with no surprises.echo/frontend/src/components/language/LanguagePicker.tsx (1)
38-43: Italian language option is wired consistently.Flag, ISO code, label, and
language: "it-IT"all mirror the existing entries, so the picker will surface Italian cleanly wherever it’s used.echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx (1)
29-36: Italian locale mapping plugs straight into existing resolution.Adding
it: "it-IT"keeps LANGUAGE_TO_LOCALE uniform and lets verification topics resolve Italian labels without any extra plumbing.echo/frontend/src/hooks/useLanguage.ts (1)
12-21: Italian messages are correctly registered in i18n.Loading
"it-IT"alongside the existing locales keepsuseLanguage’s behavior unchanged while exposing Italian to any consumer that activates that locale.echo/frontend/src/components/project/ProjectPortalEditor.tsx (1)
450-471: Italian option in the portal language dropdown is consistent with the schema.The
NativeSelectnow exposes{ label: t\Italian`, value: "it" }, which matches the updatedFormSchema.language` and LANGUAGE_TO_LOCALE mapping, so the form and downstream locale lookups stay in sync.echo/server/prompt_templates/summary.it.jinja (1)
1-13: Ship it! Italian prompt looks solid.The conversational tone with "tu" and the structured guidelines are on point. The example format gives clear direction without over-constraining the AI.
echo/server/dembrane/transcribe.py (2)
28-28: Clean import, good call.Pulling in
get_allowed_languagessets up the dynamic language flow nicely.
109-109: Portuguese is intentionally separate—smart move for AssemblyAI detection.The main project languages (
ALLOWED_LANGUAGES) are locked to["en", "nl", "de", "fr", "es", "it"], but Portuguese gets added explicitly for AssemblyAI's language detection. This is by design: the project supports 6 languages, but AssemblyAI's detection can be broader to recognize Portuguese audio even if the system doesn't fully support it downstream. Clean separation of concerns.echo/frontend/src/components/participant/verify/VerifySelection.tsx (2)
19-19: Italian in the house.Type union updated cleanly. Solid.
26-26: Locale mapping looks tight.The
it→it-ITmapping keeps the frontend aligned with Lingui locales. No issues here.echo/server/dembrane/api/project.py (2)
26-26: Import game strong.Bringing in
get_allowed_languagesfrom the service layer keeps things DRY.
55-55: Dynamic validation is the way.Swapping hardcoded language checks for
get_allowed_languages()makes this way more maintainable. Adding new languages just works now.echo/server/prompt_templates/get_reply_summarize.it.jinja (1)
1-12: Another solid Italian prompt.Conversational guidelines are clear, example format is helpful. The "tu" form keeps it friendly. This template matches the pattern from the other prompts—no complaints.
echo/server/dembrane/service/project.py (2)
7-7: Centralized language config = chef's kiss.Defining
ALLOWED_LANGUAGEShere as the single source of truth is the right move. Italian joins the squad cleanly.
10-12: Accessor function keeps it clean.Simple getter for allowed languages. This makes it easy for other modules to query supported languages without tight coupling to the constant.
echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx (1)
179-203: Italian onboarding flows nicely.The
it-ITblock follows the same structure as the other locales—microphone check + ready-to-start screens. "Controllo Microfono" and "Pronti a iniziare?" read naturally. Integration withgetSystemCardsand the shared components looks solid.echo/frontend/lingui.config.ts (1)
13-13: Lingui config updated, all systems go.Adding
it-ITto the locales array unlocks Italian translations across the frontend. Simple, necessary, done right.echo/frontend/src/locales/it-IT.ts (1)
1-1: Lingui catalog wiring forit-ITis structurally solidMinified, eslint-disabled catalog with
Messagestyping andJSON.parsematches the usual Lingui compiled pattern. No structural or runtime issues; this cleanly plugs Italian into the i18n stack even if most strings still fall back to English for now. Ship it.echo/server/prompt_templates/get_reply_brainstorm.it.jinja (1)
1-17: Italian brainstorming prompt is clean and ready to plug into the LLM pipelineCopy reads naturally in Italian, captures the same constraints as the English brainstorming mode, and avoids any Jinja placeholder pitfalls (no braces, no variables). Nothing here blocks shipping.
echo/frontend/src/locales/de-DE.po (1)
1-4058: de-DE catalog updates look like clean Lingui regeneration + new IDs wired inSpot-checking the changed sections: references are updated for the new PortalEditor, onboarding, language options (including Italian), and header “Help us translate” flows; msgids/msgstrs stay consistent, and ICU/placeholder usage (
{0},{label},{revisionNumber}, plurals, etc.) remains structurally sound. No runtime‑relevant issues; for a generated .po this is exactly what we want. LGTM, don’t hand‑edit this file.echo/frontend/src/locales/en-US.po (1)
1-4470: LGTM – auto-generated i18n file.This .po file is generated by lingui/cli and reflects the addition of Italian locale support across the app. The reordering of references and new Italian entries are expected outputs from the i18n extraction process.
echo/frontend/src/components/participant/hooks/useOnboardingCards.ts (3)
333-401: LGTM – Italian basic tutorial cards look solid.The structure mirrors existing languages perfectly. All required fields are present, icons are correctly assigned, and the content follows the same flow as other locales.
888-989: LGTM – Italian advanced tutorial cards ship-ready.The advanced cards include all sections (Welcome, How it works, Privacy, Best Practices) with proper structure. The privacy card integration via spread operator matches the pattern used in other languages.
1190-1211: LGTM – Italian privacy card complete.The privacy card includes the required checkbox, proper content structure, and links to the official privacy policy. All fields are correctly populated and match the structure of other language privacy cards.
echo/frontend/src/locales/es-ES.po (1)
1671-1694: es-ES.po is auto-generated; new language strings align with the feature, nothing to fix.es-ES.po is Lingui-generated, so we shouldn’t hand-edit it. The new entries around
"Italian","Language", and related portal/editor strings look consistent with existing patterns and with adding Italian as a selectable language. From an app/integration perspective this diff is fine to ship; any wording tweaks should go through your translation workflow, not manual edits here. LGTM.echo/server/prompt_templates/generate_conversation_summary.it.jinja (1)
1-87: Italian summary template wiring and Jinja structure look solidThe template shape (quotes block, optional project context, optional verified artifacts loop) and the Jinja conditionals/loops are clean and consistent with the usual summary pipeline; there’s no risky logic or placeholder misuse here. The stylistic guidelines are self-contained instructions to the model and won’t interfere with downstream parsing. LGTM to ship as the Italian variant.
echo/server/prompt_templates/system_chat.it.jinja (1)
1-83: Mode-switching system prompt for Italian is correctly structuredThe Italian system prompt cleanly mirrors the two-mode contract: a summaries-only “PANORAMICA” branch and a full-transcript “CONTESTO SPECIFICO” branch, gated by
is_overview_mode. No risky Jinja usage, tags match the documented conversation schema (<name>,<tags>,<date>,<duration>,<transcript>,<artifacts>), and the style constraints are in line with the existing system_chat templates. This is ready to plug into the Italian path. LGTM.echo/frontend/src/locales/fr-FR.po (1)
1-4064: LGTM! Auto-generated translations ship clean.This
.pofile is auto-generated by@lingui/cli(line 15) and the changes look solid. Line number shifts reflect source code updates, and the new Italian language entry ("Italien"at lines 1671-1673) plus the "Help us translate" addition (lines 1524-1525) are properly formatted and correctly translated to French.Based on learnings,
.pofiles are tool-managed and shouldn't be manually edited—these changes follow that pattern perfectly.
| IconWorld, | ||
| } from "@tabler/icons-react"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Harden external menu links with rel="noreferrer noopener".
The new “Help us translate” link (and the existing Documentation link) open a new tab without rel, which leaves window.opener wired up. Easy win to lock this down:
- <Menu.Item
- rightSection={<IconNotes />}
- component="a"
- href={docUrl}
- target="_blank"
- >
+ <Menu.Item
+ rightSection={<IconNotes />}
+ component="a"
+ href={docUrl}
+ target="_blank"
+ rel="noreferrer noopener"
+ >
@@
- <Menu.Item
- rightSection={<IconWorld />}
- component="a"
- href="https://tally.so/r/PdprZV"
- target="_blank"
- >
+ <Menu.Item
+ rightSection={<IconWorld />}
+ component="a"
+ href="https://tally.so/r/PdprZV"
+ target="_blank"
+ rel="noreferrer noopener"
+ >Also applies to: 175-185, 188-195
🤖 Prompt for AI Agents
In echo/frontend/src/components/layout/Header.tsx around lines 11-12 (and also
apply to blocks at 175-185 and 188-195), external links that open in a new tab
(target="_blank") are missing the rel attribute; update each anchor that opens a
new tab (e.g., Documentation and Help us translate links) to include
rel="noreferrer noopener" to prevent window.opener from being exposed and
improve security; ensure you add both values exactly as shown and keep other
attributes intact.
| language: z.enum(["en", "nl", "de", "fr", "es", "it"]), | ||
| verification_topics: z.array(z.string()), | ||
| }); | ||
|
|
||
| type ProjectPortalFormValues = z.infer<typeof FormSchema>; | ||
|
|
||
| type LanguageCode = "de" | "en" | "es" | "fr" | "nl"; | ||
| type LanguageCode = "de" | "en" | "es" | "fr" | "nl" | "it"; | ||
|
|
||
| const LANGUAGE_TO_LOCALE: Record<LanguageCode, string> = { | ||
| de: "de-DE", | ||
| en: "en-US", | ||
| es: "es-ES", | ||
| fr: "fr-FR", | ||
| it: "it-IT", | ||
| nl: "nl-NL", | ||
| }; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Unify LanguageCode usage with projectLanguageCode for type safety.
You’ve extended the schema, LanguageCode, and LANGUAGE_TO_LOCALE to include "it", which is exactly what we want. The only loose end is projectLanguageCode still hardcoding a narrower union; you can let the single source of truth drive it:
- const projectLanguageCode = (project.language ?? "en") as
- | "en"
- | "nl"
- | "de"
- | "fr"
- | "es";
+ const projectLanguageCode = (project.language ?? "en") as LanguageCode;Keeps runtime behavior the same, but keeps the type system honest when more languages get added.
Also applies to: 197-203
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.