Skip to content

Conversation

@ussaama
Copy link
Contributor

@ussaama ussaama commented Dec 11, 2025

Summary by CodeRabbit

Release Notes

  • New Features
    • Added Italian (it-IT) language support throughout the application with complete UI translations
    • Italian users can now select Italian in language preferences
    • Italian onboarding guides and verification content available
    • New "Help us translate" link in header for community translation contributions

✏️ Tip: You can customize this high-level summary in your review settings.

@linear
Copy link

linear bot commented Dec 11, 2025

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Walkthrough

This 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

Cohort / File(s) Summary
Lingui Configuration & Language Support
echo/frontend/lingui.config.ts, echo/frontend/src/hooks/useLanguage.ts, echo/frontend/src/config.ts
Added "it-IT" to supported locales array and registered Italian translations (itMessages) in i18n.load map
Frontend Locale Mappings
echo/frontend/src/components/announcement/utils/dateUtils.ts, echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx, echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx, echo/frontend/src/components/participant/verify/VerifySelection.tsx, echo/frontend/src/components/project/ProjectPortalEditor.tsx, echo/frontend/src/components/project/ProjectQRCode.tsx
Extended LANGUAGE_TO_LOCALE mappings and LanguageCode type definitions to include Italian "it" ↔ "it-IT" bidirectional support
Frontend UI Language Selection
echo/frontend/src/components/language/LanguagePicker.tsx, echo/frontend/src/components/layout/Header.tsx
Added Italian language option (🇮🇹 "Italiano") to language picker and introduced "Help us translate" menu item with external translation link
Frontend Onboarding Content
echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx, echo/frontend/src/components/participant/hooks/useOnboardingCards.ts
Introduced Italian (it-IT) onboarding card sets including system cards (Benvenuto, Come funziona, Privacy, Migliori Pratiche), microphone test component, and initiation form with Italian labels and content
Frontend Italian Locale File
echo/frontend/src/locales/it-IT.ts
Created new TypeScript locale file exporting Italian translation messages object from JSON payload
Frontend Translation Files
echo/frontend/src/locales/de-DE.po, echo/frontend/src/locales/en-US.po, echo/frontend/src/locales/es-ES.po, echo/frontend/src/locales/fr-FR.po, echo/frontend/src/locales/nl-NL.po
Updated translation reference paths (reindexed line numbers for ProjectPortalEditor and other components) and added Italian language labels across all locale files; no semantic content changes to existing translations
Backend Language Configuration & Validation
echo/server/dembrane/service/project.py, echo/server/dembrane/api/project.py
Introduced ALLOWED_LANGUAGES constant ["en", "nl", "de", "fr", "es", "it"] and get_allowed_languages() function; replaced hard-coded language whitelist with dynamic validation
Backend Seed Data
echo/server/dembrane/seed.py
Added Italian (it-IT) to DEFAULT_DIRECTUS_LANGUAGES and extended DEFAULT_VERIFICATION_TOPICS with Italian translations for all six topic categories (agreements, gems, truths, moments, actions, disagreements)
Backend Transcription
echo/server/dembrane/transcribe.py
Updated AssemblyAI language-detection options to use dynamic get_allowed_languages() union with {"pt"} instead of hard-coded language list
Backend Italian Prompt Templates
echo/server/prompt_templates/default_whisper_prompt.it.jinja, echo/server/prompt_templates/context_conversations.it.jinja, echo/server/prompt_templates/generate_conversation_summary.it.jinja, echo/server/prompt_templates/get_reply_brainstorm.it.jinja, echo/server/prompt_templates/get_reply_summarize.it.jinja, echo/server/prompt_templates/get_reply_system.it.jinja, echo/server/prompt_templates/summary.it.jinja, echo/server/prompt_templates/system_chat.it.jinja, echo/server/prompt_templates/system_report.it.jinja, echo/server/prompt_templates/translate_transcription.it.jinja
Added 10 new Italian-language Jinja2 template files for prompt generation, conversation processing, transcription translation, and system instructions

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

  • Scope & breadth: 30+ files touched across frontend and backend, spanning multiple systems (i18n, onboarding, prompts, API validation, seed data)
  • Homogeneity of changes: Most changes follow consistent patterns (locale mapping additions, translation file updates, template creation) which reduces per-file review effort
  • Areas requiring attention:
    • echo/server/dembrane/service/project.py and echo/server/dembrane/api/project.py — verify dynamic language validation logic replaces hard-coded logic correctly and doesn't break existing contracts
    • echo/frontend/src/components/participant/hooks/useOnboardingCards.ts — ensure Italian onboarding card structure mirrors existing language patterns consistently
    • echo/server/prompt_templates/*.it.jinja — validate Italian prompt templates (10 files) follow established patterns from other language templates and contain semantically correct instructions
    • echo/frontend/src/locales/it-IT.ts — spot-check JSON payload structure and key alignment with other locale files

Possibly related PRs

Suggested labels

feature, internationalization, i18n, italian-support


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)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the primary change: adding Italian language support throughout the application.
Linked Issues check ✅ Passed The pull request implements Italian language support across frontend and backend components, aligning with ECHO-620's objective to add Italian support.
Out of Scope Changes check ✅ Passed All changes are directly related to adding Italian language support; no unrelated modifications detected outside the scope of ECHO-620.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch testing

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ussaama ussaama requested a review from spashii December 11, 2025 12:27
@coderabbitai coderabbitai bot added the Feature label Dec 11, 2025
@spashii spashii merged commit cc0f27c into main Dec 11, 2025
20 of 21 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 unknown project.language values.

Right now, if project.language isn’t one of the mapped keys, languageCode ends up undefined and 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 routing formatArtefactTime through 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.

📥 Commits

Reviewing files that changed from the base of the PR and between d6096a0 and af04c6a.

📒 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 via className, alongside toast feedback via @/components/common/Toaster
For Tailwind classes that need dynamic values, replace with inline style props using CSS variables instead of hardcoded hex values

Files:

  • echo/frontend/src/components/project/ProjectQRCode.tsx
  • echo/frontend/src/components/layout/Header.tsx
  • echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx
  • echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx
  • echo/frontend/src/components/participant/verify/VerifySelection.tsx
  • echo/frontend/src/components/language/LanguagePicker.tsx
  • echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx
  • echo/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) and var(--app-text) instead of hardcoded colors like #F6F4F1 or #2D2D2C to ensure theme changes propagate

Files:

  • echo/frontend/src/components/project/ProjectQRCode.tsx
  • echo/frontend/src/components/announcement/utils/dateUtils.ts
  • echo/frontend/src/hooks/useLanguage.ts
  • echo/frontend/src/components/layout/Header.tsx
  • echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx
  • echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx
  • echo/frontend/src/components/participant/verify/VerifySelection.tsx
  • echo/frontend/src/components/language/LanguagePicker.tsx
  • echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx
  • echo/frontend/src/locales/it-IT.ts
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
  • echo/frontend/src/components/participant/hooks/useOnboardingCards.ts
  • echo/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.tsx with custom primary color palette and component defaults, preferring CSS variables in styles over hardcoded hex values

Files:

  • echo/frontend/src/components/project/ProjectQRCode.tsx
  • echo/frontend/src/components/layout/Header.tsx
  • echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx
  • echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx
  • echo/frontend/src/components/participant/verify/VerifySelection.tsx
  • echo/frontend/src/components/language/LanguagePicker.tsx
  • echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx
  • echo/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 Alert components inside modals/forms for errors or warnings

Files:

  • echo/frontend/src/components/project/ProjectQRCode.tsx
  • echo/frontend/src/components/layout/Header.tsx
  • echo/frontend/src/components/participant/ParticipantOnboardingCards.tsx
  • echo/frontend/src/components/participant/verify/VerifiedArtefactsList.tsx
  • echo/frontend/src/components/participant/verify/VerifySelection.tsx
  • echo/frontend/src/components/language/LanguagePicker.tsx
  • echo/frontend/src/components/conversation/VerifiedArtefactsSection.tsx
  • echo/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 using run_in_thread_pool from dembrane.async_helpers in backend code. Wrap calls to directus.*, 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 to async def and await results rather than using synchronous functions

echo/server/dembrane/**/*.py: Config changes live in dembrane/settings.py; add new env vars as fields on AppSettings, expose grouped accessors (e.g., feature_flags, directus) if multiple modules read them, and fetch config at runtime with settings = get_settings()—never import env vars directly
Embeddings use settings.embedding; populate EMBEDDING_* env vars (model, key/base URL/version) before calling dembrane.embedding.embed_text

Files:

  • echo/server/dembrane/service/project.py
  • echo/server/dembrane/seed.py
  • echo/server/dembrane/api/project.py
  • echo/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.py
  • echo/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 via run_async_in_new_loop from dembrane.async_helpers instead of calling it directly or with asyncio.run to 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.jinja
  • echo/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.tsx
  • echo/frontend/src/locales/fr-FR.po
  • echo/frontend/src/locales/es-ES.po
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/en-US.po
  • echo/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.tsx
  • echo/frontend/src/locales/it-IT.ts
  • echo/frontend/src/locales/fr-FR.po
  • echo/frontend/lingui.config.ts
  • echo/frontend/src/locales/es-ES.po
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/en-US.po
  • echo/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.ts
  • echo/frontend/src/locales/de-DE.po
  • echo/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.ts
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/en-US.po
  • echo/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.po
  • echo/frontend/src/locales/es-ES.po
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/en-US.po
  • echo/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.po
  • echo/frontend/src/locales/es-ES.po
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/en-US.po
  • echo/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.po
  • echo/frontend/src/locales/es-ES.po
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/en-US.po
  • echo/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.po
  • echo/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-ready

Simple, 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 solid

Variables 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 port

Context 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 patterns

Header switch for overview vs full transcripts, iteration over conversations, and conditional summary vs transcript plus optional artifacts all mirror the existing templates. Using conversation.created_at and conversation.duration without 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 correctly

Adding "it-IT" to DEFAULT_DIRECTUS_LANGUAGES plus the new "it-IT" labels on all DEFAULT_VERIFICATION_TOPICS entries slots perfectly into the existing reconciliation pipeline: _build_desired_topic_translations, _ensure_verification_topic_translations, and reconcile_default_verification_topics will pick these up automatically. No extra Directus calls, and all existing ones stay behind run_in_thread_pool as 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 conservative

Transcript 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 flows

The 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 Italian

Adding "it-IT" to SUPPORTED_LANGUAGES keeps 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 it and adding "it-IT" to localeMap is symmetric with the other locales, so formatDate will 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 keeps useLanguage’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 NativeSelect now exposes { label: t\Italian`, value: "it" }, which matches the updated FormSchema.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_languages sets 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 itit-IT mapping 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_languages from 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_LANGUAGES here 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-IT block follows the same structure as the other locales—microphone check + ready-to-start screens. "Controllo Microfono" and "Pronti a iniziare?" read naturally. Integration with getSystemCards and the shared components looks solid.

echo/frontend/lingui.config.ts (1)

13-13: Lingui config updated, all systems go.

Adding it-IT to 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 for it-IT is structurally solid

Minified, eslint-disabled catalog with Messages typing and JSON.parse matches 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 pipeline

Copy 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 in

Spot-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 solid

The 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 structured

The 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 .po file 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, .po files are tool-managed and shouldn't be manually edited—these changes follow that pattern perfectly.

Comment on lines +11 to 12
IconWorld,
} from "@tabler/icons-react";
Copy link
Contributor

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.

Comment on lines +53 to 69
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",
};

Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants