Files
Sharepoint-Toolbox/.planning/phases/04-bulk-operations-and-provisioning/04-VERIFICATION.md
2026-04-03 13:52:45 +02:00

21 KiB

phase, verified, status, score, human_verification
phase verified status score human_verification
04-bulk-operations-and-provisioning 2026-04-03T00:00:00Z human_needed 12/12 must-haves verified
test expected why_human
Run the application and verify all 5 new tabs are visible and load without crashing 10 tabs total — Permissions, Storage, Search, Duplicates, Transfer, Bulk Members, Bulk Sites, Folder Structure, Templates, Settings WPF UI startup cannot be verified programmatically
test expected why_human
Bulk Members tab — click Load Example, verify DataGrid populates with sample member rows 7 rows appear with GroupName, Email, Role columns and all IsValid = True Embedded-resource loading and DataGrid binding require runtime
test expected why_human
Bulk Sites tab — click Load Example, verify DataGrid populates with site rows including semicolon-delimited data 5 rows appear with Name, Alias, Type, Owners columns parsed correctly Requires runtime CSV parsing with auto-detected semicolon delimiter
test expected why_human
Bulk Members or Sites — import a CSV with one invalid row, verify the invalid row is visible in the DataGrid with an error message in the Errors column Valid column shows False, Errors column shows the specific validation message (e.g. 'Invalid email format') DataGrid rendering of CsvValidationRow<T> requires runtime
test expected why_human
Transfer tab — click Browse on Source, verify SitePickerDialog opens; after selecting a site, verify FolderBrowserDialog opens for library/folder selection Two-step dialog flow works, selected library/folder path displayed in the Transfer tab Dialog chaining requires a connected tenant and live UI interaction
test expected why_human
Templates tab — verify 5 capture option checkboxes are visible (Libraries, Folders, Permission Groups, Site Logo, Site Settings) All 5 checkboxes shown, all checked by default XAML checkbox rendering requires runtime
test expected why_human
On any bulk operation tab, click Execute after loading a CSV, verify the confirmation dialog appears before the operation starts ConfirmBulkOperationDialog shows with a summary message and Proceed/Cancel buttons Requires connected tenant or a mock; ShowConfirmDialog is wired through code-behind factory

Phase 4: Bulk Operations and Provisioning — Verification Report

Phase Goal: Users can execute bulk write operations (member additions, site creation, file transfer) with per-item error reporting and cancellation, capture site structures as reusable templates, apply templates to create new sites, and provision folder structures from CSV — all without silent partial failures.

Verified: 2026-04-03 Status: human_needed — All automated checks passed; 7 items require live UI or connected-tenant verification. Re-verification: No — initial verification.


Goal Achievement

Observable Truths

# Truth Status Evidence
1 Bulk write operations continue on error and report per-item results VERIFIED BulkOperationRunner.RunAsync catches per-item exceptions, wraps in BulkItemResult<T>.Failed, continues loop. 5 unit tests pass including RunAsync_SomeItemsFail_ContinuesAndReportsPerItem.
2 Cancellation propagates immediately and stops processing VERIFIED OperationCanceledException is re-thrown from BulkOperationRunner.RunAsync. Tests RunAsync_Cancelled_ThrowsOperationCanceled and RunAsync_CancelledMidOperation_StopsProcessing pass. Cancel button wired in all Views via CancelCommand.
3 File transfer (copy and move) works with per-file error reporting and conflict policies VERIFIED FileTransferService uses MoveCopyUtil.CopyFileByPath / MoveFileByPath with ResourcePath.FromDecodedUrl, delegates to BulkOperationRunner.RunAsync. All three conflict policies (Skip/Overwrite/Rename) implemented via MoveCopyOptions.
4 Bulk member addition uses Graph API for M365 groups with CSOM fallback VERIFIED BulkMemberService.AddMembersAsync delegates to BulkOperationRunner.RunAsync. Graph path uses GraphClientFactory+MsalTokenProvider. CSOM path uses EnsureUser + SiteGroups. clientId passed explicitly from ViewModel.
5 Bulk site creation creates Team and Communication sites with per-site error reporting VERIFIED BulkSiteService uses TeamSiteCollectionCreationInformation and CommunicationSiteCollectionCreationInformation via PnP Framework CreateSiteAsync. Delegated to BulkOperationRunner.RunAsync.
6 Site structures are captured as reusable templates and persisted locally VERIFIED TemplateService.CaptureTemplateAsync reads libraries (filtering hidden+system lists), folders (recursive), permission groups, logo, settings via CSOM. TemplateRepository.SaveAsync persists JSON with atomic tmp+Move write. 6 TemplateRepository tests pass.
7 Templates can be applied to create new sites with the captured structure VERIFIED TemplateService.ApplyTemplateAsync creates Team or Communication site via PnP Framework, then recreates libraries, folders (recursive), permission groups via CSOM. Key link to CaptureTemplateAsync / ApplyTemplateAsync in TemplatesViewModel confirmed.
8 Folder structures can be provisioned from CSV with parent-first ordering VERIFIED FolderStructureService.BuildUniquePaths sorts paths by depth. CreateFoldersAsync uses BulkOperationRunner.RunAsync. Tests BuildUniquePaths_FromExampleCsv_ReturnsParentFirst and BuildUniquePaths_DuplicateRows_Deduplicated pass.
9 CSV validation reports per-row errors before execution VERIFIED CsvValidationService uses CsvHelper with DetectDelimiter=true, BOM detection, per-row validation. 9 unit tests pass. DataGrid binds to CsvValidationRow<T>.IsValid and Errors columns.
10 Failed items can be exported as CSV after partial failures VERIFIED BulkResultCsvExportService.BuildFailedItemsCsv writes failed-only rows with Error+Timestamp columns. ExportFailedCommand wired in all 4 bulk operation ViewModels. 2 unit tests pass.
11 Retry Failed button re-runs only the failed items VERIFIED RetryFailedCommand in BulkMembersViewModel and BulkSitesViewModel populates _failedRowsForRetry from _lastResult.FailedItems and re-runs. Button bound in XAML for both tabs.
12 All 5 new tabs are registered in DI and wired to MainWindow VERIFIED All 5 services+ViewModels+Views registered in App.xaml.cs (lines 124-152). All 5 TabItems declared in MainWindow.xaml with named x:Name. Content set from DI in MainWindow.xaml.cs (lines 36-40).

Score: 12/12 truths verified


Required Artifacts

Artifact Expected Status Details
SharepointToolbox/Services/BulkOperationRunner.cs Shared bulk helper with continue-on-error VERIFIED RunAsync<TItem> with OperationCanceledException re-throw and per-item catch
SharepointToolbox/Core/Models/BulkOperationResult.cs Per-item result tracking VERIFIED BulkItemResult<T> with Success/Failed factories; BulkOperationSummary<T> with HasFailures, FailedItems
SharepointToolbox/Core/Models/SiteTemplate.cs Template JSON model VERIFIED SiteTemplate, TemplateSettings, TemplateLogo classes present
SharepointToolbox/Services/CsvValidationService.cs CSV parsing + validation VERIFIED CsvHelper with DetectDelimiter, BOM, per-row member/site/folder validation
SharepointToolbox/Infrastructure/Persistence/TemplateRepository.cs JSON persistence for templates VERIFIED SemaphoreSlim, atomic tmp+Move write, JsonSerializer, full CRUD
SharepointToolbox/Services/FileTransferService.cs CSOM file transfer VERIFIED MoveCopyUtil.CopyFileByPath/MoveFileByPath, ResourcePath.FromDecodedUrl, 3 conflict policies
SharepointToolbox/Services/BulkMemberService.cs Graph + CSOM member addition VERIFIED Graph SDK path + CSOM fallback, delegates to BulkOperationRunner.RunAsync
SharepointToolbox/Infrastructure/Auth/GraphClientFactory.cs Graph SDK client from MSAL VERIFIED MsalTokenProvider bridges MSAL PCA to BaseBearerTokenAuthenticationProvider
SharepointToolbox/Services/BulkSiteService.cs Bulk site creation VERIFIED Team + Communication site creation via PnP Framework, BulkOperationRunner.RunAsync
SharepointToolbox/Services/TemplateService.cs Site template capture + apply VERIFIED SystemListNames filter, recursive folder enumeration, permission group capture, apply creates site + recreates structure
SharepointToolbox/Services/FolderStructureService.cs Folder creation from CSV VERIFIED BuildUniquePaths parent-first sort, BulkOperationRunner.RunAsync, Web.Folders.Add
SharepointToolbox/Services/Export/BulkResultCsvExportService.cs Failed items CSV export VERIFIED CsvWriter with WriteHeader<T> + Error + Timestamp columns
SharepointToolbox/Views/Dialogs/ConfirmBulkOperationDialog.xaml Pre-write confirmation dialog VERIFIED Proceed/Cancel buttons, IsConfirmed property, TranslationSource bindings
SharepointToolbox/Views/Dialogs/FolderBrowserDialog.xaml Library/folder tree browser VERIFIED TreeView with lazy-load expansion, library load on Loaded event
SharepointToolbox/Resources/bulk_add_members.csv Example CSV — members VERIFIED Present as EmbeddedResource in csproj
SharepointToolbox/Resources/bulk_create_sites.csv Example CSV — sites VERIFIED Present as EmbeddedResource in csproj
SharepointToolbox/Resources/folder_structure.csv Example CSV — folder structure VERIFIED Present as EmbeddedResource in csproj
SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs Transfer tab ViewModel VERIFIED TransferAsync called, GetOrCreateContextAsync for both contexts, ExportFailedCommand
SharepointToolbox/ViewModels/Tabs/BulkMembersViewModel.cs Bulk Members ViewModel VERIFIED ParseAndValidateMembers, AddMembersAsync, RetryFailedCommand, ExportFailedCommand, LoadExampleCommand
SharepointToolbox/ViewModels/Tabs/BulkSitesViewModel.cs Bulk Sites ViewModel VERIFIED ParseAndValidateSites, CreateSitesAsync, RetryFailedCommand, ExportFailedCommand, LoadExampleCommand
SharepointToolbox/ViewModels/Tabs/FolderStructureViewModel.cs Folder Structure ViewModel VERIFIED ParseAndValidateFolders, CreateFoldersAsync, BuildUniquePaths called, ExportFailedCommand
SharepointToolbox/ViewModels/Tabs/TemplatesViewModel.cs Templates ViewModel VERIFIED CaptureTemplateAsync, ApplyTemplateAsync, TemplateRepository CRUD, RefreshCommand
SharepointToolbox/Views/Tabs/TransferView.xaml Transfer tab UI VERIFIED Source/dest site pickers, library/folder browse buttons, Copy/Move radio, conflict policy, progress, ExportFailed button
SharepointToolbox/Views/Tabs/BulkMembersView.xaml Bulk Members tab UI VERIFIED Import/LoadExample buttons, DataGrid with IsValid+Errors columns, RunCommand, RetryFailed, ExportFailed
SharepointToolbox/Views/Tabs/BulkSitesView.xaml Bulk Sites tab UI VERIFIED Same pattern as BulkMembers
SharepointToolbox/Views/Tabs/FolderStructureView.xaml Folder Structure tab UI VERIFIED DataGrid with Level1-4 columns and Errors column
SharepointToolbox/Views/Tabs/TemplatesView.xaml Templates tab UI VERIFIED Capture section with 5 checkboxes, Apply section with title/alias, template DataGrid
SharepointToolbox/App.xaml.cs DI registration for all Phase 4 types VERIFIED Lines 124-152: all 5 services, ViewModels, Views registered
SharepointToolbox/MainWindow.xaml 5 new tab items VERIFIED TransferTabItem, BulkMembersTabItem, BulkSitesTabItem, FolderStructureTabItem, TemplatesTabItem

From To Via Status Details
BulkOperationRunner.cs BulkOperationResult.cs returns BulkOperationSummary<T> WIRED return new BulkOperationSummary<TItem>(results) on line 34
FileTransferService.cs BulkOperationRunner.cs per-file delegation WIRED BulkOperationRunner.RunAsync called on line 33
FileTransferService.cs MoveCopyUtil CSOM file operations WIRED MoveCopyUtil.CopyFileByPath (line 85), MoveCopyUtil.MoveFileByPath (line 90)
BulkMemberService.cs BulkOperationRunner.cs per-row delegation WIRED BulkOperationRunner.RunAsync on line 28
GraphClientFactory.cs MsalClientFactory shared MSAL token WIRED _msalFactory.GetOrCreateClient(clientId) in CreateClientAsync
BulkSiteService.cs BulkOperationRunner.cs per-site delegation WIRED BulkOperationRunner.RunAsync on line 17
TemplateService.cs SiteTemplate.cs builds and returns model WIRED SiteTemplate constructed in CaptureTemplateAsync, pattern confirmed
FolderStructureService.cs BulkOperationRunner.cs per-folder error handling WIRED BulkOperationRunner.RunAsync on line 27
CsvValidationService.cs CsvHelper CsvReader with DetectDelimiter WIRED CsvReader with DetectDelimiter = true and detectEncodingFromByteOrderMarks: true
TemplateRepository.cs SiteTemplate.cs System.Text.Json serialization WIRED JsonSerializer.Serialize/Deserialize<SiteTemplate>
TransferViewModel.cs IFileTransferService.TransferAsync RunOperationAsync override WIRED _transferService.TransferAsync(srcCtx, dstCtx, job, progress, ct) on line 109
TransferViewModel.cs ISessionManager.GetOrCreateContextAsync context acquisition WIRED Called for both srcProfile and dstProfile on lines 106-107
BulkMembersView.xaml.cs TranslationSource localized labels WIRED All buttons use TranslationSource.Instance binding
TemplatesViewModel.cs ITemplateService capture and apply WIRED _templateService.CaptureTemplateAsync (line 112), ApplyTemplateAsync (line 148)
TemplatesViewModel.cs TemplateRepository template CRUD WIRED _templateRepo.SaveAsync, RenameAsync, DeleteAsync, GetAllAsync all called
App.xaml.cs All Phase 4 services DI registration WIRED AddTransient/AddSingleton for all 10 Phase 4 service types (lines 124-152)
MainWindow.xaml.cs All Phase 4 Views tab content wiring WIRED GetRequiredService<TransferView/BulkMembersView/BulkSitesView/FolderStructureView/TemplatesView>() lines 36-40
ConfirmBulkOperationDialog.xaml.cs TranslationSource localized button text WIRED Title and button text bound to bulk.confirm.* keys

Requirements Coverage

Requirement Source Plan Description Status Evidence
BULK-01 04-03, 04-08 File/folder transfer between sites with progress tracking SATISFIED FileTransferService + TransferViewModel + TransferView. Copy/Move modes, progress bar, cancel, per-file results.
BULK-02 04-04, 04-09 Bulk member addition from CSV SATISFIED BulkMemberService (Graph + CSOM) + BulkMembersViewModel (CSV import, preview, execute, retry, export)
BULK-03 04-05, 04-09 Bulk site creation from CSV SATISFIED BulkSiteService (Team + Communication) + BulkSitesViewModel (CSV import, preview, execute)
BULK-04 04-01, 04-03, 04-04, 04-05, 04-06, 04-08, 04-09 All bulk operations support cancellation SATISFIED BulkOperationRunner.RunAsync propagates OperationCanceledException. Cancel button wired in all 4 Views.
BULK-05 04-01, 04-03, 04-04, 04-05, 04-06, 04-08, 04-09 Per-item error reporting (no silent failures) SATISFIED BulkItemResult<T>.Failed per item. HasFailures/FailedItems exposed. ExportFailed + RetryFailed in all Views.
TMPL-01 04-06, 04-10 Capture site structure as template SATISFIED TemplateService.CaptureTemplateAsync captures libraries (filtered), folders (recursive), groups, logo, settings per SiteTemplateOptions
TMPL-02 04-06, 04-10 Apply template to create new site SATISFIED TemplateService.ApplyTemplateAsync creates Team or Communication site, recreates structure
TMPL-03 04-02 Templates persist locally as JSON SATISFIED TemplateRepository with atomic write (tmp + Move), JsonSerializer, 6 passing tests
TMPL-04 04-02, 04-10 Manage templates (create, rename, delete) SATISFIED TemplatesViewModel has CaptureCommand, RenameCommand, DeleteCommand. TemplateRepository has full CRUD.
FOLD-01 04-06, 04-09 Folder structure creation from CSV SATISFIED FolderStructureService.CreateFoldersAsync with parent-first ordering. FolderStructureViewModel with CSV import, preview, execute.
FOLD-02 04-07, 04-09 Example CSV templates provided SATISFIED 3 example CSVs in Resources/ as EmbeddedResource. LoadExampleCommand in all 3 CSV ViewModels reads from embedded assembly.

All 11 requirement IDs accounted for. No orphaned requirements.


Anti-Patterns Found

File Observation Severity Impact
BulkMembersView.xaml DataGrid shows IsValid as text column ("True"/"False") but no row-level visual highlighting (no DataGrid.RowStyle + DataTrigger for red background on invalid rows) Warning Invalid rows are identifiable via column text, but visually indistinct. Fix requires adding RowStyle with DataTrigger IsValid=False -> Background=LightCoral.
BulkSitesView.xaml Same as above — no row highlighting for invalid rows Warning Same impact
FolderStructureView.xaml Same as above Warning Same impact

No blocker anti-patterns. No TODO/FIXME/placeholder comments in service or ViewModel files. No throw new NotImplementedException. All services have real implementations.


Human Verification Required

1. Application Launch with 5 New Tabs

Test: Run dotnet run --project SharepointToolbox/SharepointToolbox.csproj and count tabs in MainWindow Expected: 10 visible tabs: Permissions, Storage, Search, Duplicates, Transfer, Bulk Members, Bulk Sites, Folder Structure, Templates, Settings Why human: WPF application startup, DI resolution, and XAML rendering cannot be verified programmatically

2. Bulk Members — Load Example Flow

Test: Click the "Load Example" button on the Bulk Members tab Expected: DataGrid populates with 7 sample rows (all IsValid = True). PreviewSummary shows "7 rows, 7 valid, 0 invalid" Why human: Requires embedded resource loading, CsvHelper parsing, and DataGrid MVVM binding at runtime

3. Bulk Sites — Semicolon CSV Auto-Detection

Test: Click "Load Example" on Bulk Sites tab Expected: 5 rows parsed correctly despite semicolon delimiter. Name, Alias, Type columns show correct values. Why human: DetectDelimiter behavior requires runtime CsvHelper parsing

4. Invalid Row Display in DataGrid

Test: Import a CSV with one invalid row (e.g., missing email) to Bulk Members Expected: Invalid row visible, IsValid column shows "False", Errors column shows the specific error message Why human: DataGrid rendering requires runtime

5. Confirmation Dialog Before Execution

Test: Load a valid CSV on Bulk Members and click "Add Members" Expected: ConfirmBulkOperationDialog appears with operation summary and Proceed/Cancel buttons before any SharePoint call is made Why human: Requires ShowConfirmDialog factory to fire via code-behind at runtime

6. Transfer Tab — Two-Step Browse Flow

Test: On Transfer tab, click Browse for Source; complete the SitePickerDialog; observe FolderBrowserDialog opens Expected: After selecting a site in SitePickerDialog, FolderBrowserDialog opens and loads document libraries from that site Why human: Requires connected tenant and live dialog interaction

7. Templates Tab — Capture Checkboxes

Test: Navigate to Templates tab Expected: Capture section shows 5 checkboxes (Libraries, Folders, Permission Groups, Site Logo, Site Settings), all checked by default Why human: XAML checkbox default state and layout require runtime rendering


Build and Test Summary

Build: dotnet build SharepointToolbox.slnx — Build succeeded, 0 errors Tests: 122 passed, 22 skipped (all skipped tests require live SharePoint tenant — correctly marked), 0 failed Key test results:

  • BulkOperationRunner: 5/5 pass (all semantics verified including continue-on-error and cancellation)
  • CsvValidationService: 9/9 pass (comma + semicolon delimiters, BOM, member/site/folder validation)
  • TemplateRepository: 6/6 pass (round-trip JSON, GetAll, Delete, Rename)
  • FolderStructureService: 4/5 pass + 1 skip (BuildUniquePaths logic verified; live SharePoint test skipped)
  • BulkResultCsvExportService: 2/2 pass (failed-only filtering, Error+Timestamp columns)

Verified: 2026-04-03T00:00:00Z Verifier: Claude (gsd-verifier)