docs(01-05): complete localization and logging plan
- 01-05-SUMMARY.md: TranslationSource + EN/FR resx + Serilog integration tests - STATE.md: progress 50% (4/8 plans), metrics recorded, decisions added - ROADMAP.md: phase 1 progress updated (4/8 summaries) - REQUIREMENTS.md: FOUND-09 marked complete
This commit is contained in:
@@ -17,7 +17,7 @@ Requirements for initial release. Each maps to roadmap phases.
|
|||||||
- [x] **FOUND-06**: User can cancel any long-running operation mid-execution
|
- [x] **FOUND-06**: User can cancel any long-running operation mid-execution
|
||||||
- [x] **FOUND-07**: All errors surface to the user with actionable messages — no silent failures
|
- [x] **FOUND-07**: All errors surface to the user with actionable messages — no silent failures
|
||||||
- [x] **FOUND-08**: Structured logging for diagnostics (Serilog or equivalent)
|
- [x] **FOUND-08**: Structured logging for diagnostics (Serilog or equivalent)
|
||||||
- [ ] **FOUND-09**: Localization system supporting English and French with dynamic language switching
|
- [x] **FOUND-09**: Localization system supporting English and French with dynamic language switching
|
||||||
- [x] **FOUND-10**: JSON-based local storage for profiles, settings, and templates (compatible with current app's format for migration)
|
- [x] **FOUND-10**: JSON-based local storage for profiles, settings, and templates (compatible with current app's format for migration)
|
||||||
- [ ] **FOUND-11**: Self-contained single EXE distribution — no .NET runtime dependency for end users
|
- [ ] **FOUND-11**: Self-contained single EXE distribution — no .NET runtime dependency for end users
|
||||||
- [x] **FOUND-12**: Configurable data output folder for exports
|
- [x] **FOUND-12**: Configurable data output folder for exports
|
||||||
@@ -123,7 +123,7 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| FOUND-06 | Phase 1 | Complete |
|
| FOUND-06 | Phase 1 | Complete |
|
||||||
| FOUND-07 | Phase 1 | Complete |
|
| FOUND-07 | Phase 1 | Complete |
|
||||||
| FOUND-08 | Phase 1 | Complete |
|
| FOUND-08 | Phase 1 | Complete |
|
||||||
| FOUND-09 | Phase 1 | Pending |
|
| FOUND-09 | Phase 1 | Complete |
|
||||||
| FOUND-10 | Phase 1 | Complete |
|
| FOUND-10 | Phase 1 | Complete |
|
||||||
| FOUND-11 | Phase 5 | Pending |
|
| FOUND-11 | Phase 5 | Pending |
|
||||||
| FOUND-12 | Phase 1 | Complete |
|
| FOUND-12 | Phase 1 | Complete |
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5
|
|||||||
|
|
||||||
| Phase | Plans Complete | Status | Completed |
|
| Phase | Plans Complete | Status | Completed |
|
||||||
|-------|----------------|--------|-----------|
|
|-------|----------------|--------|-----------|
|
||||||
| 1. Foundation | 3/8 | In Progress| |
|
| 1. Foundation | 4/8 | In Progress| |
|
||||||
| 2. Permissions | 0/? | Not started | - |
|
| 2. Permissions | 0/? | Not started | - |
|
||||||
| 3. Storage and File Operations | 0/? | Not started | - |
|
| 3. Storage and File Operations | 0/? | Not started | - |
|
||||||
| 4. Bulk Operations and Provisioning | 0/? | Not started | - |
|
| 4. Bulk Operations and Provisioning | 0/? | Not started | - |
|
||||||
|
|||||||
@@ -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 01-foundation-03-PLAN.md
|
stopped_at: Completed 01-foundation-05-PLAN.md
|
||||||
last_updated: "2026-04-02T10:13:20.259Z"
|
last_updated: "2026-04-02T10:19:35.873Z"
|
||||||
last_activity: 2026-04-02 — Roadmap created, requirements mapped, all 42 v1 requirements assigned to phases
|
last_activity: 2026-04-02 — Roadmap created, requirements mapped, all 42 v1 requirements assigned to phases
|
||||||
progress:
|
progress:
|
||||||
total_phases: 5
|
total_phases: 5
|
||||||
completed_phases: 0
|
completed_phases: 0
|
||||||
total_plans: 8
|
total_plans: 8
|
||||||
completed_plans: 3
|
completed_plans: 4
|
||||||
percent: 13
|
percent: 13
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -53,6 +53,7 @@ Progress: [█░░░░░░░░░] 13%
|
|||||||
| Phase 01-foundation P01 | 4 | 2 tasks | 14 files |
|
| Phase 01-foundation P01 | 4 | 2 tasks | 14 files |
|
||||||
| Phase 01-foundation P02 | 1 | 2 tasks | 7 files |
|
| Phase 01-foundation P02 | 1 | 2 tasks | 7 files |
|
||||||
| Phase 01-foundation P03 | 8 | 2 tasks | 7 files |
|
| Phase 01-foundation P03 | 8 | 2 tasks | 7 files |
|
||||||
|
| Phase 01-foundation P05 | 4min | 2 tasks | 8 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -73,6 +74,8 @@ Recent decisions affecting current work:
|
|||||||
- [Phase 01-foundation]: Explicit System.IO using required in WPF project — WPF temp build project does not include System.IO in implicit usings; all persistence classes need explicit import
|
- [Phase 01-foundation]: Explicit System.IO using required in WPF project — WPF temp build project does not include System.IO in implicit usings; all persistence classes need explicit import
|
||||||
- [Phase 01-foundation]: SettingsService validates only 'en' and 'fr' language codes — throws ArgumentException for unsupported codes
|
- [Phase 01-foundation]: SettingsService validates only 'en' and 'fr' language codes — throws ArgumentException for unsupported codes
|
||||||
- [Phase 01-foundation]: LoadAsync on corrupt JSON throws InvalidDataException (not silent empty) — explicit failure protects against silent data loss
|
- [Phase 01-foundation]: LoadAsync on corrupt JSON throws InvalidDataException (not silent empty) — explicit failure protects against silent data loss
|
||||||
|
- [Phase 01-foundation]: Strings.Designer.cs maintained manually — ResXFileCodeGenerator is VS-only, not run by dotnet build; only ResourceManager accessor needed
|
||||||
|
- [Phase 01-foundation]: EmbeddedResource uses Update not Include in SDK-style project — SDK auto-includes all .resx; Include causes NETSDK1022 duplicate error
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -86,6 +89,6 @@ None yet.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-02T10:13:20.255Z
|
Last session: 2026-04-02T10:19:35.870Z
|
||||||
Stopped at: Completed 01-foundation-03-PLAN.md
|
Stopped at: Completed 01-foundation-05-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
167
.planning/phases/01-foundation/01-05-SUMMARY.md
Normal file
167
.planning/phases/01-foundation/01-05-SUMMARY.md
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
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 `<!-- FR stub — Phase 5 -->`
|
||||||
|
- 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 `<EmbeddedResource Include=...>` to `<EmbeddedResource Update=...>` 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*
|
||||||
Reference in New Issue
Block a user