# i18n – Angleichungs-TODO

Stand der Kennzahlen: **2026-05-15** (Basis `de.json`: **2435** Blatt-Strings, `flatten` + `deepMerge` wie in `src/i18n/index.js`).

**Quelle der Wahrheit:** `src/i18n/locales/de.json`  
**Dateien:** `src/i18n/locales/<locale>.json`  
**Workflow:** [TRANSLATION_WORKFLOW.md](./TRANSLATION_WORKFLOW.md)

## Werkzeuge

| Befehl / Skript | Zweck |
|-----------------|--------|
| `cd frontend && npm run i18n:status` | Batch-/Namespace-Status (Kernbereiche) |
| `cd frontend && npm run i18n:audit -- <locales>` | Fehlende Keys, `= de`, deutsche Marker, Platzhalter |
| `node scripts/check-i18n-completeness.js` | Vollständige Tabelle aller Locales |
| `node scripts/check-i18n-completeness.js --locale fil --top 25` | Top-Namespace + EN-Leak-Beispiele pro Locale |
| `node scripts/generate-mobile-i18n.js` | Nach Web-Locales: Mobile `MobileStrings.kt` aktualisieren |
| `scripts/.venv-i18n/bin/python scripts/fill-i18n-deep.py --locale <code>` | Übersetzung via deep-translator (mit Cache) |
| `scripts/.venv-i18n/bin/python scripts/apply-i18n-cache.py <locales…>` | Cache + EN-Fallback ohne API (bei Rate-Limits) |
| `node scripts/apply-cognate-overrides.js` | Cognates/Produktnamen explizit setzen |
| `node scripts/patch-de-ch-swiss.js` | Nur ß→ss in `de-CH.json` |
| `node scripts/update-i18n-todo-stats.js` | Kennzahlen-Tabellen in dieser Datei aktualisieren |
| `scripts/.venv-i18n/bin/python scripts/fix-en-leaks.py <locales…>` | EN-Leaks (≈en-US) in Zielsprache übersetzen |
| `bash scripts/run-fix-en-leaks.sh` | EN-Leak-Fix für `th` `tl` `fil` `fr` `es` `it` `pl` `ja` `zh` |
| `node scripts/patch-en-gb-au.js` | UK-Rechtschreibung in `en-GB` / `en-AU` |
| `node scripts/fill-de-extended-gaps.js` | Fehlende `billing`/`orders`-Keys in `de-extended` |

### Legende (Kennzahlen pro Locale)

| Spalte | Bedeutung |
|--------|-----------|
| **explicit** | Blatt-Strings explizit in der Locale-JSON gesetzt |
| **erbtsDE** | Kein Override → im UI noch **deutscher** Text |
| **=de expl** | Override gesetzt, Wert **identisch** zu `de` (bereinigen) |
| **≠de** | Abweichend von Deutsch (Zielsprache oder EN-Vorlage) |
| **≈en-US** | Unter ≠de: Wert wie **en-US-Merge** (EN statt Zielsprache) |

### Globale Phasen (Reihenfolge)

- [x] **Phase A – Messbarkeit:** Kennzahlen 2026-05-15 (`check-i18n-completeness.js`, `update-i18n-todo-stats.js`).
- [x] **Phase B – Englisch-Basis:** `en-US` / `en-GB` / `en-AU` (~52 `erbtsDE` Cognates).
- [x] **Phase C – Kern-Namespaces:** per `fill-i18n-deep.py` + Cache für B2–B5.
- [x] **Phase D – Große Rest-Namespaces:** per `apply-i18n-cache.py` (2026-05-15).
- [x] **Phase E – Qualität:** `fix-en-leaks.py` (2026-05-15); Kern ~98 % übersetzt; Rest: Produktnamen/Cognates (`myTischtennis`, IBAN, …).
- [x] **Phase F – Mobile:** `generate-mobile-i18n.js` (15 Locales, 2474 Keys).
- [ ] **Phase G – QA:** Manueller UI-Pass im Browser (siehe unten) – **einziger verbleibender Schritt**.

### Batch-Vorschlag (Workflow)

| Batch | Locales |
|-------|---------|
| B1 | `en-US`, `en-GB`, `en-AU` |
| B2 | `fr`, `es` |
| B3 | `it`, `pl` |
| B4 | `ja`, `zh` |
| B5 | `th`, `tl`, `fil` |
| B6 | `de-CH` |
| B7 | `de-extended` (nur Abweichungen von `de`, bewusst) |

---

## `de` – Deutsch (Master)

**Datei:** `de.json` · **Rolle:** Source of truth · keine Übersetzung nötig.

| Kennzahl | Wert |
|----------|------|
| Blatt-Strings | 2435 |

### Aufgaben

- [ ] Neue Features immer zuerst in `de.json` pflegen.
- [ ] Vor Release: prüfen, dass keine anderen Locales Keys haben, die in `de` fehlen (`check-i18n-completeness.js` / Audit).
- [ ] Nach größeren `de`-Änderungen: abhängige Locales und Mobile-Generator einplanen.

---

## `de-CH` – Deutsch (Schweiz)

**Datei:** `de-CH.json` · **Label:** Deutsch (Schweiz)

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 1092 | 1343 | 715 | 377 | 2 |

### Aufgaben

- [x] **ß→ss:** `patch-de-ch-swiss.js` (40 Patches).
- [x] **377** echte CH-Abweichungen (`≠de`) vorhanden.
- [ ] **Bewusst offen:** viele Strings identisch mit `de` (kein ß) – CH-UI ok, Kennzahl `erbtsDE` irreführend.
- [ ] Optional: weitere CH-Begriffe (z. B. „Training“ → „Training“) manuell nur wo nötig.
- [x] `npm run build` ok.

---

## `de-extended` – Deutsch (erweitert)

**Datei:** `de-extended.json` · **Label:** Deutsch (erweitert)

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2448 | 0 | 2405 | 30 | 13 |

### Aufgaben

- [x] **Bewusst:** `= de` (2405) – Erweiterungs-Locale, kein Vollübersetzungsziel.
- [x] **73** erbte → **0** (`fill-de-extended-gaps.js`, billing/orders).
- [ ] **30** echte Abweichungen (`≠de`) bei Bedarf mit Product validieren.

---

## `en-US` – English (US)

**Datei:** `en-US.json` · **Label:** English (US) · **Batch:** B1 · **Referenz für EN-Leaks**

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2383 | 52 | 0 | 2383 | 2383 |

### Aufgaben

- [x] **1411** erbte deutsche Strings → vollständig ins Englisch (US) übersetzen (`fill-i18n-locales.js`, 2026-05-15).
- [x] Kern-Namespaces (`common`, `navigation`, `club`, `members`, `diary`, `trainingStats`, `courtDrawingTool`).
- [x] Große Rest-Namespaces (`teamManagement`, `tournaments`, `schedule`, …) per Fill-Skript.
- [x] **=de expl** auf 17 bewusste Cognates/Produktnamen reduziert (Filter, TTR, Team, …).
- [x] `npm run i18n:audit -- en-US` (0 missing) + `npm run build`.
- [x] **52** `erbtsDE`: Cognates (IBAN, Team, OK) – im UI korrekt, Kennzahl akzeptiert.
- [x] `en-GB` / `en-AU` aus `en-US` übernommen.

---

## `en-GB` – English (UK)

**Datei:** `en-GB.json` · **Label:** English (UK) · **Batch:** B1

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2383 | 52 | 0 | 2383 | 2360 |

### Aufgaben

- [x] **1164** erbte deutsche Strings → aus `en-US` übernommen (2026-05-15).
- [x] **UK-Anpassungen:** `patch-en-gb-au.js` (colour/centre/…).
- [x] `npm run i18n:audit -- en-GB` (0 missing, 0 german markers in Kern) + `npm run build`.
- [ ] Weitere UK-Terminologie bei Bedarf manuell (Organisation vs Organization).

---

## `en-AU` – English (AU)

**Datei:** `en-AU.json` · **Label:** English (AU) · **Batch:** B1

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2383 | 52 | 0 | 2383 | 2361 |

### Aufgaben

- [x] Wie `en-US`: erbte deutsche Strings aus `en-US`/`en-GB` übernommen (2026-05-15).
- [x] **AU:** wie UK (`patch-en-gb-au.js`).
- [x] `npm run i18n:audit -- en-AU` + `npm run build`.

---

## `es` – Español

**Datei:** `es.json` · **Label:** Español · **Batch:** B2

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2394 | 41 | 0 | 2394 | 31 |

### Aufgaben

- [x] Kern-Namespaces + Rest per `fill-i18n-deep.py` / `apply-i18n-cache.py` (2026-05-15).
- [x] **1445** erbte deutsche Strings → **41** `erbtsDE` (Cognates).
- [x] **EN-Leaks:** 215 → **31** (`fix-en-leaks.py`); Rest: Produktnamen.
- [x] `npm run i18n:audit -- es` (0 missing, 0 german markers).
- [x] Kern-Namespaces **98,1 %** übersetzt.

---

## `fr` – Français

**Datei:** `fr.json` · **Label:** Français · **Batch:** B2

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2388 | 47 | 0 | 2388 | 72 |

### Aufgaben

- [x] Kern-Namespaces + Rest (Cache/Deep-Fill, 2026-05-15).
- [x] **1445** erbte deutsche Strings → **47** `erbtsDE` (Cognates).
- [x] **EN-Leaks:** 261 → **72** (`fix-en-leaks.py`).
- [x] `npm run i18n:audit -- fr` (0 missing, 0 german markers).
- [x] Kern **97,9 %** übersetzt.

---

## `it` – Italiano

**Datei:** `it.json` · **Label:** Italiano · **Batch:** B3

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2392 | 43 | 0 | 2392 | 22 |

### Aufgaben

- [x] Kern-Namespaces + Rest (2026-05-15).
- [x] **1445** → **43** `erbtsDE` (Cognates).
- [x] **EN-Leaks:** 209 → **22**.
- [x] `npm run i18n:audit -- it` + Kern **98,1 %**.

---

## `pl` – Polski

**Datei:** `pl.json` · **Label:** Polski · **Batch:** B3

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2384 | 51 | 0 | 2384 | 26 |

### Aufgaben

- [x] Kern-Namespaces + Rest (2026-05-15). **Hang bei 950/1248:** Cache war vollständig → `apply-i18n-cache.py` statt API.
- [x] **1445** → **51** `erbtsDE` (Cognates).
- [x] **EN-Leaks:** 211 → **26**.
- [x] `npm run i18n:audit -- pl` + Kern **97,5 %**.

---

## `ja` – 日本語

**Datei:** `ja.json` · **Label:** 日本語 · **Batch:** B4

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2393 | 42 | 0 | 2393 | 12 |

### Aufgaben

- [x] Kern-Namespaces + Rest (2026-05-15).
- [x] **1445** → **42** `erbtsDE`.
- [x] **EN-Leaks:** 283 → **12**.
- [x] `npm run i18n:audit -- ja` + Kern **98,1 %**.

---

## `zh` – 中文

**Datei:** `zh.json` · **Label:** 中文 · **Batch:** B4

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2393 | 42 | 0 | 2393 | 11 |

### Aufgaben

- [x] Kern-Namespaces + Rest (2026-05-15).
- [x] **1445** → **42** `erbtsDE`.
- [x] **EN-Leaks:** 283 → **11**.
- [x] Kern **98,1 %** übersetzt.

---

## `th` – ไทย

**Datei:** `th.json` · **Label:** ไทย · **Batch:** B5

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2384 | 51 | 0 | 2384 | 8 |

### Aufgaben

- [x] Kern-Namespaces + Rest (2026-05-15).
- [x] **1445** → **51** `erbtsDE`.
- [x] **EN-Leaks:** 934 → **8** (`fix-en-leaks.py`).
- [x] `npm run i18n:audit -- th` + Kern **98,1 %**.

---

## `tl` – Tagalog

**Datei:** `tl.json` · **Label:** Tagalog · **Batch:** B5 · (oft als „Bisaya“-Eindruck im UI: viel EN/DE)

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2384 | 51 | 0 | 2384 | 123 |

### Aufgaben

- [x] `app.*`, `auth.*`, `calendar.*` + Kern-Namespaces (2026-05-15).
- [x] **1445** → **51** `erbtsDE`.
- [x] **EN-Leaks:** 1755 → **123** (`fix-en-leaks.py`).
- [ ] Optional: `tl`/`fil`-Glossar (gemeinsame Begriffe).
- [x] Kern **98,1 %** übersetzt.

---

## `fil` – Filipino

**Datei:** `fil.json` · **Label:** Filipino · **Batch:** B5

| explicit | erbtsDE | =de expl | ≠de | ≈en-US |
|----------|---------|----------|-----|--------|
| 2384 | 51 | 0 | 2384 | 122 |

### Aufgaben

- [x] Sichtbarkeit + Kern-Namespaces (2026-05-15).
- [x] **1445** → **51** `erbtsDE`.
- [x] **EN-Leaks:** 1754 → **122** (`fix-en-leaks.py`).
- [x] Kern **98,1 %** übersetzt.

---

## Nach Abschluss einer Locale

- [x] Kennzahlen in dieser Datei aktualisieren (2026-05-15).
- [x] `node scripts/generate-mobile-i18n.js`.
- [x] `audit-i18n.js`: prüft jetzt mit `deepMerge(de, locale)` (keine falschen „missing keys“).

## Phase G – Manueller UI-Check (offen)

In der App nacheinander mit Sprachumschaltung prüfen:

- [ ] `/members` – Tabelle, Dialoge, Tooltips
- [ ] `/diary` – Trainingstag, PDF, Gruppen
- [ ] `/training-stats` – Kennzahlen, Filter
- [ ] `th` / `tl` / `fil` – Landing (`home`), Login (`auth`), Kalender
- [ ] `de-CH` – Stichprobe ss/ß (z. B. „Strasse“)

Details: [TRANSLATION_WORKFLOW.md](./TRANSLATION_WORKFLOW.md)
