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
Dev
9f2e2f9899
fix(02-01): add export service stubs and fix PermissionsService compile errors
...
[Rule 3 - Blocking] CsvExportService/HtmlExportService stubs added so export test
files compile. [Rule 1 - Bug] PermissionsService: removed Principal.Email (not on
Principal, only on User) and changed folder param from Folder to ListItem (SecurableObject).
2026-04-02 13:53:45 +02:00
Dev
d17689cc46
docs(02-03): complete SiteListService plan
...
- 02-03-SUMMARY.md created
- STATE.md: progress updated 67%, decisions added, session recorded
- ROADMAP.md: phase 2 progress updated (2/7 summaries)
2026-04-02 13:52:17 +02:00
Dev
c04d88882d
docs(02-05): complete Phase 2 localization keys plan
...
- Added 02-05-SUMMARY.md with 15 EN+FR localization keys plan results
- Updated STATE.md progress (67%), session, and metrics
- Updated ROADMAP.md phase 02 progress (2/7 summaries)
- Marked PERM-01, PERM-02, PERM-04, PERM-05, PERM-06 requirements complete
2026-04-02 13:52:03 +02:00
Dev
83464a009c
test(02-01): scaffold export service test stubs for PERM-05 and PERM-06
...
- CsvExportServiceTests.cs: 3 real [Fact] tests (header row, empty list, merge rows) — PERM-05
- HtmlExportServiceTests.cs: 3 real [Fact] tests (user names, empty HTML, external user marker) — PERM-06
- Both files reference CsvExportService/HtmlExportService from Plan 03 — compile errors expected until Plan 03 creates the services
2026-04-02 13:51:54 +02:00
Dev
4a6594d9e8
feat(02-02): define PermissionEntry, ScanOptions, and IPermissionsService
...
- PermissionEntry record with 9 fields matching PS Generate-PnPSitePermissionRpt
- ScanOptions record with defaults: IncludeInherited=false, ScanFolders=true, FolderDepth=1, IncludeSubsites=false
- IPermissionsService interface with ScanSiteAsync method enabling ViewModel mocking
2026-04-02 13:51:15 +02:00
Dev
57c258015b
feat(02-05): add 15 Phase 2 localization keys to EN/FR resx and Designer
...
- Added 15 keys to Strings.resx with English values (grp.scan.opts, chk.scan.folders, chk.recursive, lbl.folder.depth, chk.max.depth, chk.inherited.perms, grp.export.fmt, rad.csv.perms, rad.html.perms, btn.gen.perms, btn.open.perms, btn.view.sites, perm.site.url, perm.or.select, perm.sites.selected)
- Added same 15 keys to Strings.fr.resx with genuine French translations (no English fallback)
- Added 15 static properties to Strings.Designer.cs following dot-to-underscore naming pattern
2026-04-02 13:50:43 +02:00
Dev
a9f6bde686
test(02-01): scaffold PermissionsService, ViewModel, and classification test stubs
...
- PermissionEntryHelper.cs: pure static IsExternalUser, FilterPermissionLevels, IsSharingLinksGroup
- PermissionEntryClassificationTests.cs: 7 real [Fact] tests — all passing immediately
- PermissionsServiceTests.cs: 2 stubs (PERM-01, PERM-04) skipped until Plan 02 CSOM impl
- PermissionsViewModelTests.cs: 1 stub (PERM-02) skipped until Plan 02 ViewModel impl
2026-04-02 13:50:41 +02:00
Dev
78b3d4f759
feat(02-03): implement ISiteListService and SiteListService with admin URL derivation
...
- SiteInfo record added to Core/Models
- ISiteListService interface with GetSitesAsync signature
- SiteListService derives admin URL via Regex, connects via SessionManager
- Filters to Active sites only, excludes OneDrive personal (-my.sharepoint.com)
- Access denied ServerException wrapped as InvalidOperationException with actionable message
- DeriveAdminUrl marked internal static for unit testability
- InternalsVisibleTo added to AssemblyInfo.cs to expose internal to test project
- 2 DeriveAdminUrl tests pass; full suite: 53 pass, 4 skip, 0 fail
2026-04-02 13:50:35 +02:00
Dev
5c10840581
test(02-03): add failing tests for SiteListService.DeriveAdminUrl
...
- Two tests for DeriveAdminUrl: standard URL and trailing-slash URL
- Tests fail (RED) — SiteListService not yet implemented
2026-04-02 13:49:16 +02:00
Dev
097d7b3326
docs(phase-02): add research, validation strategy, and 7 plans for Permissions phase
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-02 13:40:33 +02:00
Dev
55819bd059
docs(02-permissions): create phase 2 plan — 7 plans across 4 waves
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-02 13:38:09 +02:00
Dev
031a7dbc0f
docs(phase-02): research permissions phase domain
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-02 13:25:38 +02:00
Dev
27d654d86a
docs(phase-01): complete phase execution — 11/11 verified, advancing to phase 02
2026-04-02 13:02:50 +02:00
Dev
62a7deb6e9
docs(01-08): complete plan — human visual checkpoint approved, Phase 1 Foundation done
...
- Task 2 (human-verify checkpoint) approved: all 7 visual checks passed
- Updated SUMMARY to document 3 runtime fix commits (DI registration, FR translations)
- STATE.md: plan complete, session updated
- ROADMAP.md: Phase 1 confirmed Complete 8/8
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-02 12:55:22 +02:00
Dev
0b8a86a58a
fix(01-08): add real French translations (stubs were identical to English)
2026-04-02 12:52:16 +02:00
Dev
6211f65a5e
fix(01-08): provide file paths to ProfileRepository and SettingsRepository via factory registration
2026-04-02 12:47:11 +02:00
Dev
c66efdadfa
fix(01-08): register ProfileRepository and SettingsRepository in DI container
2026-04-02 12:45:59 +02:00
Dev
991c92e83a
docs(01-08): complete phase 1 final verification plan — awaiting human checkpoint
...
- 44/44 non-interactive tests pass, 1 MSAL interactive skip (expected)
- Build: 0 errors, 0 warnings with -warnaserror
- ROADMAP.md: Phase 1 marked Complete (8/8 summaries)
- STATE.md: progress 100%, decisions recorded, checkpoint pause noted
- SUMMARY.md created for 01-08
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-02 12:43:28 +02:00
Dev
334a5f10ad
chore(01-08): run full test suite — 44 passed, 1 skipped, 0 failed
...
- dotnet build with -warnaserror: 0 warnings, 0 errors
- 44 unit/integration tests pass
- 1 interactive MSAL test skipped (expected)
- Build clean on SharepointToolbox.slnx
2026-04-02 12:41:55 +02:00
Dev
405a013375
docs(01-07): complete ProfileManagementDialog + SettingsView plan
...
- Create 01-07-SUMMARY.md with full documentation
- Update STATE.md: progress 88%, decisions added, session recorded
- Update ROADMAP.md: Phase 1 at 7/8 plans
2026-04-02 12:40:36 +02:00
Dev
0665152e0d
feat(01-07): add SettingsView and wire into MainWindow Settings tab
...
- Create Views/Tabs/SettingsView.xaml (UserControl with language ComboBox en/fr, DataFolder TextBox and Browse button using TranslationSource)
- Create Views/Tabs/SettingsView.xaml.cs (DI constructor injection of SettingsViewModel, LoadAsync on Loaded)
- Update MainWindow.xaml to add xmlns:views namespace and clear placeholder TextBlock from SettingsTabItem
- Register SettingsView as Transient in DI; resolve and set as SettingsTabItem.Content from MainWindow constructor
- All 42 unit tests pass, 0 build errors
2026-04-02 12:38:38 +02:00
Dev
cb7cf93c52
feat(01-07): add ProfileManagementDialog with DI factory wiring
...
- Create Views/Dialogs/ProfileManagementDialog.xaml (modal Window with Name/TenantUrl/ClientId fields and TranslationSource bindings)
- Create Views/Dialogs/ProfileManagementDialog.xaml.cs (DI constructor injection, LoadAsync on Loaded)
- Add OpenProfileManagementDialog factory delegate to MainWindowViewModel
- Wire ManageProfilesCommand to open dialog via factory, reload profiles after close
- Register ProfileManagementDialog as Transient in DI (App.xaml.cs)
- Inject IServiceProvider into MainWindow constructor for DI-resolved dialog factory
2026-04-02 12:38:31 +02:00
Dev
b41599d95a
docs(01-06): complete WPF shell plan — SUMMARY, STATE, ROADMAP updated
...
- 2 tasks completed, 12 files modified
- 6 FeatureViewModelBase unit tests added and passing
- Full WPF shell with FeatureTabBase, MainWindowViewModel, LogPanelSink wiring
2026-04-02 12:34:58 +02:00
Dev
5920d42614
feat(01-06): build WPF shell — MainWindow XAML, ViewModels, LogPanelSink wiring
...
- Add FeatureTabBase UserControl with ProgressBar/TextBlock/CancelButton strip
(Visibility bound to IsRunning, shown only during operations)
- Add MainWindowViewModel with TenantProfiles ObservableCollection, ConnectCommand,
ClearSessionCommand, ManageProfilesCommand, ProgressUpdatedMessage subscription
- Add ProfileManagementViewModel wrapping ProfileService CRUD with input validation
- Add SettingsViewModel (extends FeatureViewModelBase) with language/folder settings
- Update MainWindow.xaml: DockPanel shell with Toolbar, TabControl (8 tabs), 150px
RichTextBox LogPanel, StatusBar (tenant name | ProgressStatus | ProgressPercentage)
- MainWindow.xaml.cs: DI constructor, DataContext=viewModel, LoadProfilesAsync on Loaded
- App.xaml.cs: register all services, wire LogPanelSink after MainWindow resolved,
register DispatcherUnhandledException and UnobservedTaskException global handlers
- App.xaml: add BoolToVisibilityConverter resource
2026-04-02 12:32:41 +02:00
Dev
3c09155648
feat(01-06): implement FeatureViewModelBase with async/cancel/progress pattern
...
- Add ProgressUpdatedMessage ValueChangedMessage for StatusBar live updates
- Add FeatureViewModelBase with CancellationTokenSource lifecycle, IsRunning,
IProgress<OperationProgress>, OperationCanceledException handling
- Add 6 unit tests covering lifecycle, progress, cancellation, error handling
and CanExecute guard
2026-04-02 12:29:38 +02:00
Dev
fcae8f0e49
docs(01-04): complete auth layer plan
...
- 01-04-SUMMARY.md: MsalClientFactory + SessionManager auth layer
- STATE.md: progress updated to 63%, decisions added, session recorded
- ROADMAP.md: phase 1 progress updated (5/8 summaries)
- REQUIREMENTS.md: FOUND-03 and FOUND-04 marked complete
2026-04-02 12:26:55 +02:00
Dev
158aab96b2
feat(01-04): SessionManager singleton holding all ClientContext instances
...
- SessionManager owns all ClientContexts; callers must not store references
- IsAuthenticated(tenantUrl) returns false before auth, true after GetOrCreateContextAsync
- ClearSessionAsync disposes ClientContext and removes state (idempotent for unknown tenants)
- GetOrCreateContextAsync validates null/empty TenantUrl and ClientId (ArgumentException)
- MsalClientFactory.GetCacheHelper() added — exposes helper for PnP tokenCacheCallback wiring
- 8 unit tests pass, 1 interactive-login test skipped (integration-only)
2026-04-02 12:25:01 +02:00
Dev
02955199f6
feat(01-04): MsalClientFactory with per-clientId PCA and MsalCacheHelper
...
- Creates one IPublicClientApplication per ClientId (never shared)
- Persists token cache to configurable directory (default: %AppData%\SharepointToolbox\auth\msal_{clientId}.cache)
- SemaphoreSlim(1,1) prevents duplicate creation under concurrent calls
- CacheDirectory property exposed for test injection
- 4 unit tests: same-instance, different-instance, concurrent, AppData path
2026-04-02 12:22:54 +02:00
Dev
466bef3e87
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
2026-04-02 12:20:08 +02:00
Dev
1c532d1f6b
feat(01-05): add Serilog integration tests and App.xaml.cs LogPanelSink comment
...
- LoggingIntegrationTests: verifies Serilog writes rolling log file with correct content
- LogPanelSink structural smoke test: confirms type implements ILogEventSink
- App.xaml.cs: added comment for LogPanelSink DI registration deferred to plan 01-06
2026-04-02 12:18:02 +02:00
Dev
a287ed83ab
feat(01-05): implement TranslationSource singleton + EN/FR resx files
...
- TranslationSource singleton with INotifyPropertyChanged indexer binding
- PropertyChanged fires with string.Empty on culture switch (signals all bindings refresh)
- Missing key returns [key] placeholder (prevents null in WPF bindings)
- Strings.resx with 27 Phase 1 UI string keys (EN)
- Strings.fr.resx with same 27 keys stubbed with EN text (FR completeness Phase 5)
- Strings.Designer.cs ResourceManager for dotnet build compatibility
- SharepointToolbox.csproj updated with EmbeddedResource metadata
2026-04-02 12:16:57 +02:00
Dev
8a58140f9b
test(01-05): add failing tests for TranslationSource singleton
...
- Instance singleton test
- EN string lookup test
- FR culture fallback test
- Missing key returns bracketed key
- PropertyChanged fires with empty string on culture switch
- Same culture does not fire PropertyChanged
2026-04-02 12:14:49 +02:00
Dev
dd2f179c2d
docs(01-03): complete persistence layer plan — ProfileService + SettingsService
...
- SUMMARY.md: 7 files, 18 tests, write-then-replace pattern documented
- STATE.md: plan 03 complete, progress 38%, decisions recorded
- ROADMAP.md: phase 1 progress updated (3/8 plans done)
- REQUIREMENTS.md: FOUND-02, FOUND-10, FOUND-12 marked complete
2026-04-02 12:13:35 +02:00
Dev
ac3fa5c8eb
feat(01-03): SettingsRepository and SettingsService with write-then-replace
...
- AppSettings model: DataFolder + Lang with camelCase JSON serialization
- SettingsRepository: SemaphoreSlim write lock + write-then-replace (tmp→validate→move)
- SettingsService: GetSettings/SetLanguage/SetDataFolder; SetLanguage validates en/fr only
- All 8 SettingsServiceTests pass; all 18 Unit tests pass
2026-04-02 12:12:02 +02:00