--- phase: 04-chart-polish-and-bug-fixes plan: 01 subsystem: ui tags: [intl, locale, currency, formatting, typescript, vitest] # Dependency graph requires: [] provides: - "Locale-aware formatCurrency(amount, currency, locale='en') with 'en' default" - "Unit tests covering English, German, USD, zero, negative, and empty-string edge cases" affects: - 04-02-chart-tooltips - any component calling formatCurrency # Tech tracking tech-stack: added: [] patterns: - "Intl.NumberFormat locale parameter passed from call site — no hardcoded locale in utility functions" key-files: created: - frontend/src/lib/format.test.ts modified: - frontend/src/lib/format.ts key-decisions: - "formatCurrency third parameter defaults to 'en', replacing hardcoded 'de-DE' — all existing 2-arg call sites now produce English formatting (FIX-01)" - "Defensive locale || 'en' guard prevents RangeError when empty string is passed" patterns-established: - "TDD pattern: write failing test first (RED commit), then implement (GREEN commit) — verified by vitest run between steps" requirements-completed: [FIX-01] # Metrics duration: 5min completed: 2026-03-12 --- # Phase 4 Plan 01: Locale-Aware formatCurrency Summary **`Intl.NumberFormat` locale parameter added to `formatCurrency` with `'en'` default, replacing hardcoded `'de-DE'` — English users now see `1,234.56` instead of `1.234,56`** ## Performance - **Duration:** 5 min - **Started:** 2026-03-12T08:23:13Z - **Completed:** 2026-03-12T08:28:00Z - **Tasks:** 2 (TDD RED + TDD GREEN) - **Files modified:** 2 ## Accomplishments - Added optional `locale` parameter to `formatCurrency` with `'en'` as the default - Removed the hardcoded `'de-DE'` locale that was forcing German number formatting for all users - Defensive `locale || 'en'` guard prevents `RangeError` on empty string input - 8 unit tests cover English formatting, German formatting, USD, zero, negative amounts, and edge cases - All 51 frontend tests pass with no regressions ## Task Commits Each task was committed atomically: 1. **TDD RED: Failing tests for locale-aware formatCurrency** - `6ffce76` (test) 2. **TDD GREEN: Implement locale parameter** - `eb1bb8a` (feat) _Note: TDD tasks have two commits (test → feat). No refactor needed._ ## Files Created/Modified - `frontend/src/lib/format.test.ts` - 8 unit tests for locale behavior, defaults, and edge cases - `frontend/src/lib/format.ts` - Updated function signature with `locale: string = 'en'` parameter ## Decisions Made - Third parameter defaults to `'en'` (not `'en-US'` or `'de-DE'`) — bare `'en'` is a valid BCP 47 tag and produces comma-grouped, period-decimal output consistent with user expectations for English locale - `locale || 'en'` fallback is intentional — empty string is not a valid BCP 47 locale and `Intl.NumberFormat('')` throws `RangeError` in some environments ## Deviations from Plan None - plan executed exactly as written. ## Issues Encountered None. Pre-existing `act(...)` warnings in unrelated test files (`InlineEditCell.test.tsx`, `CategoriesPage.test.tsx`) were observed but are out of scope per deviation rules — logged to deferred items. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - `formatCurrency(amount, currency, locale)` is ready for use in chart tooltips (04-02) - All call sites currently pass 2 args and will automatically receive English formatting - Callers can pass user's `preferred_locale` from API response as the third arg ## Self-Check: PASSED - `frontend/src/lib/format.ts` — FOUND - `frontend/src/lib/format.test.ts` — FOUND - `04-01-SUMMARY.md` — FOUND - Commit `6ffce76` (test RED) — FOUND - Commit `eb1bb8a` (feat GREEN) — FOUND --- *Phase: 04-chart-polish-and-bug-fixes* *Completed: 2026-03-12*