fix(i18n): restore en/de key parity, translate usePhotos errors, add parity guard test#1846
Conversation
…parity guard test - usePhotos.ts now routes API errors through translateApiError()/t() instead of hardcoded English strings (ApiClientError -> errors namespace by code, NetworkError/unexpected -> new photoViewer.networkError/unexpectedError keys, translated in both en and de). - Removed 5 orphaned photoAnnotator keys (reset/resetTitle/resetBody/ resetConfirm/resetComplete) left over from a "reset to original photo" feature that was replaced by PhotoViewer's "Clear annotations" entry point; also removed the associated dead CSS rules (.resetButton, .modalActions, .confirmButton). - Fixed 5 pre-existing literal duplicate JSON keys (same key twice in the same object, silently shadowed by JSON.parse's last-wins behavior) across diary.json, householdItems.json, and schedule.json in both locales. Verified behavior-preserving: the shadowed (first) occurrence was already unreachable at runtime in every case. - Added client/src/i18n/i18n.parity.test.ts: a generalized en/de key-parity test across all 14 namespaces plus a raw-text duplicate-key guard across all 28 locale files, so both bug classes fail CI instead of accumulating. Fixes #1814 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com> Co-Authored-By: Claude translator (Sonnet 4.5) <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>
|
[security-engineer] Security review of #1846 (fix/1814-i18n-parity-usephotos → beta) Scope confirmed: client-only i18n hygiene (dead-key removal, duplicate-JSON-key fixes, dead CSS rule removal) plus a Security-relevant change reviewed: Previously: setError(err.error.message ?? 'Failed to load photos.');Now: setError(translateApiError(err.error.code, tErrors));Verified Also checked:
Findings: None. No Critical/High/Medium/Low issues identified. Verdict: APPROVED |
|
[product-architect] APPROVED Architecture/contract review of the i18n hygiene changes. No API, schema, shared-type, or ADR impact — this is client-side i18n + a hook. Verified the following: Remove-vs-wire decision (orphaned photoAnnotator keys) — correct. The 5 Duplicate-key removals — behavior-preserving. All 5 removed keys were the earlier occurrence of a same-scope duplicate ( usePhotos error pattern — consistent with the established convention. Matches Guard test design — sound. The Informational (non-blocking):
|
|
[ux-designer] Reviewed the client diff ( 1. Duplicate-key removals — verified behavior-preservingParsed
All matches what CI's new Informational, non-blocking, out of scope for this PR: the surviving 2. Dead CSS removal — verified unreferenced
3. German error strings — quality check
Both match established phrasing already used elsewhere in the app ( Other checks
No findings that warrant blocking. Verdict: APPROVED |
|
🎉 This PR is included in version 2.13.0-beta.15 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
usePhotos.tsnow routes API errors throughtranslateApiError()/t()instead of hardcoded English strings (ApiClientError→errorsnamespace by code;NetworkError/unexpected → newphotoViewer.networkError/unexpectedErrorkeys, translated in bothenandde).photoAnnotatorkeys (reset/resetTitle/resetBody/resetConfirm/resetComplete) left over from a "reset to original photo" feature that was replaced by PhotoViewer's "Clear annotations" entry point; also removed the associated dead CSS (.resetButton,.modalActions,.confirmButton).JSON.parse's last-wins behavior) acrossdiary.json,householdItems.json, andschedule.jsonin both locales — verified behavior-preserving in every case (the shadowed/first occurrence was already unreachable at runtime).client/src/i18n/i18n.parity.test.ts: a generalized en/de key-parity guard test across all 14 namespaces, plus a raw-text duplicate-key guard across all 28 locale files, so both bug classes fail CI going forward instead of accumulating.Fixes #1814
Test plan
usePhotos.test.ts38/38, 100% stmts/lines coverage; newi18n.parity.test.ts46/46)tsc --noEmitclean,npm run lintcleanPhotoAnnotator,DiaryEntryCreatePage,DiaryEntryEditPage,HouseholdItemDetailPage,MilestoneDetailPage,errorTranslation) — 227/233 passing, 6 pre-existing unrelatedtodoskips, zero failuresCo-Authored-By: Claude dev-team-lead (Sonnet 4.6) noreply@anthropic.com
Co-Authored-By: Claude frontend-developer (Haiku 4.5) noreply@anthropic.com
Co-Authored-By: Claude translator (Sonnet 4.5) noreply@anthropic.com
Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) noreply@anthropic.com