---
phase: 34-i18n-foundation
plan: 08
type: execute
wave: 1
depends_on: []
files_modified:
  - src/client/locales/de/common.json
  - src/client/locales/de/settings.json
  - src/client/locales/de/threads.json
  - src/client/locales/de/setups.json
  - src/client/locales/de/collection.json
autonomous: true
gap_closure: true
requirements: []

must_haves:
  truths:
    - "All 58 missing German translation keys exist in the de/*.json files"
    - "bun test tests/i18n/locales.test.ts passes with 19 pass, 0 fail"
    - "German translations use proper Unicode umlauts, not ASCII fallbacks"
  artifacts:
    - path: "src/client/locales/de/common.json"
      provides: "German translations for home.*, imageUpload.*, profile.* sections"
      contains: "popularSetups"
    - path: "src/client/locales/de/settings.json"
      provides: "German translations for currency.suggestion, currency.switch, showConversions.*"
      contains: "showConversions"
    - path: "src/client/locales/de/threads.json"
      provides: "German translations for card.candidates, card.candidates_one, planning.*"
      contains: "planning"
    - path: "src/client/locales/de/setups.json"
      provides: "German translations for card.by, card.anonymous, impact.compareWith"
      contains: "compareWith"
    - path: "src/client/locales/de/collection.json"
      provides: "German translations for tabs.setups, totals.*, classificationBadge.*"
      contains: "classificationBadge"
  key_links:
    - from: "src/client/locales/de/common.json"
      to: "src/client/locales/en/common.json"
      via: "key parity — every en key must have a de key"
      pattern: "home|imageUpload|profile"
---

<objective>
Add the 58 missing German translations to 5 de/*.json locale files to achieve full key parity with the English locale files.

Purpose: Close the gap from VERIFICATION.md — plans 34-06/34-07 wired useTranslation into routes and fixed umlaut encoding, but never added the corresponding German translations for the new English keys. German users currently see English fallbacks for the home page, profile, thread cards, setup cards, totals bar, and classification badges.

Output: All 5 German locale files with complete key parity. The i18n key parity test passes (19 pass, 0 fail).
</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-VERIFICATION.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add 58 missing German translations to 5 de/*.json files</name>
  <files>
    src/client/locales/de/common.json,
    src/client/locales/de/settings.json,
    src/client/locales/de/threads.json,
    src/client/locales/de/setups.json,
    src/client/locales/de/collection.json
  </files>
  <read_first>
    src/client/locales/en/common.json,
    src/client/locales/de/common.json,
    src/client/locales/en/settings.json,
    src/client/locales/de/settings.json,
    src/client/locales/en/threads.json,
    src/client/locales/de/threads.json,
    src/client/locales/en/setups.json,
    src/client/locales/de/setups.json,
    src/client/locales/en/collection.json,
    src/client/locales/de/collection.json,
    tests/i18n/locales.test.ts
  </read_first>
  <action>
Add the following German translations to each file. Read the corresponding en/*.json file first to confirm exact key names, then add the missing keys to the de/*.json file. Use proper Unicode umlauts throughout.

**de/common.json** — Add these 3 sections (34 keys) after the existing "filter" section:

```json
"home": {
  "popularSetups": "Beliebte Setups",
  "recentlyAdded": "Kürzlich hinzugefügt",
  "trendingCategories": "Beliebte Kategorien"
},
"imageUpload": {
  "clickToAdd": "Klicken, um Foto hinzuzufügen",
  "invalidType": "Bitte wählen Sie ein JPG-, PNG- oder WebP-Bild.",
  "tooLarge": "Das Bild muss kleiner als 5 MB sein.",
  "uploadFailed": "Upload fehlgeschlagen. Bitte versuchen Sie es erneut."
},
"profile": {
  "title": "Profil",
  "account": "Konto",
  "accountInfo": "Ihre Kontoinformationen",
  "email": "E-Mail",
  "noEmail": "Keine E-Mail hinterlegt",
  "change": "Ändern",
  "newEmailPlaceholder": "Neue E-Mail-Adresse",
  "updating": "Wird aktualisiert...",
  "updateEmail": "E-Mail aktualisieren",
  "emailUpdated": "E-Mail aktualisiert",
  "memberSince": "Mitglied seit",
  "security": "Sicherheit",
  "managePassword": "Passwort verwalten",
  "currentPassword": "Aktuelles Passwort",
  "newPassword": "Neues Passwort",
  "password": "Passwort",
  "confirmPassword": "Passwort bestätigen",
  "passwordRequirements": "Das Passwort muss mindestens 8 Zeichen mit Groß-, Kleinbuchstaben und einer Zahl enthalten.",
  "passwordUpdated": "Passwort aktualisiert",
  "changingPassword": "Wird geändert...",
  "changePassword": "Passwort ändern",
  "setPassword": "Passwort festlegen",
  "dangerZone": "Gefahrenzone",
  "dangerZoneDescription": "Löschen Sie Ihr Konto und alle persönlichen Daten. Öffentliche Setups werden als „Gelöschter Benutzer" angezeigt.",
  "deleteAccount": "Konto löschen",
  "deleteConfirmMessage": "Diese Aktion ist dauerhaft. Geben Sie DELETE zur Bestätigung ein.",
  "deleteConfirmPlaceholder": "DELETE zur Bestätigung eingeben"
}
```

**de/settings.json** — Add these 4 keys. Inside the existing "currency" object, add "suggestion" and "switch". Add a new "showConversions" object:

```json
"currency": {
  ... existing keys ...,
  "suggestion": "Basierend auf Ihrer Region empfehlen wir {{symbol}} ({{code}})",
  "switch": "Wechseln"
},
"showConversions": {
  "title": "Umgerechnete Preise anzeigen",
  "description": "Zeigt ungefähre Umrechnungen an, wenn der lokale Preis nicht verfügbar ist"
}
```

**de/threads.json** — Add these 11 keys. Add a "card" section and a "planning" section:

```json
"card": {
  "candidates": "{{count}} Kandidaten",
  "candidates_one": "{{count}} Kandidat"
},
"planning": {
  "title": "Planungs-Threads",
  "emptyTitle": "Planen Sie Ihren nächsten Kauf",
  "createFirst": "Erstellen Sie Ihren ersten Thread",
  "step1Title": "Thread erstellen",
  "step1Description": "Starten Sie einen Recherche-Thread für Ausrüstung, die Sie in Betracht ziehen",
  "step2Title": "Kandidaten hinzufügen",
  "step2Description": "Fügen Sie Produkte zum Vergleich mit Preisen und Gewichten hinzu",
  "step3Title": "Gewinner wählen",
  "step3Description": "Schließen Sie den Thread ab und der Gewinner wird Ihrer Sammlung hinzugefügt"
}
```

**de/setups.json** — Add these 3 keys. Inside the existing "card" object add "by" and "anonymous". Inside the existing "impact" object add "compareWith":

```json
"card": {
  ... existing keys ...,
  "by": "von {{name}}",
  "anonymous": "Anonym"
},
"impact": {
  ... existing keys ...,
  "compareWith": "Mit Setup vergleichen..."
}
```

**de/collection.json** — Add these 6 keys. Add "tabs", "totals", and "classificationBadge" sections:

```json
"tabs": {
  "setups": "Setups"
},
"totals": {
  "totalWeight": "Gesamtgewicht",
  "totalCost": "Gesamtkosten"
},
"classificationBadge": {
  "base": "Basisgewicht",
  "worn": "Getragen",
  "consumable": "Verbrauchsmaterial"
}
```

Ensure all files remain valid JSON. Preserve existing keys exactly as they are — only add the missing ones.
  </action>
  <verify>
    <automated>cd /home/jlmak/Projects/jlmak/GearBox && bun test tests/i18n/locales.test.ts</automated>
  </verify>
  <acceptance_criteria>
    - de/common.json contains key "home" with subkeys "popularSetups", "recentlyAdded", "trendingCategories"
    - de/common.json contains key "imageUpload" with subkeys "clickToAdd", "invalidType", "tooLarge", "uploadFailed"
    - de/common.json contains key "profile" with 27 subkeys including "title", "account", "dangerZone", "deleteAccount"
    - de/settings.json contains "currency.suggestion" with "{{symbol}}" interpolation
    - de/settings.json contains "currency.switch" with value "Wechseln"
    - de/settings.json contains "showConversions.title" and "showConversions.description"
    - de/threads.json contains "card.candidates" with "{{count}}" interpolation
    - de/threads.json contains "card.candidates_one" with "{{count}}" interpolation
    - de/threads.json contains "planning" section with 9 keys including "title", "emptyTitle", "step3Description"
    - de/setups.json contains "card.by" with "{{name}}" interpolation
    - de/setups.json contains "card.anonymous" with value "Anonym"
    - de/setups.json contains "impact.compareWith" with value "Mit Setup vergleichen..."
    - de/collection.json contains "tabs.setups" with value "Setups"
    - de/collection.json contains "totals.totalWeight" and "totals.totalCost"
    - de/collection.json contains "classificationBadge.base", "classificationBadge.worn", "classificationBadge.consumable"
    - All German text uses proper Unicode umlauts (no "ae", "oe", "ue" ASCII fallbacks)
    - bun test tests/i18n/locales.test.ts exits 0 with 19 pass, 0 fail
  </acceptance_criteria>
  <done>All 58 missing German translations added across 5 de/*.json files. Key parity test passes with 0 failures. German users see translated text for home page, profile, thread cards, setup cards, totals bar, classification badges, currency suggestion, and price conversion toggle.</done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

No trust boundaries involved — this plan modifies static client-side locale JSON files only.

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-34-08-01 | T (Tampering) | locale JSON files | accept | Static bundled content, no user input, no runtime risk |
</threat_model>

<verification>
Run the key parity test to confirm all gaps are closed:
```bash
bun test tests/i18n/locales.test.ts
```
Expected: 19 pass, 0 fail (previously 14 pass, 5 fail)

Additionally verify no ASCII umlaut fallbacks crept in:
```bash
grep -r "ae\|oe\|ue" src/client/locales/de/ | grep -v node_modules | grep -E "(Loeschen|Zurueck|Aenderung|Ueber|fuer|Geraet)" | wc -l
```
Expected: 0
</verification>

<success_criteria>
- bun test tests/i18n/locales.test.ts passes with 19 pass, 0 fail
- All 5 de/*.json files have complete key parity with their en/*.json counterparts
- German translations use proper Unicode umlauts throughout
</success_criteria>

<output>
After completion, create `.planning/phases/34-i18n-foundation/34-08-SUMMARY.md`
</output>
