Skip to content

ECHO-668 helper changes for anonymous transcripts mode (#436)#437

Merged
ussaama merged 1 commit intomainfrom
testing
Feb 13, 2026
Merged

ECHO-668 helper changes for anonymous transcripts mode (#436)#437
ussaama merged 1 commit intomainfrom
testing

Conversation

@ussaama
Copy link
Contributor

@ussaama ussaama commented Feb 13, 2026

Summary by CodeRabbit

  • New Features

    • Added conversation anonymization feature that replaces personal information with placeholders in transcripts.
    • Added visual indicators for anonymized conversations and verified artifacts.
  • Changes

    • Anonymized conversations now disable audio playback, audio download, and retranscription.
    • Updated UI messaging to inform users of anonymization restrictions and privacy protections.
  • Bug Fixes

    • Improved stability by protecting analytics tracking from failures.
  • Documentation

    • Added comprehensive translations across multiple languages for anonymization-related features.

@linear
Copy link

linear bot commented Feb 13, 2026

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

Walkthrough

Implements anonymized conversations feature by adding is_anonymized field to conversation records, disabling audio playback/download/retranscription in UI when enabled, updating translation strings across six languages, and adjusting backend conversation creation/processing logic to respect anonymization flag.

Changes

Cohort / File(s) Summary
Directus Sync Configuration
echo/directus/sync/collections/operations.json, echo/directus/sync/collections/policies.json
Operations JSON ID swaps without functional change; Administrator policy updated to remove trailing null role entry.
Conversation Field Sort Orders
echo/directus/sync/snapshot/fields/conversation/...
Field metadata updates: is_anonymized added as new field definition, is_finished (21→22), is_audio_processing_finished (22→23), is_all_chunks_transcribed (23→24), linked_conversations (24→25), linking_conversations (25→26), conversation_artifacts (26→27).
Conversation UI Components
echo/frontend/src/components/conversation/ConversationAccordion.tsx, ConversationDangerZone.tsx, RetranscribeConversation.tsx
ConversationAccordion adds shield icon for anonymized indicator and verified artefacts badge, with analytics wrapped in try/catch; ConversationDangerZone disables audio download with tooltip for anonymized conversations; RetranscribeConversation adds disabled state and tooltip for anonymized conversations.
Conversation Hooks & Types
echo/frontend/src/components/conversation/hooks/index.ts, echo/frontend/src/lib/typesDirectus.d.ts
Added is_anonymized to CONVERSATION_FIELDS_WITHOUT_PROCESSING_STATUS and Conversation interface; removed diarization from chunk field selection.
Portal Editor UI
echo/frontend/src/components/project/ProjectPortalEditor.tsx
Added shield icon and expanded description text for "Anonymize Transcripts" setting, documenting audio playback/download/retranscription restrictions and irreversibility for processed conversations.
Conversation Routes
echo/frontend/src/routes/project/conversation/ProjectConversationOverview.tsx, ProjectConversationTranscript.tsx
ProjectConversationOverview passes disableDownloadAudio flag to ConversationDangerZone based on anonymization state; ProjectConversationTranscript requests and respects is_anonymized field, disabling audio player and retranscription action when set, preventing audio data propagation to child components.
Button Styling
echo/frontend/src/styles/button.module.css
Extended disabled button styling to cover anchor-based buttons using data-disabled attribute with pointer-events: all for hover/active states.
Localization Files
echo/frontend/src/locales/{de-DE,en-US,es-ES,fr-FR,it-IT,nl-NL}.po
Added translation entries across six languages for anonymized conversation indicators, audio restriction notices, retranscription restrictions, and comprehensive privacy notice explaining anonymization behavior and its effects on audio/retranscription features.
Backend Services
echo/server/dembrane/api/conversation.py, echo/server/dembrane/service/conversation.py, echo/server/dembrane/tasks.py
API layer adds is_anonymized field to retranscribed conversation payload; service layer populates is_anonymized from project setting when creating conversations; task layer refactored to read anonymization flag directly from conversation record instead of querying Directus project config.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The feature implementation is cohesive and well-structured with consistent patterns across UI/backend layers, but requires verification across multiple component integration points, localization completeness across six languages, and backend data flow from project setting → conversation record → task execution.

Possibly related PRs

Suggested labels

Feature, improvement

🚥 Pre-merge checks | ✅ 5 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 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 main change: implementing helper functionality for anonymous transcripts mode with required feature restrictions.
Linked Issues check ✅ Passed All ECHO-668 requirements are met: audio player disabled for anonymized conversations, retranscription disabled, audio download disabled, icons added, and portal editor text updated.
Out of Scope Changes check ✅ Passed All changes directly support anonymization feature: field additions, UI components, translations, backend logic, and styling updates for disabled states are all scope-aligned.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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.

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: 16

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/conversation/RetranscribeConversation.tsx (1)

42-59: ⚠️ Potential issue | 🟠 Major

Use data-disabled instead of disabled so the tooltip can show.

Mantine's Tooltip won't fire on truly disabled elements. Replace disabled={disabled} with data-disabled={disabled || undefined} and guard the onClick handler: onClick={(e) => !disabled && open()}. This keeps hover events alive while preserving the visual disabled state.

🧩 Suggested fix
 			<Tooltip
 				label={
 					disabled
 						? t`Retranscription not available for anonymized conversations`
 						: t`Retranscribe conversation`
 				}
 			>
 				<ActionIcon
-					onClick={open}
+					onClick={(e) => !disabled && open()}
 					size="md"
 					variant="subtle"
 					color="gray"
-					disabled={disabled}
+					data-disabled={disabled || undefined}
 					{...testId("transcript-retranscribe-button")}
 				>
 					<IconRefresh size={20} />
 				</ActionIcon>
 			</Tooltip>
echo/frontend/src/locales/it-IT.po (1)

8-8: ⚠️ Potential issue | 🟡 Minor

Language header in it-IT.po is incorrect — it says en-US but should be it-IT.

All other locale files have matching headers. This mismatch likely stems from a tool configuration issue with the i18n setup. Instead of manually editing the .po file, fix the lingui configuration to correctly specify it-IT for this locale, then run pnpm messages:extract to regenerate the file with the correct Language header.

🤖 Fix all issues with AI agents
In `@echo/frontend/src/components/conversation/ConversationAccordion.tsx`:
- Around line 935-939: Multiple identical try/catch wrappers around
analytics.trackEvent create noise; extract a thin helper (e.g., safeTrackEvent)
that accepts the same parameters as analytics.trackEvent, wraps the call in a
try/catch, and logs failures with the existing warning message, then replace all
occurrences in ConversationAccordion (the calls around events.SELECT_ALL_CLICK
and the other three sites) and ConversationDangerZone with safeTrackEvent to DRY
up the code.

In `@echo/frontend/src/locales/de-DE.po`:
- Around line 3236-3238: Update the German translation for the msgid "Project
default: enabled. This will replace personally identifiable information with
<redacted>." (occurrences at the shown diff and also lines 4389-4391) to use
natural German word order and include "durch": change the msgstr to a sentence
like "Projektstandard: aktiviert. Dies ersetzt persönlich identifizierbare
Informationen durch <redacted>." so the phrasing is grammatically correct and
reads naturally.
- Around line 3145-3147: The German translation for the msgid "Please wait while
we process your retranscription request. You will be redirected to the new
conversation when ready." is ungrammatical and uses inconsistent terminology;
update the msgstr to a correct, natural phrasing using "Gespräch" (e.g. "Bitte
warten Sie, während wir Ihre Anfrage zur Neutranskription bearbeiten. Sie werden
automatisch zum neuen Gespräch weitergeleitet, sobald es fertig ist.") and apply
the same correction to the other retranscription-related entries referenced (the
msgid(s) around 3227-3230) so all retranscription messages consistently use the
corrected wording and "Gespräch".
- Around line 2549-2551: The German translation uses two separate words "Neuer
Gespräch Name" instead of the correct compound noun; update the msgstr for msgid
"New Conversation Name" to a single compound like "Neuer Gesprächsname" (or
"Neuer Konversationsname" if you prefer "Konversation") so the PO entry reads
msgid "New Conversation Name" and msgstr "Neuer Gesprächsname".
- Around line 4094-4103: The UI copy uses "Summary generated successfully." and
"Summary regenerated successfully." in ProjectConversationOverview.tsx; update
those source string literals to remove "successfully" (e.g., "Summary
generated." and "Summary regenerated."), then re-run the translation extraction
to regenerate locales (update de-DE.po accordingly). Locate the strings in
src/routes/project/conversation/ProjectConversationOverview.tsx and replace the
msgids, run the project's i18n extraction script (or the established extract
step) to update .po files, and commit the updated source and regenerated locale
file.
- Around line 1600-1602: The UI copy uses the term "AI" but must use "language
model" per guidelines; update the source strings in ProjectPortalEditor (the
msgid currently containing "AI-powered responses" and the other occurrence noted
around lines 4341-4344) to replace "AI" with "language model", then re-run the
i18n extraction to regenerate echo/frontend/src/locales/de-DE.po so the msgid
entries and translations are updated accordingly (ensure the component
function/JSX in ProjectPortalEditor.tsx contains the new wording and re-extract
strings).

In `@echo/frontend/src/locales/en-US.po`:
- Around line 4639-4641: Update the user-facing helper text to use "language
model" instead of "AI": modify the source string in ProjectPortalEditor.tsx (the
prompt/label around the helper used at or near the code referenced) to replace
"AI" with "language model", then re-run the i18n extraction so en-US.po
(msgid/msgstr for the string used in ProjectPortalEditor.tsx) is updated
accordingly; ensure both the source string in ProjectPortalEditor.tsx and the
corresponding msgid/msgstr in en-US.po are changed to the new wording.
- Around line 1840-1842: Update the source string in ProjectPortalEditor (the
msgid currently containing "AI-powered") to use "language model" instead of
"AI-powered", then re-extract translations so the .po entry's msgid and msgstr
reflect the updated source copy; specifically edit the string in the component
where the Explore feature is described (referenced at
ProjectPortalEditor.tsx:646) and run the i18n extraction task to regenerate
en-US.po.

In `@echo/frontend/src/locales/es-ES.po`:
- Around line 717-719: The Spanish translation for msgid "Audio download not
available for anonymized conversations" has incorrect gendered article; update
the msgstr in echo/frontend/src/locales/es-ES.po so it reads "La descarga de
audio no está disponible para conversaciones anónimas" (replace "El descarga..."
with "La descarga...") to match correct Spanish grammar; you can find the entry
associated with src/components/conversation/ConversationDangerZone.tsx:57 by
locating the msgid and updating its msgstr accordingly.
- Around line 4979-4981: The Spanish translation for the anonymization
description (the msgid starting "When enabled, all new transcripts will have
personal information...") contains a gender/article typo in the msgstr ("el
descarga de audio"); update that msgstr to use the correct feminine article ("la
descarga de audio") so it reads "...la reproducción de audio, la descarga de
audio y la retranscripción...". Also scan for and fix any other occurrences of
"el descarga" in es-ES.po to ensure consistency.

In `@echo/frontend/src/locales/fr-FR.po`:
- Around line 4998-5004: The French translation msgstr for the msgid that begins
"When enabled, all new transcripts..." contains the incorrect gender/number
phrase "tous les nouveaux transcriptions"; update that msgstr so the phrase
reads "toutes les nouvelles transcriptions" (and ensure it replaces the exact
substring in the msgstr associated with that msgid in the locales file
referenced by ProjectPortalEditor.tsx).
- Around line 3574-3580: Replace the incorrect verb "La rétranscrire" with the
noun "La retranscription" in the French translations matching the msgids from
RetranscribeConversation.tsx (the entries for "Retranscription not available for
anonymized conversations" and "Retranscription started. New conversation will be
available soon.") and also update the similar anonymization notice translation
referenced later (around the other anonymization msgid) so all msgstr values
consistently use "La retranscription".

In `@echo/frontend/src/locales/it-IT.po`:
- Around line 777-787: The Italian locale file it-IT.po has many untranslated
entries (only ~20% translated) and the three new strings from
ProjectPortalEditor.tsx ("Anonymize Transcripts") and ConversationAccordion.tsx
("anonymized conversation" / "Anonymized conversation") are still English;
update those msgstr values to proper Italian translations (e.g., "Anonymizza le
trascrizioni" and "conversazione anonimizzata"/"Conversazione anonimizzata" as
appropriate), then run your i18n tooling (msgfmt/poedit or your pipeline) to
validate the .po file, and perform a systematic audit to translate the remaining
717 placeholders so that all six locale files reach full translation coverage
per guidelines.

In `@echo/frontend/src/locales/nl-NL.po`:
- Around line 4971-4973: The translation for msgid "Verify Topics" is incorrect:
msgstr currently uses German "Themen"; update the Dutch translation in nl-NL.po
by replacing the msgstr "Verifiëren Themen" with the correct Dutch phrase
"Verifiëren Onderwerpen" (the entry tied to msgid "Verify Topics" referenced
from ProjectPortalEditor.tsx).
- Around line 5164-5167: The Dutch translation for the msgid in
ProjectPortalEditor.tsx uses "al bestaande gesprekken" which erroneously reads
"already-existing" instead of "already-processed"; update the msgstr in nl-NL.po
(the entry for the long anonymization description) to use "al verwerkte
gesprekken" (or equivalent Dutch phrasing meaning "already-processed
conversations") so it matches the English source semantics.

In `@echo/frontend/src/styles/button.module.css`:
- Around line 63-65: Stylelint reports a missing empty line before the comment
preceding the .root selector; fix by inserting a single blank line immediately
before the comment block "/* Note: [data-disabled]..." so the comment is
separated from the previous CSS rule, ensuring the selector block that starts
with ".root:disabled:not([data-loading="true"])," and
".root[data-disabled]:not([data-loading="true"])" follows the blank line and
satisfies the stylelint empty-line-before-comment rule.

Comment on lines +935 to +939
try {
analytics.trackEvent(events.SELECT_ALL_CLICK);
} catch (error) {
console.warn("Analytics tracking failed:", error);
}
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

Consider extracting a safe analytics helper to DRY up these try/catch blocks.

Four identical try/catch patterns for analytics.trackEvent. A thin wrapper would reduce noise:

♻️ Proposed refactor
// e.g. in analytics.ts or locally
const safeTrackEvent = (...args: Parameters<typeof analytics.trackEvent>) => {
  try {
    analytics.trackEvent(...args);
  } catch (error) {
    console.warn("Analytics tracking failed:", error);
  }
};

Then replace all four sites with safeTrackEvent(events.SELECT_ALL_CLICK), etc. Also applies to the same pattern in ConversationDangerZone.tsx.

Also applies to: 951-955, 967-971, 973-977

🤖 Prompt for AI Agents
In `@echo/frontend/src/components/conversation/ConversationAccordion.tsx` around
lines 935 - 939, Multiple identical try/catch wrappers around
analytics.trackEvent create noise; extract a thin helper (e.g., safeTrackEvent)
that accepts the same parameters as analytics.trackEvent, wraps the call in a
try/catch, and logs failures with the existing warning message, then replace all
occurrences in ConversationAccordion (the calls around events.SELECT_ALL_CLICK
and the other three sites) and ConversationDangerZone with safeTrackEvent to DRY
up the code.

Comment on lines +1600 to 1602
#: src/components/project/ProjectPortalEditor.tsx:646
msgid "Enable this feature to allow participants to request AI-powered responses during their conversation. Participants can click \"Explore\" after recording their thoughts to receive contextual feedback, encouraging deeper reflection and engagement. A cooldown period applies between requests."
msgstr "Aktivieren Sie diese Funktion, um Teilnehmern die Möglichkeit zu geben, KI-gesteuerte Antworten während ihres Gesprächs anzufordern. Teilnehmer können nach Aufnahme ihrer Gedanken auf \"Explore\" klicken, um kontextbezogene Rückmeldungen zu erhalten, die tiefere Reflexion und Engagement fördern. Ein Abkühlungszeitraum gilt zwischen Anfragen."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Swap “AI” → “language model” in these strings.
Guidelines require “language model,” not “AI,” so update the source strings and re-extract.

💡 Suggested copy update
- msgid "Enable this feature to allow participants to request AI-powered responses during their conversation. Participants can click \"Explore\" after recording their thoughts to receive contextual feedback, encouraging deeper reflection and engagement. A cooldown period applies between requests."
- msgstr "Aktivieren Sie diese Funktion, um Teilnehmern die Möglichkeit zu geben, KI-gesteuerte Antworten während ihres Gesprächs anzufordern. Teilnehmer können nach Aufnahme ihrer Gedanken auf \"Explore\" klicken, um kontextbezogene Rückmeldungen zu erhalten, die tiefere Reflexion und Engagement fördern. Ein Abkühlungszeitraum gilt zwischen Anfragen."
+ msgid "Enable this feature to allow participants to request language model–powered responses during their conversation. Participants can click \"Explore\" after recording their thoughts to receive contextual feedback, encouraging deeper reflection and engagement. A cooldown period applies between requests."
+ msgstr "Aktivieren Sie diese Funktion, um Teilnehmenden sprachmodell-gestützte Antworten während ihres Gesprächs zu ermöglichen. Nach der Aufnahme können sie auf \"Explore\" klicken, um kontextbezogenes Feedback zu erhalten. Zwischen Anfragen gilt eine Abkühlzeit."

- msgid "This prompt guides how the AI responds to participants. Customize it to shape the type of feedback or engagement you want to encourage."
- msgstr "Dieser Prompt leitet ein, wie die KI auf die Teilnehmer reagiert. Passen Sie ihn an, um den Typ der Rückmeldung oder Engagement zu bestimmen, den Sie fördern möchten."
+ msgid "This prompt guides how the language model responds to participants. Customize it to shape the type of feedback or engagement you want to encourage."
+ msgstr "Dieser Prompt steuert, wie das Sprachmodell auf Teilnehmende reagiert. Passen Sie ihn an, um die gewünschte Art von Feedback oder Beteiligung zu fördern."
As per coding guidelines, use “language model” instead of “AI” in UI copy.

Also applies to: 4341-4344

🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/de-DE.po` around lines 1600 - 1602, The UI copy
uses the term "AI" but must use "language model" per guidelines; update the
source strings in ProjectPortalEditor (the msgid currently containing
"AI-powered responses" and the other occurrence noted around lines 4341-4344) to
replace "AI" with "language model", then re-run the i18n extraction to
regenerate echo/frontend/src/locales/de-DE.po so the msgid entries and
translations are updated accordingly (ensure the component function/JSX in
ProjectPortalEditor.tsx contains the new wording and re-extract strings).

Comment on lines 2549 to 2551
msgid "New Conversation Name"
msgstr "Neuer Gespräch Name"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use correct compound noun for “New Conversation Name.”

💡 Suggested translation
- msgstr "Neuer Gespräch Name"
+ msgstr "Neuer Gesprächsname"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
msgid "New Conversation Name"
msgstr "Neuer Gespräch Name"
msgid "New Conversation Name"
msgstr "Neuer Gesprächsname"
🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/de-DE.po` around lines 2549 - 2551, The German
translation uses two separate words "Neuer Gespräch Name" instead of the correct
compound noun; update the msgstr for msgid "New Conversation Name" to a single
compound like "Neuer Gesprächsname" (or "Neuer Konversationsname" if you prefer
"Konversation") so the PO entry reads msgid "New Conversation Name" and msgstr
"Neuer Gesprächsname".

Comment on lines 3145 to 3147
msgid "Please wait while we process your retranscription request. You will be redirected to the new conversation when ready."
msgstr "Bitte warten Sie, während wir Ihre Hertranskription anfragen verarbeiten. Sie werden automatisch zur neuen Konversation weitergeleitet, wenn fertig."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix German grammar for retranscription processing messages.
Current phrasing is ungrammatical and inconsistent with “Gespräch”.

💡 Suggested translation
- msgstr "Bitte warten Sie, während wir Ihre Hertranskription anfragen verarbeiten. Sie werden automatisch zur neuen Konversation weitergeleitet, wenn fertig."
+ msgstr "Bitte warten Sie, während wir Ihre Anfrage zur Hertranskription verarbeiten. Sie werden automatisch zum neuen Gespräch weitergeleitet, sobald es bereit ist."

- msgstr "Ihre Hertranskription anfragen werden verarbeitet..."
+ msgstr "Ihre Anfrage zur Hertranskription wird verarbeitet..."

Also applies to: 3227-3230

🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/de-DE.po` around lines 3145 - 3147, The German
translation for the msgid "Please wait while we process your retranscription
request. You will be redirected to the new conversation when ready." is
ungrammatical and uses inconsistent terminology; update the msgstr to a correct,
natural phrasing using "Gespräch" (e.g. "Bitte warten Sie, während wir Ihre
Anfrage zur Neutranskription bearbeiten. Sie werden automatisch zum neuen
Gespräch weitergeleitet, sobald es fertig ist.") and apply the same correction
to the other retranscription-related entries referenced (the msgid(s) around
3227-3230) so all retranscription messages consistently use the corrected
wording and "Gespräch".

Comment on lines 3236 to 3238
msgid "Project default: enabled. This will replace personally identifiable information with <redacted>."
msgstr "Projekt Standard: aktiviert. Dies wird persönliche Identifizierbare Informationen mit <redacted> ersetzen."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Tighten PII-redaction German phrasing.
Missing “durch” and awkward noun phrase.

💡 Suggested translation
- msgstr "Projekt Standard: aktiviert. Dies wird persönliche Identifizierbare Informationen mit <redacted> ersetzen."
+ msgstr "Projektstandard: aktiviert. Dies ersetzt personenbezogene Daten durch <redacted>."

- msgstr "Dies wird persönliche Identifizierbare Informationen mit <redacted> ersetzen."
+ msgstr "Dies ersetzt personenbezogene Daten durch <redacted>."

Also applies to: 4389-4391

🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/de-DE.po` around lines 3236 - 3238, Update the
German translation for the msgid "Project default: enabled. This will replace
personally identifiable information with <redacted>." (occurrences at the shown
diff and also lines 4389-4391) to use natural German word order and include
"durch": change the msgstr to a sentence like "Projektstandard: aktiviert. Dies
ersetzt persönlich identifizierbare Informationen durch <redacted>." so the
phrasing is grammatically correct and reads naturally.

Comment on lines +4998 to +5004
#: src/components/project/ProjectPortalEditor.tsx:1183
msgid "When enabled, all new transcripts will have personal information (names, emails, phone numbers, addresses) replaced with placeholders. Anonymized conversations also disable audio playback, audio download, and retranscription to protect participant privacy. This cannot be undone for already-processed conversations."
msgstr "Lorsqu'il est activé, tous les nouveaux transcriptions auront des informations personnelles (noms, emails, numéros de téléphone, adresses) remplacées par des placeholders. Les conversations anonymisées désactivent également la lecture de l'audio, le téléchargement de l'audio et la rétranscrire pour protéger la confidentialité des participants. Cela ne peut pas être annulé pour les conversations déjà traitées."

#: src/components/project/ProjectPortalEditor.tsx:1178
msgid "When enabled, all new transcripts will have personal information (names, emails, phone numbers, addresses) replaced with placeholders. This cannot be undone for already-processed conversations."
msgstr "Lorsqu'il est activé, tous les nouveaux transcriptions auront des informations personnelles (noms, emails, numéros de téléphone, adresses) remplacées par des placeholders. Cela ne peut pas être annulé pour les conversations déjà traitées."
#~ msgid "When enabled, all new transcripts will have personal information (names, emails, phone numbers, addresses) replaced with placeholders. This cannot be undone for already-processed conversations."
#~ msgstr "Lorsqu'il est activé, tous les nouveaux transcriptions auront des informations personnelles (noms, emails, numéros de téléphone, adresses) remplacées par des placeholders. Cela ne peut pas être annulé pour les conversations déjà traitées."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Anonymization notice — additional grammatical nit.

Beyond the "rétranscrire" issue flagged above, line 5000 also has "tous les nouveaux transcriptions" — should be "toutes les nouvelles transcriptions" since "transcription" is feminine in French.

Proposed fix (line 5000)
-msgstr "Lorsqu'il est activé, tous les nouveaux transcriptions auront des informations personnelles..."
+msgstr "Lorsqu'il est activé, toutes les nouvelles transcriptions auront des informations personnelles..."
🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/fr-FR.po` around lines 4998 - 5004, The French
translation msgstr for the msgid that begins "When enabled, all new
transcripts..." contains the incorrect gender/number phrase "tous les nouveaux
transcriptions"; update that msgstr so the phrase reads "toutes les nouvelles
transcriptions" (and ensure it replaces the exact substring in the msgstr
associated with that msgid in the locales file referenced by
ProjectPortalEditor.tsx).

Comment on lines +777 to +787
#: src/components/project/ProjectPortalEditor.tsx:1172
msgid "Anonymize Transcripts"
msgstr "Anonymize Transcripts"

#: src/components/conversation/ConversationAccordion.tsx:586
msgid "anonymized conversation"
msgstr "anonymized conversation"

#: src/components/conversation/ConversationAccordion.tsx:582
msgid "Anonymized conversation"
msgstr "Anonymized conversation"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Analyze it-IT.po translation status

# First, check if file exists and basic stats
echo "=== File Info ==="
if [ -f 'echo/frontend/src/locales/it-IT.po' ]; then
  wc -l 'echo/frontend/src/locales/it-IT.po'
else
  echo "File not found at expected path"
  # Try to find it
  find . -name "it-IT.po" -type f
fi

echo ""
echo "=== Translation Status Check ==="
python3 << 'PYEOF'
import re

filepath = 'echo/frontend/src/locales/it-IT.po'
try:
    with open(filepath, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # Find all msgid/msgstr pairs (active entries only)
    pattern = r'(?:^|\n)msgid "(.+?)"\nmsgstr "(.+?)"'
    entries = re.findall(pattern, content, re.MULTILINE | re.DOTALL)
    
    total = len(entries)
    translated = sum(1 for msgid, msgstr in entries if msgid.strip() != msgstr.strip())
    untranslated = total - translated
    
    print(f'Total active entries: {total}')
    print(f'Actually translated (msgstr ≠ msgid): {translated}')
    print(f'Untranslated/placeholder (msgstr = msgid): {untranslated}')
    print(f'Translation coverage: {translated/total*100:.1f}%')
    
    # Check the specific lines mentioned
    print("\n=== Checking lines 777-787 ===")
    lines = content.split('\n')
    for i in range(776, min(788, len(lines))):
        print(f"{i+1}: {lines[i]}")
    
except FileNotFoundError:
    print(f"File not found: {filepath}")
PYEOF

Repository: Dembrane/echo

Length of output: 754


Italian locale file is 80% untranslated — new anonymization strings continue the pattern.

The flagged strings at lines 779, 783, and 787 are indeed untranslated (msgstr equals msgid). However, this reveals a file-wide problem: it-IT.po has only 20% translation coverage (179 of 896 entries translated), with 717 entries using English placeholders.

Per coding guidelines, all 6 language locales should have full translations. These new strings need Italian translations, but that's part of a much larger gap in this file that should be addressed systematically rather than piecemeal.

🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/it-IT.po` around lines 777 - 787, The Italian
locale file it-IT.po has many untranslated entries (only ~20% translated) and
the three new strings from ProjectPortalEditor.tsx ("Anonymize Transcripts") and
ConversationAccordion.tsx ("anonymized conversation" / "Anonymized
conversation") are still English; update those msgstr values to proper Italian
translations (e.g., "Anonymizza le trascrizioni" and "conversazione
anonimizzata"/"Conversazione anonimizzata" as appropriate), then run your i18n
tooling (msgfmt/poedit or your pipeline) to validate the .po file, and perform a
systematic audit to translate the remaining 717 placeholders so that all six
locale files reach full translation coverage per guidelines.

Comment on lines +4971 to 4973
#: src/components/project/ProjectPortalEditor.tsx:894
msgid "Verify Topics"
msgstr "Verifiëren Themen"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug: "Themen" is German, not Dutch.

Verifiëren Themen mixes German ("Themen") into the Dutch locale. The correct Dutch word for "Topics" is "Onderwerpen".

🐛 Fix
 msgid "Verify Topics"
-msgstr "Verifiëren Themen"
+msgstr "Verifiëren Onderwerpen"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#: src/components/project/ProjectPortalEditor.tsx:894
msgid "Verify Topics"
msgstr "Verifiëren Themen"
#: src/components/project/ProjectPortalEditor.tsx:894
msgid "Verify Topics"
msgstr "Verifiëren Onderwerpen"
🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/nl-NL.po` around lines 4971 - 4973, The translation
for msgid "Verify Topics" is incorrect: msgstr currently uses German "Themen";
update the Dutch translation in nl-NL.po by replacing the msgstr "Verifiëren
Themen" with the correct Dutch phrase "Verifiëren Onderwerpen" (the entry tied
to msgid "Verify Topics" referenced from ProjectPortalEditor.tsx).

Comment on lines +5164 to +5167
#: src/components/project/ProjectPortalEditor.tsx:1183
msgid "When enabled, all new transcripts will have personal information (names, emails, phone numbers, addresses) replaced with placeholders. Anonymized conversations also disable audio playback, audio download, and retranscription to protect participant privacy. This cannot be undone for already-processed conversations."
msgstr "Wanneer ingeschakeld, zullen alle nieuwe transcripties persoonlijke informatie (namen, e-mails, telefoonnummers, adressen) worden vervangen door placeholders. Anonieme gesprekken deactiveren ook audio-afspelen, audio-download en hertranscriptie om de privacy van deelnemers te beschermen. Dit kan niet ongedaan worden gemaakt voor al bestaande gesprekken."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: "al bestaande" doesn't match "already-processed".

The English source says "already-processed conversations" but the Dutch says "al bestaande gesprekken" (already-existing). Since the distinction matters (only processed conversations are irreversible, not merely existing ones), consider "al verwerkte gesprekken".

✏️ Suggested tweak
-msgstr "Wanneer ingeschakeld, zullen alle nieuwe transcripties persoonlijke informatie (namen, e-mails, telefoonnummers, adressen) worden vervangen door placeholders. Anonieme gesprekken deactiveren ook audio-afspelen, audio-download en hertranscriptie om de privacy van deelnemers te beschermen. Dit kan niet ongedaan worden gemaakt voor al bestaande gesprekken."
+msgstr "Wanneer ingeschakeld, zullen alle nieuwe transcripties persoonlijke informatie (namen, e-mails, telefoonnummers, adressen) worden vervangen door placeholders. Anonieme gesprekken deactiveren ook audio-afspelen, audio-download en hertranscriptie om de privacy van deelnemers te beschermen. Dit kan niet ongedaan worden gemaakt voor al verwerkte gesprekken."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#: src/components/project/ProjectPortalEditor.tsx:1183
msgid "When enabled, all new transcripts will have personal information (names, emails, phone numbers, addresses) replaced with placeholders. Anonymized conversations also disable audio playback, audio download, and retranscription to protect participant privacy. This cannot be undone for already-processed conversations."
msgstr "Wanneer ingeschakeld, zullen alle nieuwe transcripties persoonlijke informatie (namen, e-mails, telefoonnummers, adressen) worden vervangen door placeholders. Anonieme gesprekken deactiveren ook audio-afspelen, audio-download en hertranscriptie om de privacy van deelnemers te beschermen. Dit kan niet ongedaan worden gemaakt voor al bestaande gesprekken."
#: src/components/project/ProjectPortalEditor.tsx:1183
msgid "When enabled, all new transcripts will have personal information (names, emails, phone numbers, addresses) replaced with placeholders. Anonymized conversations also disable audio playback, audio download, and retranscription to protect participant privacy. This cannot be undone for already-processed conversations."
msgstr "Wanneer ingeschakeld, zullen alle nieuwe transcripties persoonlijke informatie (namen, e-mails, telefoonnummers, adressen) worden vervangen door placeholders. Anonieme gesprekken deactiveren ook audio-afspelen, audio-download en hertranscriptie om de privacy van deelnemers te beschermen. Dit kan niet ongedaan worden gemaakt voor al verwerkte gesprekken."
🤖 Prompt for AI Agents
In `@echo/frontend/src/locales/nl-NL.po` around lines 5164 - 5167, The Dutch
translation for the msgid in ProjectPortalEditor.tsx uses "al bestaande
gesprekken" which erroneously reads "already-existing" instead of
"already-processed"; update the msgstr in nl-NL.po (the entry for the long
anonymization description) to use "al verwerkte gesprekken" (or equivalent Dutch
phrasing meaning "already-processed conversations") so it matches the English
source semantics.

Comment on lines +63 to +65
/* Note: [data-disabled] is needed for anchor-based buttons (component="a") which lack :disabled */
.root:disabled:not([data-loading="true"]),
.root[data-disabled]:not([data-loading="true"]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Stylelint flags missing empty line before comment on Line 63.

Static analysis caught this. Easy fix to keep CI green.

🔧 Proposed fix
 	cursor: not-allowed;
 	pointer-events: all; /* Allow hover/active on disabled anchor buttons */
 }
 
+
 /* Note: [data-disabled] is needed for anchor-based buttons (component="a") which lack :disabled */
 .root:disabled:not([data-loading="true"]),
 .root[data-disabled]:not([data-loading="true"]) {

Wait — the comment is inside the rule block. Let me re-read. Actually the comment is on Line 63, which comes right before the selector on Lines 64-65. The fix would be:

 }
 
+
 /* Note: [data-disabled] is needed for anchor-based buttons (component="a") which lack :disabled */
 .root:disabled:not([data-loading="true"]),
🧰 Tools
🪛 Stylelint (17.2.0)

[error] 63-63: Expected empty line before comment (comment-empty-line-before)

(comment-empty-line-before)

🤖 Prompt for AI Agents
In `@echo/frontend/src/styles/button.module.css` around lines 63 - 65, Stylelint
reports a missing empty line before the comment preceding the .root selector;
fix by inserting a single blank line immediately before the comment block "/*
Note: [data-disabled]..." so the comment is separated from the previous CSS
rule, ensuring the selector block that starts with
".root:disabled:not([data-loading="true"])," and
".root[data-disabled]:not([data-loading="true"])" follows the blank line and
satisfies the stylelint empty-line-before-comment rule.

@ussaama ussaama requested a review from spashii February 13, 2026 11:08
@ussaama ussaama added this pull request to the merge queue Feb 13, 2026
Merged via the queue into main with commit 2261bcf Feb 13, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants