Commit Graph

239 Commits

Author SHA1 Message Date
Dev
84cd569fb7 feat(04-06): implement TemplateService and FolderStructureService
- FolderStructureService.CreateFoldersAsync creates folder hierarchy from CSV rows using BulkOperationRunner
- FolderStructureService.BuildUniquePaths deduplicates and sorts paths parent-first by slash depth
- TemplateService already committed; verified compilation and interface compliance
- FolderStructureServiceTests: 4 unit tests pass (BuildUniquePaths edge cases, deduplication, empty levels, BuildPath) + 1 skip
- TemplateServiceTests: 3 unit tests pass (interface impl, SiteTemplate defaults, SiteTemplateOptions defaults) + 2 skip
2026-04-03 10:07:49 +02:00
Dev
773393c4c0 docs(04-04): complete BulkMemberService plan — Graph API member addition with CSOM fallback
- Create 04-04-SUMMARY.md with full execution details and deviation docs
- Update STATE.md: plan 04 complete, new decisions, session record
- Update REQUIREMENTS.md: BULK-02 marked complete (BULK-04/05 already done in 04-01)
2026-04-03 10:06:37 +02:00
Dev
c4d8124a81 docs(04-02): complete CsvValidationService + TemplateRepository plan
- 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
2026-04-03 10:05:21 +02:00
Dev
0cf6f50448 docs(04-03): complete FileTransferService plan — CSOM file transfer with conflict policies
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 10:05:00 +02:00
Dev
98fa16a195 docs(04-05): complete BulkSiteService plan — PnP Framework Team + Communication site creation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 10:04:03 +02:00
Dev
f3a1c352c7 feat(04-02): implement CsvValidationService and TemplateRepository with tests
- CsvValidationService: CsvHelper-based parsing with DetectDelimiter, BOM detection,
  per-row validation for BulkMemberRow/BulkSiteRow/FolderStructureRow
- TemplateRepository: atomic JSON write (tmp + File.Move) with SemaphoreSlim,
  supports GetAll/GetById/Save/Delete/Rename operations
- CsvValidationServiceTests: 9 passing tests (email validation, delimiter detection,
  BOM handling, folder/site/member validation)
- TemplateRepositoryTests: 6 passing tests (round-trip, GetAll, delete, rename,
  empty directory, non-existent id)
- All previously-skipped scaffold tests now active and passing (15 total)
2026-04-03 10:03:41 +02:00
Dev
ac74d31933 feat(04-03): implement FileTransferService with MoveCopyUtil and conflict policies
- FileTransferService.cs: CSOM copy/move via MoveCopyUtil.CopyFileByPath/MoveFileByPath
- Conflict policies: Skip (catch ServerException), Overwrite (overwrite=true), Rename (KeepBoth=true)
- ResourcePath.FromDecodedUrl for special character support
- Recursive folder enumeration with system folder filtering
- EnsureFolderAsync creates intermediate destination folders
- Best-effort metadata preservation (ResetAuthorAndCreatedOnCopy=false)
- FileTransferServiceTests.cs: 4 passing tests, 3 skipped (integration)
2026-04-03 10:02:57 +02:00
Dev
b0956adaa3 feat(04-05): implement BulkSiteService with PnP Framework site creation
- BulkSiteService creates Team sites via TeamSiteCollectionCreationInformation with owners/members
- BulkSiteService creates Communication sites via CommunicationSiteCollectionCreationInformation with generated URL
- Per-site error handling via BulkOperationRunner with continue-on-error semantics
- SanitizeAlias generates URL-safe aliases from site names for Communication sites
- BulkSiteServiceTests: 3 pass (interface check + model defaults + CSV parsing), 3 skip (live SP)
- Fixed pre-existing BulkMemberService.cs Group type ambiguity (MSCSC.Group vs Graph.Models.Group)
2026-04-03 10:02:09 +02:00
Dev
fdcd4c8377 docs(04-01): complete Phase 4 Plan 01 — models, interfaces, BulkOperationRunner
- Create 04-01-SUMMARY.md with full execution details and deviation docs
- Update STATE.md: progress 73%, new decisions, session record
- Update ROADMAP.md: Phase 4 In Progress, 1/10 plans complete
- Mark requirements BULK-04 and BULK-05 complete in REQUIREMENTS.md
2026-04-03 09:55:26 +02:00
Dev
39deed9d8d feat(04-01): add Phase 4 models, interfaces, BulkOperationRunner, and test scaffolds
- Install CsvHelper 33.1.0 and Microsoft.Graph 5.74.0 (main + test projects)
- Add 14 core model/enum files (BulkOperationResult, BulkMemberRow, BulkSiteRow, TransferJob, FolderStructureRow, SiteTemplate, SiteTemplateOptions, TemplateLibraryInfo, TemplateFolderInfo, TemplatePermissionGroup, ConflictPolicy, TransferMode, CsvValidationRow)
- Add 6 service interfaces (IFileTransferService, IBulkMemberService, IBulkSiteService, ITemplateService, IFolderStructureService, ICsvValidationService)
- Add BulkOperationRunner with continue-on-error and cancellation support
- Add BulkResultCsvExportService stub (compile-ready)
- Add test scaffolds: BulkOperationRunnerTests (5 passing), BulkResultCsvExportServiceTests (2 passing), CsvValidationServiceTests (6 skipped), TemplateRepositoryTests (4 skipped)
2026-04-03 09:53:05 +02:00
Dev
d73e50948d docs(04): create Phase 4 plan — 10 plans for Bulk Operations and Provisioning
Wave 0: models, interfaces, BulkOperationRunner, test scaffolds
Wave 1: CsvValidationService, TemplateRepository, FileTransferService,
        BulkMemberService, BulkSiteService, TemplateService, FolderStructureService
Wave 2: Localization, shared dialogs, example CSV resources
Wave 3: TransferVM+View, BulkMembers/BulkSites/FolderStructure VMs+Views,
        TemplatesVM+View, DI registration, MainWindow wiring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:38:33 +02:00
Dev
97fc29c15e docs(04): research phase domain for Bulk Operations and Provisioning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:17:41 +02:00
Dev
97d1e10faf docs(state): record phase 4 context session
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:07:43 +02:00
Dev
6dd5faf65d docs(04): capture phase context for Bulk Operations and Provisioning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:07:34 +02:00
Dev
43dd6ce17f docs(03-08): complete SearchViewModel + DuplicatesViewModel + Views plan — Phase 3 complete
- 3 tasks completed, 9 files created/modified
- Visual checkpoint pending: all three Phase 3 tabs wired and ready for UI verification
2026-04-02 16:10:54 +02:00
Dev
1f2a49d7d3 feat(03-08): DI registration + MainWindow wiring for Search and Duplicates tabs
- App.xaml.cs: register ISearchService, SearchCsvExportService, SearchHtmlExportService, SearchViewModel, SearchView, IDuplicatesService, DuplicatesHtmlExportService, DuplicatesViewModel, DuplicatesView
- MainWindow.xaml: add x:Name to SearchTabItem and DuplicatesTabItem (remove FeatureTabBase stubs)
- MainWindow.xaml.cs: wire SearchTabItem.Content and DuplicatesTabItem.Content via DI
2026-04-02 15:45:29 +02:00
Dev
0984a36bc7 feat(03-08): create DuplicatesViewModel, DuplicatesView XAML and code-behind
- DuplicatesViewModel: ModeFiles/Folders, criteria checkboxes, group flattening to DuplicateRow
- Uses TenantProfile site URL override pattern (ctx.Url is read-only)
- ExportHtmlCommand exports DuplicateGroup list via DuplicatesHtmlExportService
- DuplicatesView.xaml: type selector, criteria panel + flattened DataGrid
- DuplicatesView.xaml.cs: DI constructor with DataContext wiring
2026-04-02 15:44:26 +02:00
Dev
7e6d39a3db feat(03-08): create SearchViewModel, SearchView XAML and code-behind
- SearchViewModel: full filter props, RunOperationAsync via ISearchService
- Uses TenantProfile site URL override pattern (ctx.Url is read-only)
- ExportCsvCommand + ExportHtmlCommand with CanExport guard
- SearchView.xaml: filter panel + DataGrid with all 8 columns
- SearchView.xaml.cs: DI constructor with DataContext wiring
2026-04-02 15:43:22 +02:00
Dev
50c7ab19f5 docs(03-05): complete Search and Duplicate export services plan
- 9/9 export tests pass (6 Search + 3 Duplicates)
- SearchCsvExportService, SearchHtmlExportService, DuplicatesHtmlExportService fully implemented
- Requirements SRCH-03, SRCH-04, DUPL-03 satisfied
2026-04-02 15:40:30 +02:00
Dev
82acc81e13 docs(03-07): complete StorageViewModel and StorageView plan — SUMMARY, STATE, ROADMAP updated 2026-04-02 15:40:07 +02:00
Dev
fc1ba00aa8 feat(03-05): implement DuplicatesHtmlExportService with grouped cards
- Replace stub with full grouped HTML export (port of PS Export-DuplicatesToHTML)
- One collapsible card per DuplicateGroup with item count badge and path table
- Uses System.IO.File explicitly per WPF project pattern
- 3/3 DuplicatesHtmlExportServiceTests pass; 9/9 total export tests pass
2026-04-02 15:38:43 +02:00
Dev
e08452d1bf feat(03-07): create StorageView XAML, DI registration, and MainWindow wiring
- StorageView.xaml: DataGrid with IndentLevel-based name indentation
- StorageView.xaml.cs: code-behind wiring DataContext to StorageViewModel
- IndentConverter.cs: IndentConverter, BytesConverter, InverseBoolConverter
- App.xaml: register converters and RightAlignStyle as Application.Resources
- App.xaml.cs: register IStorageService, StorageCsvExportService, StorageHtmlExportService, StorageViewModel, StorageView
- MainWindow.xaml: add x:Name=StorageTabItem to Storage TabItem
- MainWindow.xaml.cs: wire StorageTabItem.Content from DI
2026-04-02 15:38:20 +02:00
Dev
e174a18350 feat(03-07): create StorageViewModel with IStorageService orchestration and export commands
- Rule 1: Fixed ctx.Url read-only bug — use new TenantProfile with site URL for GetOrCreateContextAsync
- Rule 3: Added missing System.IO using to SearchCsvExportService and SearchHtmlExportService
2026-04-02 15:36:27 +02:00
Dev
9a55c9e7d0 docs(03-04): complete SearchService and DuplicatesService plan — 2/2 tasks, 5 MakeKey tests pass 2026-04-02 15:33:47 +02:00
Dev
e83c4f34f1 docs(03-06): complete Phase 3 localization plan — 54 EN/FR keys added for Storage, Search, Duplicates tabs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 15:32:56 +02:00
Dev
47e6cf62d2 docs(03-03): complete Storage export services plan — CSV and HTML exporters
- Add 03-03-SUMMARY.md: StorageCsvExportService and StorageHtmlExportService
- Update STATE.md: advance to plan 03-04, record metrics and decision
- Update ROADMAP.md: phase 3 progress 3/8 plans complete
2026-04-02 15:32:03 +02:00
Dev
df5f79d1cb feat(03-04): implement DuplicatesService composite key grouping for files and folders
- File mode: Search API KQL pagination matching SearchService pattern
- Folder mode: CAML FSObjType=1 via SharePointPaginationHelper.GetAllItemsAsync
- MakeKey composite key (name+size+dates+counts) matches DuplicatesServiceTests scaffold
- Groups only items with count >= 2, ordered by group size then name
- ExtractLibraryFromPath derives library name from path relative to site URL
- SelectProperties added per-item (StringCollection has no AddRange)
2026-04-02 15:31:57 +02:00
Dev
938de30437 feat(03-06): add Phase 3 EN/FR localization keys for Storage, Search, and Duplicates tabs
- Added 14 Storage tab keys (chk.per.lib, chk.subsites, stor.note, btn.gen.storage, btn.open.storage, stor.col.*, stor.rad.*)
- Added 26 File Search tab keys (grp.search.filters, lbl.extensions, ph.extensions, lbl.regex, ph.regex, date filters, lbl/ph.library, lbl.max.results, lbl.site.url, btn.run.search, btn.open.search, srch.col.*, srch.rad.*)
- Added 14 Duplicates tab keys (grp.dup.type, rad.dup.*, grp.dup.criteria, lbl.dup.note, chk.dup.*, chk.include.subsites, ph.dup.lib, btn.run.scan, btn.open.results)
- Matching FR translations in Strings.fr.resx with proper French text
- 54 new static properties in Strings.Designer.cs (dot-to-underscore naming convention)
2026-04-02 15:31:25 +02:00
Dev
9e3d5016e6 feat(03-04): implement SearchService KQL pagination with 500-row batches and 50,000 hard cap
- KQL builder for extension, date, creator, editor, library filters
- Pagination via StartRow += 500, stops at MaxStartRow or MaxResults
- Filters _vti_history/ version history paths from results
- Client-side Regex filter on file name and title
- ValidateKqlLength enforces 4096-char SharePoint limit
- SelectProperties added one-by-one (StringCollection has no AddRange)
2026-04-02 15:30:44 +02:00
Dev
eafaa15459 feat(03-03): implement StorageHtmlExportService
- Replace string.Empty stub with full BuildHtml implementation
- Self-contained HTML with inline CSS and JS — no external dependencies
- toggle(i) JS function with collapsible subfolder rows (sf-{i} IDs)
- _togIdx counter reset at start of each BuildHtml call (per PS pattern)
- RenderNode/RenderChildNode for recursive tree rendering
- FormatSize helper: B/KB/MB/GB adaptive display
- HtmlEncode via System.Net.WebUtility
- Add explicit System.IO using (required in WPF project)
2026-04-02 15:30:34 +02:00
Dev
94ff181035 feat(03-03): implement StorageCsvExportService
- Replace string.Empty stub with full BuildCsv implementation
- UTF-8 BOM header row: Library,Site,Files,Total Size (MB),Version Size (MB),Last Modified
- RFC 4180 CSV quoting via Csv() helper
- FormatMb() converts bytes to MB with 2 decimal places
- Add explicit System.IO using (required in WPF project)
2026-04-02 15:29:45 +02:00
Dev
3730b54527 docs(03-02): complete StorageService plan — CSOM scan engine implemented
- Create 03-02-SUMMARY.md with full deviation and test documentation
- Update STATE.md: position = 03-02 complete, Wave 2 next (03-03/04/06)
- Update ROADMAP.md: Phase 3 at 2/8 plans complete
- Note auto-fixed Rule 3 blocker: created missing 03-01 export stubs and test scaffolds
2026-04-02 15:28:08 +02:00
Dev
556fad1377 docs(03-01): complete Wave 0 plan — models, interfaces, export stubs, test scaffolds
- 7 pure-logic tests pass (VersionSizeBytes + MakeKey composite key)
- 0 build errors, 15 export tests fail as expected (stubs)
- 12 requirements marked complete (STOR-01/05, SRCH-01/04, DUPL-01/03)
2026-04-02 15:27:35 +02:00
Dev
b5df0641b0 feat(03-02): implement StorageService CSOM StorageMetrics scan engine
- Add StorageService implementing IStorageService
- Load Folder.StorageMetrics, TimeLastModified, Name, ServerRelativeUrl in one CSOM round-trip per folder
- CollectStorageAsync returns one StorageNode per document library at IndentLevel=0
- With FolderDepth>0, CollectSubfoldersAsync recurses into child folders
- All CSOM calls use ExecuteQueryRetryHelper.ExecuteQueryRetryAsync (3 call sites)
- System/hidden lists skipped (Hidden=true or BaseType != DocumentLibrary)
- Forms/ and _-prefixed system folders skipped during subfolder recursion
- ct.ThrowIfCancellationRequested() called at top of every recursive step
2026-04-02 15:26:16 +02:00
Dev
08e4d2ee7d feat(03-01): create Phase 3 export stubs and test scaffolds
- Add StorageCsvExportService, StorageHtmlExportService stub (Plan 03-03)
- Add SearchCsvExportService, SearchHtmlExportService stub (Plan 03-05)
- Add DuplicatesHtmlExportService stub (Plan 03-05)
- Add StorageServiceTests, SearchServiceTests, DuplicatesServiceTests scaffolds
- Add export test scaffolds for all 4 Phase 3 export services
- 7 pure-logic tests pass (VersionSizeBytes + MakeKey); 4 CSOM stubs skip
2026-04-02 15:25:20 +02:00
Dev
b52f60f8eb feat(03-01): create 7 core models and 3 service interfaces for Phase 3
- StorageNode, StorageScanOptions models
- SearchResult, SearchOptions models
- DuplicateItem, DuplicateGroup, DuplicateScanOptions models
- IStorageService, ISearchService, IDuplicatesService interfaces
2026-04-02 15:23:04 +02:00
Dev
d09db015f2 docs(phase-03): research storage, search, and duplicate detection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:41:39 +02:00
Dev
20780318a3 docs(phase-02): complete phase execution — 7/7 verified, advancing to phase 03
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:29:22 +02:00
Dev
80a3873a15 fix(02-07): bind export buttons to localization keys (rad.csv.perms, rad.html.perms)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:29:03 +02:00
Dev
6e9a0033f2 docs(02-07): complete Permissions integration plan — Phase 2 done
- Created 02-07-SUMMARY.md: PermissionsView XAML wired into MainWindow, all Phase 2 DI registered, human-verified
- Updated STATE.md: Phase 2 complete, 16/22 plans done, new decisions recorded
- Updated ROADMAP.md: Phase 2 all 7 plans checked, status Complete 2026-04-02

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:21:18 +02:00
Dev
afe69bd37f feat(02-07): create PermissionsView XAML + code-behind and register DI
- Created PermissionsView.xaml with left scan-config panel and right results DataGrid
- Created PermissionsView.xaml.cs wiring ViewModel via IServiceProvider, factory for SitePickerDialog
- Updated App.xaml.cs: registered IPermissionsService, ISiteListService, CsvExportService,
  HtmlExportService, PermissionsViewModel, PermissionsView, SitePickerDialog, and
  Func<TenantProfile, SitePickerDialog> factory; also registered ISessionManager -> SessionManager
- Updated MainWindow.xaml: replaced FeatureTabBase stub with named PermissionsTabItem
- Updated MainWindow.xaml.cs: wires PermissionsTabItem.Content from DI-resolved PermissionsView
- Added CurrentProfile public accessor, SitesSelectedLabel computed property, and
  IsMaxDepth toggle property to PermissionsViewModel
- Build: 0 errors, 0 warnings. Tests: 60 passed, 3 skipped (live/interactive)
2026-04-02 14:13:45 +02:00
Dev
e74cffbe31 docs(02-06): complete PermissionsViewModel and SitePickerDialog plan
- Add 02-06-SUMMARY.md with TDD results and deviation documentation
- Update STATE.md: progress bar 87%, record metrics, ISessionManager decision
- Update ROADMAP.md: phase 02-permissions now 6/7 summaries (In Progress)
2026-04-02 14:09:06 +02:00
Dev
f98ca60990 feat(02-06): implement PermissionsViewModel with multi-site scan and SitePickerDialog
- PermissionsViewModel extends FeatureViewModelBase, implements RunOperationAsync
- Multi-site mode: loops SelectedSites; single-site mode: uses SiteUrl
- ExportCsvCommand and ExportHtmlCommand enabled only when Results.Count > 0
- OpenSitePickerCommand uses dialog factory pattern (Func<Window>?)
- OnTenantSwitched clears Results, SiteUrl, SelectedSites
- Flat ObservableProperty booleans (IncludeInherited, ScanFolders, etc.) build ScanOptions record
- SitePickerDialog XAML: filterable list with CheckBox column, Title, URL columns
- SitePickerDialog code-behind: loads sites on Window.Loaded, exposes SelectedUrls
- ISessionManager interface extracted for testability (SessionManager implements it)
- StartScanAsync_WithMultipleSiteUrls_CallsServiceOncePerUrl test passes (60/60 + 3 skip)
2026-04-02 14:06:39 +02:00
Dev
c462a0b310 test(02-06): add failing test for PermissionsViewModel multi-site scan
- Write StartScanAsync_WithMultipleSiteUrls_CallsServiceOncePerUrl test (RED)
- Create ISessionManager interface for testability
- Implement ISessionManager on SessionManager
- Add PermissionsViewModel stub (NotImplementedException) to satisfy compile
2026-04-02 14:04:22 +02:00
Dev
48ccf5891b docs(02-04): add self-check result to SUMMARY.md 2026-04-02 14:01:24 +02:00
Dev
7805e0b015 docs(02-04): complete export services plan — CsvExportService and HtmlExportService
- SUMMARY.md created for plan 02-04
- STATE.md: progress updated to 87%, session recorded, decision added
- ROADMAP.md: phase 02 progress updated (5/7 plans complete)
2026-04-02 14:01:12 +02:00
Dev
e3ab31937a feat(02-04): implement HtmlExportService with self-contained interactive HTML report
- Stats cards: Total Entries, Unique Permission Sets, Distinct Users/Groups
- Type badges: site-coll (blue), site (green), list (amber), folder (gray)
- Unique/Inherited badges based on HasUniquePermissions flag
- User pills with external-user CSS class for #EXT# logins
- Inline JS filterTable() function for client-side row filtering
- WriteAsync uses UTF-8 without BOM for HTML
- All 3 HtmlExportServiceTests pass
2026-04-02 13:59:46 +02:00
Dev
44913f8075 feat(02-04): implement CsvExportService with Merge-PermissionRows port
- GroupBy (Users, PermissionLevels, GrantedThrough) to merge duplicate entries
- Pipe-joins URLs and Titles for merged rows
- RFC 4180 CSV escaping: all fields double-quoted, internal quotes doubled
- WriteAsync uses UTF-8 with BOM for Excel compatibility
- All 3 CsvExportServiceTests pass
2026-04-02 13:58:39 +02:00
Dev
ac86bbc302 docs(02-02): complete PermissionsService plan — models, interface, scan engine
- Created 02-02-SUMMARY.md with full execution record
- Updated STATE.md with decisions (CSOM type constraints) and progress
- Updated ROADMAP.md (phase 02: 4/7 summaries, In Progress)
- Marked PERM-07 complete in REQUIREMENTS.md
2026-04-02 13:56:53 +02:00
Dev
0480f97059 docs(02-01): complete Wave 0 test scaffold plan
- 02-01-SUMMARY.md: classification helper + 5 test scaffolds across PERM-01..06
- STATE.md: progress 73%, decisions logged, session updated
- ROADMAP.md: phase 02 progress 4/7 summaries
2026-04-02 13:56:02 +02:00