docs(04-01): complete locale-aware formatCurrency plan

This commit is contained in:
2026-03-12 09:24:54 +01:00
parent eb1bb8aeec
commit 1412aacf92
4 changed files with 122 additions and 10 deletions

View File

@@ -45,7 +45,7 @@ Requirements for this milestone. Each maps to roadmap phases.
### Bug Fixes ### Bug Fixes
- [ ] **FIX-01**: `formatCurrency` uses the user's locale preference instead of hardcoded `de-DE` - [x] **FIX-01**: `formatCurrency` uses the user's locale preference instead of hardcoded `de-DE`
- [x] **FIX-02**: `InlineEditRow` extracted into a shared component (currently duplicated in BillsTracker, VariableExpenses, DebtTracker) - [x] **FIX-02**: `InlineEditRow` extracted into a shared component (currently duplicated in BillsTracker, VariableExpenses, DebtTracker)
## v2 Requirements ## v2 Requirements
@@ -111,7 +111,7 @@ Which phases cover which requirements. Updated during roadmap creation.
| STATE-02 | Phase 3 | Complete | | STATE-02 | Phase 3 | Complete |
| STATE-03 | Phase 3 | Complete | | STATE-03 | Phase 3 | Complete |
| IXTN-04 | Phase 4 | Pending | | IXTN-04 | Phase 4 | Pending |
| FIX-01 | Phase 4 | Pending | | FIX-01 | Phase 4 | Complete |
**Coverage:** **Coverage:**
- v1 requirements: 23 total - v1 requirements: 23 total

View File

@@ -74,7 +74,7 @@ Plans:
1. All chart fills (donut slices, bar segments) use the semantic category colors from `lib/palette.ts` — "Bills" is the same color in the donut chart as it is in the FinancialOverview table 1. All chart fills (donut slices, bar segments) use the semantic category colors from `lib/palette.ts` — "Bills" is the same color in the donut chart as it is in the FinancialOverview table
2. Chart tooltips display values formatted with the budget's currency (e.g., "1,234.56" not "1234.56") 2. Chart tooltips display values formatted with the budget's currency (e.g., "1,234.56" not "1234.56")
3. The `formatCurrency` function uses the user's locale preference from their settings instead of the hardcoded `de-DE` — an English-locale user sees their numbers formatted correctly 3. The `formatCurrency` function uses the user's locale preference from their settings instead of the hardcoded `de-DE` — an English-locale user sees their numbers formatted correctly
**Plans:** 2 plans **Plans:** 1/2 plans executed
Plans: Plans:
- [ ] 04-01-PLAN.md — TDD: formatCurrency locale parameter fix (FIX-01) - [ ] 04-01-PLAN.md — TDD: formatCurrency locale parameter fix (FIX-01)
- [ ] 04-02-PLAN.md — Chart tooltip wiring and locale threading (IXTN-04) - [ ] 04-02-PLAN.md — Chart tooltip wiring and locale threading (IXTN-04)
@@ -89,4 +89,4 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4
| 1. Design Token Foundation | 2/2 | Complete | 2026-03-11 | | 1. Design Token Foundation | 2/2 | Complete | 2026-03-11 |
| 2. Layout and Brand Identity | 0/2 | In progress | - | | 2. Layout and Brand Identity | 0/2 | In progress | - |
| 3. Interaction Quality and Completeness | 0/4 | Not started | - | | 3. Interaction Quality and Completeness | 0/4 | Not started | - |
| 4. Chart Polish and Bug Fixes | 0/2 | Not started | - | | 4. Chart Polish and Bug Fixes | 1/2 | In Progress| |

View File

@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.0 milestone: v1.0
milestone_name: milestone milestone_name: milestone
status: planning status: planning
stopped_at: Completed 03-03-PLAN.md stopped_at: Completed 04-01-PLAN.md
last_updated: "2026-03-11T21:41:42.367Z" last_updated: "2026-03-12T08:24:41.212Z"
last_activity: 2026-03-11 — Roadmap created from requirements and research last_activity: 2026-03-11 — Roadmap created from requirements and research
progress: progress:
total_phases: 4 total_phases: 4
completed_phases: 3 completed_phases: 3
total_plans: 8 total_plans: 10
completed_plans: 8 completed_plans: 9
percent: 0 percent: 0
--- ---
@@ -58,6 +58,7 @@ Progress: [░░░░░░░░░░] 0%
| Phase 03-interaction-quality-and-completeness P01 | 2m | 2 tasks | 5 files | | Phase 03-interaction-quality-and-completeness P01 | 2m | 2 tasks | 5 files |
| Phase 03-interaction-quality-and-completeness P02 | 5 | 2 tasks | 3 files | | Phase 03-interaction-quality-and-completeness P02 | 5 | 2 tasks | 3 files |
| Phase 03-interaction-quality-and-completeness P03 | 5 | 2 tasks | 4 files | | Phase 03-interaction-quality-and-completeness P03 | 5 | 2 tasks | 4 files |
| Phase 04-chart-polish-and-bug-fixes P01 | 1 | 2 tasks | 2 files |
## Accumulated Context ## Accumulated Context
@@ -87,6 +88,8 @@ Recent decisions affecting current work:
- [Phase 03-interaction-quality-and-completeness]: CategoriesPage loading state initialized true, set false in finally block to prevent empty-state flash - [Phase 03-interaction-quality-and-completeness]: CategoriesPage loading state initialized true, set false in finally block to prevent empty-state flash
- [Phase 03-interaction-quality-and-completeness]: triggerFlash uses two separate state vars (flashRowId/errorRowId) for flash feedback — no race conditions between success and error states - [Phase 03-interaction-quality-and-completeness]: triggerFlash uses two separate state vars (flashRowId/errorRowId) for flash feedback — no race conditions between success and error states
- [Phase 03-interaction-quality-and-completeness]: Empty tracker sections show tinted skeleton card (not null) — section always visible with palette-tinted placeholders when no items exist - [Phase 03-interaction-quality-and-completeness]: Empty tracker sections show tinted skeleton card (not null) — section always visible with palette-tinted placeholders when no items exist
- [Phase 04-chart-polish-and-bug-fixes]: formatCurrency third parameter defaults to 'en', replacing hardcoded 'de-DE' — all existing 2-arg call sites now produce English formatting (FIX-01)
- [Phase 04-chart-polish-and-bug-fixes]: Defensive locale || 'en' guard in formatCurrency prevents RangeError when empty string is passed
### Pending Todos ### Pending Todos
@@ -99,6 +102,6 @@ None yet.
## Session Continuity ## Session Continuity
Last session: 2026-03-11T21:37:48.889Z Last session: 2026-03-12T08:24:41.210Z
Stopped at: Completed 03-03-PLAN.md Stopped at: Completed 04-01-PLAN.md
Resume file: None Resume file: None

View File

@@ -0,0 +1,109 @@
---
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*