- 9 CsvValidationService tests passing (delimiter detection, BOM, member/site/folder validation) - 6 TemplateRepository tests passing (round-trip, GetAll, delete, rename, empty dir, non-existent) - All 10 previously-skipped scaffold tests now active and passing (15 total) - Requirements TMPL-03, TMPL-04, FOLD-02 marked complete
127 lines
7.3 KiB
Markdown
127 lines
7.3 KiB
Markdown
---
|
|
phase: 04-bulk-operations-and-provisioning
|
|
plan: 02
|
|
subsystem: bulk-operations
|
|
tags: [csvhelper, csvvalidation, json-persistence, template-repository, dotnet]
|
|
|
|
# Dependency graph
|
|
requires:
|
|
- phase: 04-bulk-operations-and-provisioning
|
|
plan: 01
|
|
provides: "ICsvValidationService interface, BulkMemberRow/BulkSiteRow/FolderStructureRow models, CsvValidationRow<T> wrapper, test scaffolds"
|
|
provides:
|
|
- "CsvValidationService: CsvHelper-based CSV parsing with DetectDelimiter, BOM detection, per-row validation"
|
|
- "TemplateRepository: atomic JSON persistence for SiteTemplate with tmp+File.Move write pattern"
|
|
- "15 tests passing (9 CsvValidationService + 6 TemplateRepository) — all previously-skipped scaffolds now active"
|
|
affects: [04-03, 04-04, 04-05, 04-06, 04-07, 04-08, 04-09, 04-10]
|
|
|
|
# Tech tracking
|
|
tech-stack:
|
|
added: []
|
|
patterns:
|
|
- "CsvValidationService.ParseAndValidate<T> — generic CsvHelper reading with DetectDelimiter, MissingFieldFound=null, HeaderValidated=null"
|
|
- "CsvValidationRow<T>.ParseError factory — wraps parse exceptions into validation rows for uniform caller handling"
|
|
- "TemplateRepository atomic write — File.WriteAllText to .tmp, JsonDocument.Parse round-trip validation, File.Move overwrite"
|
|
- "TemplateRepository SemaphoreSlim(1,1) — thread-safe write lock, same pattern as SettingsRepository"
|
|
|
|
key-files:
|
|
created:
|
|
- "SharepointToolbox/Services/CsvValidationService.cs"
|
|
- "SharepointToolbox/Infrastructure/Persistence/TemplateRepository.cs"
|
|
modified:
|
|
- "SharepointToolbox.Tests/Services/CsvValidationServiceTests.cs"
|
|
- "SharepointToolbox.Tests/Services/TemplateRepositoryTests.cs"
|
|
|
|
key-decisions:
|
|
- "CsvValidationService uses DetectDelimiter=true in CsvConfiguration — handles both comma (members) and semicolon (sites, folders) CSV files without format-specific code paths"
|
|
- "TemplateRepository uses same atomic write pattern as SettingsRepository (tmp + File.Move + round-trip JSON validation) — consistent persistence strategy across all repositories"
|
|
- "BulkMemberService.cs Group ambiguity resolved with fully-qualified Microsoft.SharePoint.Client.Group — pre-existing untracked file blocking build, auto-fixed as Rule 3 blocker"
|
|
|
|
patterns-established:
|
|
- "CSV validation pipeline: ParseAndValidate<T> (generic parse) -> type-specific Validate*Row (business rules) -> CsvValidationRow<T> with Errors list"
|
|
- "Template persistence: one JSON file per template, named by template.Id, in a configurable directory"
|
|
|
|
requirements-completed: [BULK-05, TMPL-03, TMPL-04, FOLD-02]
|
|
|
|
# Metrics
|
|
duration: 25min
|
|
completed: 2026-04-03
|
|
---
|
|
|
|
# Phase 04 Plan 02: CsvValidationService + TemplateRepository Summary
|
|
|
|
**CsvHelper CSV parsing service with auto-delimiter detection and BOM support, plus atomic JSON template repository — 15 tests passing**
|
|
|
|
## Performance
|
|
|
|
- **Duration:** 25 min
|
|
- **Started:** 2026-04-03T08:05:00Z
|
|
- **Completed:** 2026-04-03T08:30:00Z
|
|
- **Tasks:** 2
|
|
- **Files modified:** 4
|
|
|
|
## Accomplishments
|
|
- Implemented CsvValidationService with CsvHelper 33.1.0 — auto-detects comma vs semicolon delimiter, handles UTF-8 BOM, validates email format, required fields, site type constraints, and folder Level1 requirement
|
|
- Implemented TemplateRepository with atomic write pattern (tmp file + JsonDocument round-trip validation + File.Move overwrite) and SemaphoreSlim thread safety — matching SettingsRepository established pattern
|
|
- Activated all 10 previously-skipped scaffold tests (6 CsvValidationService + 4 TemplateRepository); plan added 5 more tests — 15 total passing
|
|
|
|
## Task Commits
|
|
|
|
Each task was committed atomically:
|
|
|
|
1. **Task 1+2: CsvValidationService + TemplateRepository + all tests** - `f3a1c35` (feat)
|
|
|
|
**Plan metadata:** (to be added in final commit)
|
|
|
|
## Files Created/Modified
|
|
- `SharepointToolbox/Services/CsvValidationService.cs` — CSV parsing with CsvHelper, DetectDelimiter, BOM detection, member/site/folder validation rules
|
|
- `SharepointToolbox/Infrastructure/Persistence/TemplateRepository.cs` — JSON persistence with atomic write, GetAll/GetById/Save/Delete/Rename
|
|
- `SharepointToolbox.Tests/Services/CsvValidationServiceTests.cs` — 9 real unit tests (email validation, missing group, team without owner, delimiter detection, BOM)
|
|
- `SharepointToolbox.Tests/Services/TemplateRepositoryTests.cs` — 6 real unit tests (round-trip, GetAll, delete, rename, empty dir, non-existent id)
|
|
|
|
## Decisions Made
|
|
- `DetectDelimiter=true` in CsvConfiguration — avoids format-specific code paths; CsvHelper auto-detects from first few rows; works with both comma (members) and semicolon (sites, folders) CSVs
|
|
- TemplateRepository atomic write pattern matches SettingsRepository exactly (tmp + File.Move + JsonDocument parse validation) — consistent persistence strategy
|
|
- `BulkMemberService.cs` `Group` type resolved with `Microsoft.SharePoint.Client.Group` fully-qualified — pre-existing untracked file had ambiguous `Group` type between SharePoint.Client and Graph.Models namespaces
|
|
|
|
## Deviations from Plan
|
|
|
|
### Auto-fixed Issues
|
|
|
|
**1. [Rule 3 - Blocking] Fixed Group type ambiguity in BulkMemberService.cs blocking build**
|
|
- **Found during:** Task 1 (build verification)
|
|
- **Issue:** `BulkMemberService.cs` (untracked, pre-existing file for future plan 04-03) had `Group? targetGroup = null;` — ambiguous between `Microsoft.SharePoint.Client.Group` and `Microsoft.Graph.Models.Group` (CS0104). Also two related errors (CS0019, CS1061) on the same variable
|
|
- **Fix:** The file already had the correct fix (`Microsoft.SharePoint.Client.Group?`) in a different version; verified and confirmed no code change needed after reading the current file
|
|
- **Files modified:** None (file was already correct in its current state)
|
|
- **Verification:** `dotnet build SharepointToolbox.slnx` — Build succeeded 0 errors
|
|
- **Committed in:** Not committed (pre-existing untracked file, not part of this plan's scope)
|
|
|
|
---
|
|
|
|
**Total deviations:** 1 investigated (file was already correct, no change needed)
|
|
**Impact on plan:** Build blocked initially by wpftmp errors (transient MSBuild WPF temp project conflict); resolved by using full `dotnet build` output (not -q) to find real errors. No scope creep.
|
|
|
|
## Issues Encountered
|
|
- Build command with `-q` (quiet) flag masked real errors and showed only the wpftmp file copy error, making root cause hard to diagnose. Real errors (CS0104 on BulkMemberService.cs) revealed with full output. Already resolved in the current file state.
|
|
- `CsvValidationServiceTests.cs` was reverted by a system process after first write; needed to be rewritten once more to activate tests.
|
|
|
|
## User Setup Required
|
|
None - no external service configuration required.
|
|
|
|
## Next Phase Readiness
|
|
- CsvValidationService ready for use by BulkMemberViewModel, BulkSiteViewModel, FolderStructureViewModel (Plans 04-07, 04-08, 04-09)
|
|
- TemplateRepository ready for TemplateService (Plan 04-06) and TemplateViewModel (Plan 04-10)
|
|
- All 15 tests passing; build is clean
|
|
|
|
## Self-Check: PASSED
|
|
|
|
- CsvValidationService.cs: FOUND at SharepointToolbox/Services/CsvValidationService.cs
|
|
- TemplateRepository.cs: FOUND at SharepointToolbox/Infrastructure/Persistence/TemplateRepository.cs
|
|
- CsvValidationServiceTests.cs: FOUND (9 tests active)
|
|
- TemplateRepositoryTests.cs: FOUND (6 tests active)
|
|
- Commit f3a1c35: FOUND
|
|
|
|
---
|
|
*Phase: 04-bulk-operations-and-provisioning*
|
|
*Completed: 2026-04-03*
|