173 lines
7.7 KiB
Markdown
173 lines
7.7 KiB
Markdown
---
|
|
phase: 34-i18n-foundation
|
|
plan: 07
|
|
type: execute
|
|
wave: 4
|
|
depends_on: [05]
|
|
files_modified:
|
|
- src/client/locales/de/common.json
|
|
- src/client/locales/de/collection.json
|
|
- src/client/locales/de/threads.json
|
|
- src/client/locales/de/setups.json
|
|
- src/client/locales/de/onboarding.json
|
|
- src/client/locales/de/settings.json
|
|
autonomous: true
|
|
gap_closure: true
|
|
requirements: [D-13, D-14]
|
|
|
|
must_haves:
|
|
truths:
|
|
- "All German locale files use proper umlauts (ä, ö, ü, Ä, Ö, Ü, ß) instead of ASCII fallbacks (ae, oe, ue)"
|
|
- "No instances of 'Loeschen', 'Zurueck', 'Bestaetigen', 'Schliessen', 'Gegenstaende', 'Ausruestung', 'Waehrung', 'Schluessel' remain"
|
|
- "German translations read naturally to a German speaker"
|
|
- "Key parity test still passes after corrections"
|
|
artifacts:
|
|
- path: "src/client/locales/de/common.json"
|
|
provides: "German common translations with proper umlauts"
|
|
contains: "Löschen"
|
|
- path: "src/client/locales/de/collection.json"
|
|
provides: "German collection translations with proper umlauts"
|
|
contains: "Gegenstände"
|
|
- path: "src/client/locales/de/settings.json"
|
|
provides: "German settings translations with proper umlauts"
|
|
contains: "Währung"
|
|
key_links:
|
|
- from: "src/client/lib/i18n.ts"
|
|
to: "src/client/locales/de/common.json"
|
|
via: "import deCommon"
|
|
pattern: "deCommon"
|
|
---
|
|
|
|
<objective>
|
|
Fix all German locale files to use proper Unicode umlauts instead of ASCII fallbacks.
|
|
|
|
Purpose: UAT test 4 reported that German text uses "ae" instead of "ä", "oe" instead of "ö", "ue" instead of "ü", and similar. All 6 German JSON files were generated with ASCII approximations instead of proper German characters. This plan does a complete pass through every German locale file and replaces every ASCII fallback with the correct Unicode character.
|
|
Output: All 6 de/*.json files with proper German umlauts (ä, ö, ü, Ä, Ö, Ü, ß).
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/34-i18n-foundation/34-CONTEXT.md
|
|
@.planning/phases/34-i18n-foundation/34-UAT.md
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Replace ASCII fallbacks with proper umlauts in all 6 German locale files</name>
|
|
<files>src/client/locales/de/common.json, src/client/locales/de/collection.json, src/client/locales/de/threads.json, src/client/locales/de/setups.json, src/client/locales/de/onboarding.json, src/client/locales/de/settings.json</files>
|
|
<read_first>src/client/locales/de/common.json, src/client/locales/de/collection.json, src/client/locales/de/threads.json, src/client/locales/de/setups.json, src/client/locales/de/onboarding.json, src/client/locales/de/settings.json</read_first>
|
|
<action>
|
|
Read each German locale file fully. For every string value, replace ASCII umlaut approximations with proper Unicode characters. This is NOT a simple find-and-replace — you must check each word in context because "ae", "oe", "ue" are not always umlauts (e.g., "Israel" should not become "Israöl").
|
|
|
|
**Replacement rules (apply to German words only):**
|
|
- `ae` → `ä` when it represents an umlaut (Loeschen → Löschen, Gegenstaende → Gegenstände, Waehrung → Währung, Aenderung → Änderung)
|
|
- `oe` → `ö` when it represents an umlaut (Loeschen → Löschen, Groesse → Größe)
|
|
- `ue` → `ü` when it represents an umlaut (Zurueck → Zurück, Ausruestung → Ausrüstung, Ueberpruefen → Überprüfen, Stueck → Stück, hinzufuegen → hinzufügen)
|
|
- `Ae` → `Ä` at word start (Aenderung → Änderung)
|
|
- `Oe` → `Ö` at word start
|
|
- `Ue` → `Ü` at word start (Ueberpruefen → Überprüfen)
|
|
- `ss` → `ß` where appropriate in German (Schliessen → Schließen, Groesse → Größe, Strasse → Straße, weiss → weiß) — but NOT in compounds like "Impressum" or "Pressemitteilung"
|
|
|
|
**Known corrections (from UAT report and file inspection):**
|
|
- `Loeschen` → `Löschen`
|
|
- `Zurueck` → `Zurück`
|
|
- `Bestaetigen` → `Bestätigen`
|
|
- `Schliessen` → `Schließen`
|
|
- `Gegenstaende` → `Gegenstände`
|
|
- `Ausruestung` → `Ausrüstung`
|
|
- `Waehrung` → `Währung`
|
|
- `Schluessel` → `Schlüssel`
|
|
- `hinzufuegen` → `hinzufügen`
|
|
- `Hinzufuegen` → `Hinzufügen`
|
|
- `Ueberpruefen` → `Überprüfen`
|
|
- `verfuegbar` → `verfügbar`
|
|
- `Stueck` → `Stück`
|
|
- `Groesse` → `Größe`
|
|
- `aendern` → `ändern`
|
|
- `Aendern` → `Ändern`
|
|
- `aehnlich` → `ähnlich`
|
|
- `haeufig` → `häufig`
|
|
- `unterstuetzen` → `unterstützen`
|
|
- `Ernaehrung` → `Ernährung`
|
|
- `Geraet` → `Gerät`
|
|
- `Geraete` → `Geräte`
|
|
- `gewuenscht` → `gewünscht`
|
|
- `moeglich` → `möglich`
|
|
- `moeglicherweise` → `möglicherweise`
|
|
- `natuerlich` → `natürlich`
|
|
- `pruefen` → `prüfen`
|
|
- `Uebersicht` → `Übersicht`
|
|
- `Veroeffentlichen` → `Veröffentlichen`
|
|
- `oeffentlich` → `öffentlich`
|
|
- `Oeffentlich` → `Öffentlich`
|
|
- `wuenschen` → `wünschen`
|
|
- `fuer` → `für`
|
|
- `Fuer` → `Für`
|
|
- `ueber` → `über`
|
|
- `Ueber` → `Über`
|
|
|
|
**Process for each file:**
|
|
1. Read the entire file
|
|
2. Go through every string value
|
|
3. Identify every German word that uses ASCII umlaut approximation
|
|
4. Replace with proper Unicode umlaut
|
|
5. Write the corrected file
|
|
6. Ensure the file is valid JSON after corrections
|
|
|
|
**Also review for natural German phrasing.** While fixing umlauts, if you notice awkward or unnatural German translations, improve them. The goal (per D-14) is natural German, not word-for-word translation.
|
|
|
|
**Do NOT change:**
|
|
- JSON key names (only values)
|
|
- Interpolation variables: {{count}}, {{name}}, etc. must remain exactly as-is
|
|
- English loanwords used intentionally in German context (e.g., "Setup", "Thread", "Export", "Import", "CSV")
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/jlmak/Projects/jlmak/GearBox && echo "=== Checking for remaining ASCII fallbacks ===" && grep -r "Loeschen\|Zurueck\|Bestaetigen\|Schliessen\|Gegenstaende\|Ausruestung\|Waehrung\|Schluessel" src/client/locales/de/ && echo "FAIL: ASCII fallbacks still present" || echo "PASS: No known ASCII fallbacks found" && echo "=== Checking for proper umlauts ===" && grep -c "ä\|ö\|ü\|Ä\|Ö\|Ü\|ß" src/client/locales/de/common.json && echo "=== Key parity ===" && bun test tests/i18n/locales.test.ts 2>&1 | tail -5</automated>
|
|
</verify>
|
|
<done>All 6 German locale files use proper Unicode umlauts, no ASCII approximations remain, key parity test passes, German reads naturally</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<threat_model>
|
|
## Trust Boundaries
|
|
|
|
| Boundary | Description |
|
|
|----------|-------------|
|
|
| locale JSON→i18n | Static bundled files — trusted, no runtime injection vector |
|
|
|
|
## STRIDE Threat Register
|
|
|
|
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
|
|-----------|----------|-----------|-------------|-----------------|
|
|
| T-34-08 | Information Disclosure | de locale files | accept | Translation files contain only UI strings, no secrets. Same disposition as T-34-02 and T-34-06. |
|
|
</threat_model>
|
|
|
|
<verification>
|
|
- `grep -r "Loeschen\|Zurueck\|Bestaetigen\|Schliessen" src/client/locales/de/` returns no matches
|
|
- `grep -c "ä\|ö\|ü\|ß" src/client/locales/de/common.json` returns > 0
|
|
- All 6 de/*.json files are valid JSON
|
|
- `bun test tests/i18n/locales.test.ts` passes (key parity maintained)
|
|
- `bun run build` succeeds
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Every German locale file uses proper Unicode umlauts (ä, ö, ü, Ä, Ö, Ü, ß)
|
|
- Zero instances of known ASCII fallback patterns remain
|
|
- German translations read naturally
|
|
- Key parity test passes
|
|
- Build passes
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/34-i18n-foundation/34-07-SUMMARY.md`
|
|
</output>
|