Archive 5 phases (36 plans) to milestones/v1.0-phases/. Archive roadmap, requirements, and audit to milestones/. Evolve PROJECT.md with shipped state and validated requirements. Collapse ROADMAP.md to one-line milestone summary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.2 KiB
7.2 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-foundation | 03 | persistence |
|
|
|
|
|
|
|
|
|
8min | 2026-04-02 |
Phase 1 Plan 03: Persistence Layer Summary
ProfileRepository + SettingsRepository with write-then-replace safety, ProfileService + SettingsService with validation, 18 unit tests covering round-trips, corrupt-file recovery, concurrency, and JSON schema compatibility
Performance
- Duration: 8 min
- Started: 2026-04-02T10:09:13Z
- Completed: 2026-04-02T10:17:00Z
- Tasks: 2
- Files modified: 7
Accomplishments
- ProfileRepository and SettingsRepository both implement write-then-replace (tmp file → JSON validation → File.Move) with SemaphoreSlim(1,1) preventing concurrent write corruption
- JSON serialization uses camelCase (PropertyNamingPolicy.CamelCase) — preserves existing user data field names:
profiles,name,tenantUrl,clientId,dataFolder,lang - ProfileService provides full CRUD with input validation (Name not empty, TenantUrl valid absolute URL, ClientId not empty)
- SettingsService validates language codes against supported set (en/fr only), allows empty dataFolder
- All 18 unit tests pass (10 ProfileServiceTests + 8 SettingsServiceTests); no skips
Task Commits
Each task was committed atomically:
- Task 1: ProfileRepository and ProfileService with write-then-replace -
769196d(feat) - Task 2: SettingsRepository and SettingsService -
ac3fa5c(feat)
Plan metadata: (docs commit follows)
Files Created/Modified
SharepointToolbox/Core/Models/AppSettings.cs- AppSettings model; DataFolder + Lang with camelCase JSONSharepointToolbox/Infrastructure/Persistence/ProfileRepository.cs- File I/O; SemaphoreSlim; write-then-replace; camelCaseSharepointToolbox/Infrastructure/Persistence/SettingsRepository.cs- Same pattern as ProfileRepository for settingsSharepointToolbox/Services/ProfileService.cs- CRUD on profiles; validates Name/TenantUrl/ClientId; throws KeyNotFoundExceptionSharepointToolbox/Services/SettingsService.cs- Get/SetLanguage/SetDataFolder; validates language codesSharepointToolbox.Tests/Services/ProfileServiceTests.cs- 10 tests: round-trip, missing file, corrupt JSON, concurrency, schema keysSharepointToolbox.Tests/Services/SettingsServiceTests.cs- 8 tests: defaults, round-trip, JSON keys, tmp file, language/folder persistence
Decisions Made
- Explicit
using System.IO;required in WPF main project — the WPF temp build project does not includeSystem.IOin its implicit usings, unlike the standard non-WPF SDK. All repositories need explicit namespace imports. SettingsService.SetLanguageAsyncvalidates only "en" and "fr" using a case-insensitiveHashSet<string>. Other codes throwArgumentExceptionimmediately.LoadAsyncon corrupt JSON throwsInvalidDataException(not silent empty list/default) — this is an explicit safety decision: silently discarding corrupt data could mask accidental overwrites.
Deviations from Plan
Auto-fixed Issues
1. [Rule 3 - Blocking] Added explicit System.IO using to WPF project files
- Found during: Task 1 (dotnet test — first GREEN attempt)
- Issue: WPF temporary build project does not include
System.IOin its implicit usings.File,Path,Directory,IOException,InvalidDataExceptionall unresolved in the main project and test project. - Fix: Added
using System.IO;at the top of ProfileRepository.cs, SettingsRepository.cs, ProfileServiceTests.cs, and SettingsServiceTests.cs - Files modified: All 4 implementation and test files
- Verification: Build succeeded with 0 errors, 18/18 tests pass
- Committed in:
769196dandac3fa5c(inline with respective task commits)
Total deviations: 1 auto-fixed (Rule 3 — blocking build issue) Impact on plan: One-line fix per file, no logic changes, no scope creep.
Issues Encountered
None beyond the auto-fixed deviation above.
User Setup Required
None - no external service configuration required.
Next Phase Readiness
- ProfileService and SettingsService ready for injection in plan 01-04 (MsalClientFactory may need tenant list from ProfileService)
- SettingsService.SetLanguageAsync ready for TranslationSource in plan 01-05
- Both services follow the same constructor injection pattern — ready for DI container registration in plan 01-06 or 01-07
- JSON schema contracts locked: field names are tested and verified camelCase
Phase: 01-foundation Completed: 2026-04-02