--- phase: 01-foundation plan: 05 subsystem: localization tags: [wpf, dotnet10, serilog, localization, resx, i18n, csharp, tdd] # Dependency graph requires: - 01-02 (LogPanelSink, LanguageChangedMessage) provides: - TranslationSource singleton with INotifyPropertyChanged indexer for runtime culture switching - Strings.resx with 27 Phase 1 EN UI strings - Strings.fr.resx with same 27 keys stubbed for Phase 5 FR translation - LoggingIntegrationTests verifying Serilog rolling file sink and LogPanelSink type affects: - 01-06 (MainWindow.xaml binds via TranslationSource.Instance[key]) - 01-07 (SettingsViewModel sets TranslationSource.Instance.CurrentCulture) - 02-xx (all feature views use localized strings via TranslationSource) # Tech tracking tech-stack: added: [] patterns: - TranslationSource singleton with INotifyPropertyChanged empty-string key (signals all bindings refresh) - WPF binding: Source={x:Static loc:TranslationSource.Instance}, Path=[key] - ResourceManager from Strings.Designer.cs — manually maintained for dotnet build (no ResXFileCodeGenerator at build time) - EmbeddedResource Update (not Include) in SDK-style project — avoids NETSDK1022 duplicate error - IDisposable test teardown with TranslationSource culture reset — prevents test pollution key-files: created: - SharepointToolbox/Localization/TranslationSource.cs - SharepointToolbox/Localization/Strings.resx - SharepointToolbox/Localization/Strings.fr.resx - SharepointToolbox/Localization/Strings.Designer.cs modified: - SharepointToolbox/SharepointToolbox.csproj - SharepointToolbox/App.xaml.cs - SharepointToolbox.Tests/Localization/TranslationSourceTests.cs - SharepointToolbox.Tests/Integration/LoggingIntegrationTests.cs key-decisions: - "Strings.Designer.cs is maintained manually — ResXFileCodeGenerator is a VS-only tool; dotnet build requires the designer file to pre-exist; only the ResourceManager accessor is needed (no per-key typed properties)" - "EmbeddedResource uses Update not Include — SDK-style projects auto-include all .resx as EmbeddedResource; using Include causes NETSDK1022 duplicate error" - "System.IO using added explicitly in test project — xunit test project implicit usings do not cover System.IO; consistent with existing pattern in main project" requirements-completed: - FOUND-08 - FOUND-09 # Metrics duration: 4min completed: 2026-04-02 --- # Phase 1 Plan 05: Logging Infrastructure and Dynamic Localization Summary **TranslationSource singleton + EN/FR resx + Serilog integration tests — 26 tests pass (24 Unit, 2 Integration), 0 errors, 0 warnings** ## Performance - **Duration:** 4 min - **Started:** 2026-04-02T10:14:23Z - **Completed:** 2026-04-02T10:18:08Z - **Tasks:** 2 - **Files modified:** 8 ## Accomplishments - TranslationSource singleton implements INotifyPropertyChanged; indexer `[key]` uses ResourceManager for runtime culture switching without restart - PropertyChanged fires with `string.Empty` PropertyName on culture change — WPF re-evaluates all bindings to TranslationSource.Instance - Missing key returns `[key]` placeholder — prevents NullReferenceException in WPF bindings - Same-culture assignment is no-op — equality check prevents spurious PropertyChanged events - Strings.resx: 27 Phase 1 UI strings (EN): app, toolbar, tab, button, settings, profile, status, and error keys - Strings.fr.resx: same 27 keys, EN values stubbed, marked `` - Strings.Designer.cs: ResourceManager accessor for dotnet build compatibility (no VS ResXFileCodeGenerator dependency) - LoggingIntegrationTests: verifies Serilog creates a rolling log file and writes message content; verifies LogPanelSink implements ILogEventSink - App.xaml.cs: comment added documenting deferred LogPanelSink DI registration (plan 01-06) ## Task Commits 1. **Task 1 RED: Failing tests for TranslationSource** - `8a58140` (test) 2. **Task 1 GREEN: TranslationSource + resx files implementation** - `a287ed8` (feat) 3. **Task 2: Serilog integration tests + App.xaml.cs comment** - `1c532d1` (feat) ## Files Created/Modified - `SharepointToolbox/Localization/TranslationSource.cs` — Singleton; INotifyPropertyChanged indexer; empty-string PropertyChanged; culture equality guard - `SharepointToolbox/Localization/Strings.resx` — 27 Phase 1 EN string resources - `SharepointToolbox/Localization/Strings.fr.resx` — 27 keys stubbed with EN values; Phase 5 FR completion - `SharepointToolbox/Localization/Strings.Designer.cs` — ResourceManager accessor; manually maintained for dotnet build - `SharepointToolbox/SharepointToolbox.csproj` — EmbeddedResource Update metadata for resx files - `SharepointToolbox/App.xaml.cs` — LogPanelSink registration comment deferred to plan 01-06 - `SharepointToolbox.Tests/Localization/TranslationSourceTests.cs` — 6 unit tests; IDisposable teardown for culture reset - `SharepointToolbox.Tests/Integration/LoggingIntegrationTests.cs` — 2 integration tests; temp dir cleanup in Dispose ## Decisions Made - Strings.Designer.cs maintained manually: `ResXFileCodeGenerator` is a Visual Studio design-time tool not available in `dotnet build`. The designer file only needs the `ResourceManager` property accessor — no per-key typed properties are needed since TranslationSource uses `ResourceManager.GetString(key, culture)` directly. - `EmbeddedResource Update` instead of `Include`: SDK-style projects implicitly include all `.resx` files as `EmbeddedResource`. Using `Include` causes `NETSDK1022` duplicate build error. `Update` sets metadata on the already-included item. - Explicit `System.IO` using in test file: test project implicit usings do not cover `System.IO`; consistent with the established pattern for the main project (prior decision FOUND-10). ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 3 - Blocking] Added explicit System.IO using to LoggingIntegrationTests.cs** - **Found during:** Task 2 (dotnet build) - **Issue:** CS0103 — `Path`, `Directory`, `File` not found; test project implicit usings do not include System.IO - **Fix:** Added `using System.IO;` to the test file - **Files modified:** `SharepointToolbox.Tests/Integration/LoggingIntegrationTests.cs` - **Verification:** Build 0 errors, 0 warnings after fix - **Committed in:** 1c532d1 (Task 2 commit) **2. [Rule 3 - Blocking] Used EmbeddedResource Update (not Include) for resx metadata** - **Found during:** Task 1 GREEN (dotnet build) - **Issue:** NETSDK1022 duplicate EmbeddedResource — SDK auto-includes all .resx files; explicit Include causes duplicate error - **Fix:** Changed `` to `` in SharepointToolbox.csproj - **Files modified:** `SharepointToolbox/SharepointToolbox.csproj` - **Verification:** Build 0 errors, 0 warnings after fix - **Committed in:** a287ed8 (Task 1 commit) **3. [Rule 3 - Blocking] Created Strings.Designer.cs manually** - **Found during:** Task 1 GREEN (dotnet build) - **Issue:** `Strings` class does not exist in context — ResXFileCodeGenerator is VS-only, not run by dotnet build CLI - **Fix:** Created Strings.Designer.cs with ResourceManager accessor manually; only the `ResourceManager` property is needed (TranslationSource uses it directly) - **Files modified:** `SharepointToolbox/Localization/Strings.Designer.cs` - **Verification:** Build 0 errors after fix; TranslationSourceTests pass - **Committed in:** a287ed8 (Task 1 commit) --- **Total deviations:** 3 auto-fixed (all Rule 3 — blocking build issues) **Impact on plan:** All fixes minor; no scope creep; no behavior change from plan intent. ## Issues Encountered None beyond the auto-fixed deviations above. ## User Setup Required None — no external service configuration required. ## Next Phase Readiness - TranslationSource.Instance ready for WPF XAML binding in plan 01-06 (MainWindow) - All 27 Phase 1 UI string keys defined in EN resx - FR resx keyset matches EN — Phase 5 can add translations without key changes - Serilog rolling file sink verified working; LogPanelSink type verified ILogEventSink-compatible - Plan 01-06 can proceed immediately ## Self-Check: PASSED - FOUND: SharepointToolbox/Localization/TranslationSource.cs - FOUND: SharepointToolbox/Localization/Strings.resx - FOUND: SharepointToolbox/Localization/Strings.fr.resx - FOUND: SharepointToolbox/Localization/Strings.Designer.cs - FOUND: SharepointToolbox.Tests/Localization/TranslationSourceTests.cs - FOUND: SharepointToolbox.Tests/Integration/LoggingIntegrationTests.cs - FOUND: .planning/phases/01-foundation/01-05-SUMMARY.md - Commit 8a58140: test(01-05): add failing tests for TranslationSource singleton - Commit a287ed8: feat(01-05): implement TranslationSource singleton + EN/FR resx files - Commit 1c532d1: feat(01-05): add Serilog integration tests and App.xaml.cs LogPanelSink comment --- *Phase: 01-foundation* *Completed: 2026-04-02*