feat: multilingual glossary templates + inline GlossarySelector rewrite
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m28s

- Enriched 8 glossary templates with 18,191 translations across 11 languages
  using LLM batch generation + back-translation validation (99.98% confirmed)
- Rewrote GlossarySelector as inline section with template creation
- Fixed sidebar duplicate (single Glossaries link with proOnly flag)
- Added glossaryId reset when sourceLang changes
- Always show GlossarySelector (locked with Pro badge for free users)
- Added source_language flag on glossary cards
- Redirected /dashboard/context to /dashboard/glossaries
- Updated import endpoint to read translations from templates
- Added enrichment script (scripts/enrich_glossary_templates.py)
- Added 6 i18n keys across all 13 locales

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 00:52:24 +02:00
parent 9be640c449
commit ca8abc560d
19 changed files with 28747 additions and 2029 deletions

View File

@@ -721,6 +721,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Select a glossary",
"translate.glossary.none": "None",
"translate.glossary.terms": "terms",
"translate.glossary.proOnly": "Upgrade to Pro to use glossaries",
"translate.glossary.myGlossaries": "My glossaries",
"translate.glossary.fromTemplate": "Create from template",
"translate.glossary.noGlossaryForPair": "No glossary for",
"translate.glossary.noGlossaries": "No glossaries yet",
"translate.glossary.loading": "Loading...",
"context.presets.createGlossary": "Create glossary",
"context.presets.created": "Glossary created",
"context.presets.createdDesc": "The glossary \"{name}\" has been created with {count} terms.",
@@ -1508,6 +1514,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Sélectionner un glossaire",
"translate.glossary.none": "Aucun",
"translate.glossary.terms": "termes",
"translate.glossary.proOnly": "Passez à Pro pour utiliser les glossaires",
"translate.glossary.myGlossaries": "Mes glossaires",
"translate.glossary.fromTemplate": "Créer depuis un template",
"translate.glossary.noGlossaryForPair": "Aucun glossaire pour",
"translate.glossary.noGlossaries": "Aucun glossaire",
"translate.glossary.loading": "Chargement...",
"context.presets.createGlossary": "Créer le glossaire",
"context.presets.created": "Glossaire créé",
"context.presets.createdDesc": "Le glossaire \"{name}\" a été créé avec {count} termes.",
@@ -2241,6 +2253,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Seleccionar glosario",
"translate.glossary.none": "Ninguno",
"translate.glossary.terms": "términos",
"translate.glossary.proOnly": "Actualiza a Pro para usar glosarios",
"translate.glossary.myGlossaries": "Mis glosarios",
"translate.glossary.fromTemplate": "Crear desde plantilla",
"translate.glossary.noGlossaryForPair": "Sin glosario para",
"translate.glossary.noGlossaries": "Sin glosarios",
"translate.glossary.loading": "Cargando...",
"context.presets.createGlossary": "Crear glosario",
"context.presets.created": "Glosario creado",
"context.presets.createdDesc": "El glosario \"{name}\" ha sido creado con {count} términos.",
@@ -2972,6 +2990,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Glossar auswählen",
"translate.glossary.none": "Keins",
"translate.glossary.terms": "Begriffe",
"translate.glossary.proOnly": "Upgraden Sie auf Pro für Glossare",
"translate.glossary.myGlossaries": "Meine Glossare",
"translate.glossary.fromTemplate": "Aus Vorlage erstellen",
"translate.glossary.noGlossaryForPair": "Kein Glossar für",
"translate.glossary.noGlossaries": "Keine Glossare",
"translate.glossary.loading": "Laden...",
"context.presets.createGlossary": "Glossar erstellen",
"context.presets.created": "Glossar erstellt",
"context.presets.createdDesc": "Das Glossar \"{name}\" wurde mit {count} Begriffen erstellt.",
@@ -3703,6 +3727,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Selecionar glossário",
"translate.glossary.none": "Nenhum",
"translate.glossary.terms": "termos",
"translate.glossary.proOnly": "Atualize para Pro para usar glossários",
"translate.glossary.myGlossaries": "Meus glossários",
"translate.glossary.fromTemplate": "Criar do modelo",
"translate.glossary.noGlossaryForPair": "Sem glossário para",
"translate.glossary.noGlossaries": "Sem glossários",
"translate.glossary.loading": "Carregando...",
"context.presets.createGlossary": "Criar glossário",
"context.presets.created": "Glossário criado",
"context.presets.createdDesc": "O glossário \"{name}\" foi criado com {count} termos.",
@@ -4434,6 +4464,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Seleziona glossario",
"translate.glossary.none": "Nessuno",
"translate.glossary.terms": "termini",
"translate.glossary.proOnly": "Passa a Pro per usare i glossari",
"translate.glossary.myGlossaries": "I miei glossari",
"translate.glossary.fromTemplate": "Crea da modello",
"translate.glossary.noGlossaryForPair": "Nessun glossario per",
"translate.glossary.noGlossaries": "Nessun glossario",
"translate.glossary.loading": "Caricamento...",
"context.presets.createGlossary": "Crea glossario",
"context.presets.created": "Glossario creato",
"context.presets.createdDesc": "Il glossario \"{name}\" è stato creato con {count} termini.",
@@ -5165,6 +5201,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Woordenlijst selecteren",
"translate.glossary.none": "Geen",
"translate.glossary.terms": "termen",
"translate.glossary.proOnly": "Upgrade naar Pro voor woordenlijsten",
"translate.glossary.myGlossaries": "Mijn woordenlijsten",
"translate.glossary.fromTemplate": "Van sjabloon maken",
"translate.glossary.noGlossaryForPair": "Geen woordenlijst voor",
"translate.glossary.noGlossaries": "Geen woordenlijsten",
"translate.glossary.loading": "Laden...",
"context.presets.createGlossary": "Woordenlijst maken",
"context.presets.created": "Woordenlijst gemaakt",
"context.presets.createdDesc": "De woordenlijst \"{name}\" is gemaakt met {count} termen.",
@@ -5898,6 +5940,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "Выбрать глоссарий",
"translate.glossary.none": "Нет",
"translate.glossary.terms": "терминов",
"translate.glossary.proOnly": "Обновитесь до Pro для использования глоссариев",
"translate.glossary.myGlossaries": "Мои глоссарии",
"translate.glossary.fromTemplate": "Создать из шаблона",
"translate.glossary.noGlossaryForPair": "Нет глоссария для",
"translate.glossary.noGlossaries": "Нет глоссариев",
"translate.glossary.loading": "Загрузка...",
"context.presets.createGlossary": "Создать глоссарий",
"context.presets.created": "Глоссарий создан",
"context.presets.createdDesc": "Глоссарий \"{name}\" создан с {count} терминами.",
@@ -6628,6 +6676,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "用語集を選択",
"translate.glossary.none": "なし",
"translate.glossary.terms": "件",
"translate.glossary.proOnly": "Proにアップグレードして用語集を使用",
"translate.glossary.myGlossaries": "マイ用語集",
"translate.glossary.fromTemplate": "テンプレートから作成",
"translate.glossary.noGlossaryForPair": "用語集なし",
"translate.glossary.noGlossaries": "用語集なし",
"translate.glossary.loading": "読み込み中...",
"context.presets.createGlossary": "用語集を作成",
"context.presets.created": "用語集を作成しました",
"context.presets.createdDesc": "用語集「{name}」を{count}件の用語で作成しました。",
@@ -7358,6 +7412,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "용어집 선택",
"translate.glossary.none": "없음",
"translate.glossary.terms": "개",
"translate.glossary.proOnly": "Pro로 업그레이드하여 용어집 사용",
"translate.glossary.myGlossaries": "내 용어집",
"translate.glossary.fromTemplate": "템플릿에서 만들기",
"translate.glossary.noGlossaryForPair": "용어집 없음",
"translate.glossary.noGlossaries": "용어집 없음",
"translate.glossary.loading": "로딩 중...",
"context.presets.createGlossary": "용어집 만들기",
"context.presets.created": "용어집 생성됨",
"context.presets.createdDesc": "용어집 \"{name}\"이(가) {count}개의 용어로 생성되었습니다.",
@@ -8046,6 +8106,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "选择术语表",
"translate.glossary.none": "无",
"translate.glossary.terms": "个术语",
"translate.glossary.proOnly": "升级到Pro以使用术语表",
"translate.glossary.myGlossaries": "我的术语表",
"translate.glossary.fromTemplate": "从模板创建",
"translate.glossary.noGlossaryForPair": "无术语表",
"translate.glossary.noGlossaries": "无术语表",
"translate.glossary.loading": "加载中...",
"context.presets.createGlossary": "创建术语表",
"context.presets.created": "术语表已创建",
"context.presets.createdDesc": "术语表 \"{name}\" 已创建,包含 {count} 个术语。",
@@ -8734,6 +8800,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "اختر مسرداً",
"translate.glossary.none": "بدون",
"translate.glossary.terms": "مصطلحات",
"translate.glossary.proOnly": "قم بالترقية إلى Pro لاستخدام المصطلحات",
"translate.glossary.myGlossaries": "مصطلحاتي",
"translate.glossary.fromTemplate": "إنشاء من قالب",
"translate.glossary.noGlossaryForPair": "لا مصطلحات لـ",
"translate.glossary.noGlossaries": "لا مصطلحات",
"translate.glossary.loading": "جاري التحميل...",
"context.presets.createGlossary": "إنشاء مسرد",
"context.presets.created": "تم إنشاء المسرد",
"context.presets.createdDesc": "تم إنشاء المسرد \"{name}\" بـ {count} مصطلحات.",
@@ -9458,6 +9530,12 @@ const messages: Record<Locale, Record<string, string>> = {
"translate.glossary.select": "انتخاب واژه‌نامه",
"translate.glossary.none": "هیچکدام",
"translate.glossary.terms": "واژه",
"translate.glossary.proOnly": "ارتقا به Pro برای استفاده از واژه‌نامه",
"translate.glossary.myGlossaries": "واژه‌نامه‌های من",
"translate.glossary.fromTemplate": "ایجاد از قالب",
"translate.glossary.noGlossaryForPair": "واژه‌نامه‌ای برای",
"translate.glossary.noGlossaries": "واژه‌نامه‌ای نیست",
"translate.glossary.loading": "در حال بارگذاری...",
"context.presets.createGlossary": "ایجاد واژه‌نامه",
"context.presets.created": "واژه‌نامه ایجاد شد",
"context.presets.createdDesc": "واژه‌نامه \"{name}\" با {count} واژه ایجاد شد.",