docs(18-01): complete auto-take-ownership settings foundation plan

- 18-01-SUMMARY.md: plan execution summary
- STATE.md: progress updated to 98%, decisions recorded, stopped-at updated
- ROADMAP.md: phase 18 marked in-progress (1/2 summaries)
- REQUIREMENTS.md: OWN-01 marked complete
This commit is contained in:
Dev
2026-04-09 14:25:47 +02:00
parent 20948e4bac
commit 11e835f586
4 changed files with 96 additions and 10 deletions

View File

@@ -18,7 +18,7 @@ Requirements for v2.3 Tenant Management & Report Enhancements. Each maps to road
### Site Ownership ### Site Ownership
- [ ] **OWN-01**: User can enable/disable auto-take-ownership in application settings (global toggle, OFF by default) - [x] **OWN-01**: User can enable/disable auto-take-ownership in application settings (global toggle, OFF by default)
- [ ] **OWN-02**: App automatically takes site collection admin ownership when encountering access denied during scans (when toggle is ON) - [ ] **OWN-02**: App automatically takes site collection admin ownership when encountering access denied during scans (when toggle is ON)
### Report Enhancements ### Report Enhancements
@@ -54,7 +54,7 @@ Requirements for v2.3 Tenant Management & Report Enhancements. Each maps to road
| APPREG-04 | Phase 19 | Pending | | APPREG-04 | Phase 19 | Pending |
| APPREG-05 | Phase 19 | Pending | | APPREG-05 | Phase 19 | Pending |
| APPREG-06 | Phase 19 | Pending | | APPREG-06 | Phase 19 | Pending |
| OWN-01 | Phase 18 | Pending | | OWN-01 | Phase 18 | Complete |
| OWN-02 | Phase 18 | Pending | | OWN-02 | Phase 18 | Pending |
| RPT-01 | Phase 17 | Complete | | RPT-01 | Phase 17 | Complete |
| RPT-02 | Phase 17 | Complete | | RPT-02 | Phase 17 | Complete |

View File

@@ -102,7 +102,7 @@ Plans:
2. When the toggle is OFF, access-denied sites produce the same error behavior as before v2.3 (no regression) 2. When the toggle is OFF, access-denied sites produce the same error behavior as before v2.3 (no regression)
3. When the toggle is ON and a scan hits access denied on a site, the app automatically calls `Tenant.SetSiteAdmin` to elevate ownership and retries the site without interrupting the scan 3. When the toggle is ON and a scan hits access denied on a site, the app automatically calls `Tenant.SetSiteAdmin` to elevate ownership and retries the site without interrupting the scan
4. The scan result for an auto-elevated site is visually distinguishable from a normally-scanned site (e.g., a flag or icon in the results) 4. The scan result for an auto-elevated site is visually distinguishable from a normally-scanned site (e.g., a flag or icon in the results)
**Plans:** 2 plans **Plans:** 1/2 plans executed
Plans: Plans:
- [ ] 18-01-PLAN.md — Settings toggle + OwnershipElevationService + PermissionEntry.WasAutoElevated flag - [ ] 18-01-PLAN.md — Settings toggle + OwnershipElevationService + PermissionEntry.WasAutoElevated flag
- [ ] 18-02-PLAN.md — Scan-loop elevation logic + DataGrid visual differentiation - [ ] 18-02-PLAN.md — Scan-loop elevation logic + DataGrid visual differentiation
@@ -129,5 +129,5 @@ Plans:
| 15. Consolidation Data Model | v2.3 | 2/2 | Complete | 2026-04-09 | | 15. Consolidation Data Model | v2.3 | 2/2 | Complete | 2026-04-09 |
| 16. Report Consolidation Toggle | v2.3 | 2/2 | Complete | 2026-04-09 | | 16. Report Consolidation Toggle | v2.3 | 2/2 | Complete | 2026-04-09 |
| 17. Group Expansion in HTML Reports | 2/2 | Complete | 2026-04-09 | — | | 17. Group Expansion in HTML Reports | 2/2 | Complete | 2026-04-09 | — |
| 18. Auto-Take Ownership | v2.3 | 0/2 | Planned | — | | 18. Auto-Take Ownership | 1/2 | In Progress| | — |
| 19. App Registration & Removal | v2.3 | 0/? | Not started | — | | 19. App Registration & Removal | v2.3 | 0/? | Not started | — |

View File

@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v2.3 milestone: v2.3
milestone_name: Tenant Management & Report Enhancements milestone_name: Tenant Management & Report Enhancements
status: planning status: planning
stopped_at: Completed 17-02-PLAN.md stopped_at: Completed 18-01-PLAN.md
last_updated: "2026-04-09T11:13:35.417Z" last_updated: "2026-04-09T12:25:36.302Z"
last_activity: 2026-04-09 — Roadmap created for v2.3 (phases 15-19) last_activity: 2026-04-09 — Roadmap created for v2.3 (phases 15-19)
progress: progress:
total_phases: 5 total_phases: 5
completed_phases: 3 completed_phases: 3
total_plans: 6 total_plans: 8
completed_plans: 6 completed_plans: 7
--- ---
# Project State # Project State
@@ -71,6 +71,9 @@ Decisions are logged in PROJECT.md Key Decisions table.
- [Phase 17]: Static helpers IsAadGroup/ExtractAadGroupId/StripClaims declared internal to enable unit testing via InternalsVisibleTo without polluting public API - [Phase 17]: Static helpers IsAadGroup/ExtractAadGroupId/StripClaims declared internal to enable unit testing via InternalsVisibleTo without polluting public API
- [Phase 17]: Graph client created lazily on first AAD group encountered to avoid unnecessary auth overhead for groups with no nested AAD members - [Phase 17]: Graph client created lazily on first AAD group encountered to avoid unnecessary auth overhead for groups with no nested AAD members
- [Phase 17]: groupMembers optional param in HtmlExportService — null produces identical pre-Phase-17 output; ISharePointGroupResolver injected as optional last param in PermissionsViewModel; resolution failure degrades gracefully with LogWarning - [Phase 17]: groupMembers optional param in HtmlExportService — null produces identical pre-Phase-17 output; ISharePointGroupResolver injected as optional last param in PermissionsViewModel; resolution failure degrades gracefully with LogWarning
- [Phase 18-auto-take-ownership]: OwnershipElevationService uses Tenant.SetSiteAdmin from PnP.Framework
- [Phase 18-auto-take-ownership]: WasAutoElevated last positional param with default=false preserves all existing PermissionEntry callsites
- [Phase 18-auto-take-ownership]: AutoTakeOwnership ViewModel setter uses fire-and-forget pattern matching DataFolder
### Pending Todos ### Pending Todos
@@ -82,7 +85,7 @@ None.
## Session Continuity ## Session Continuity
Last session: 2026-04-09T11:11:03.823Z Last session: 2026-04-09T12:25:29.455Z
Stopped at: Completed 17-02-PLAN.md Stopped at: Completed 18-01-PLAN.md
Resume file: None Resume file: None
Next step: `/gsd:plan-phase 15` Next step: `/gsd:plan-phase 15`

View File

@@ -0,0 +1,83 @@
---
phase: 18-auto-take-ownership
plan: "01"
subsystem: settings, models, services
tags: [auto-take-ownership, settings, permission-entry, elevation-service, di]
dependency_graph:
requires: []
provides: [AppSettings.AutoTakeOwnership, PermissionEntry.WasAutoElevated, IOwnershipElevationService, OwnershipElevationService, SettingsViewModel.AutoTakeOwnership]
affects: [SharepointToolbox/Core/Models/AppSettings.cs, SharepointToolbox/Core/Models/PermissionEntry.cs, SharepointToolbox/Services/SettingsService.cs, SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs, SharepointToolbox/Views/Tabs/SettingsView.xaml]
tech_stack:
added: [IOwnershipElevationService, OwnershipElevationService, Microsoft.Online.SharePoint.TenantAdministration.Tenant.SetSiteAdmin]
patterns: [fire-and-forget property setter pattern (matching DataFolder), DI transient registration]
key_files:
created:
- SharepointToolbox/Services/IOwnershipElevationService.cs
- SharepointToolbox/Services/OwnershipElevationService.cs
- SharepointToolbox.Tests/Services/OwnershipElevationServiceTests.cs
- SharepointToolbox.Tests/ViewModels/SettingsViewModelOwnershipTests.cs
modified:
- SharepointToolbox/Core/Models/AppSettings.cs
- SharepointToolbox/Core/Models/PermissionEntry.cs
- SharepointToolbox/Services/SettingsService.cs
- SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs
- SharepointToolbox/Views/Tabs/SettingsView.xaml
- SharepointToolbox/Localization/Strings.resx
- SharepointToolbox/Localization/Strings.fr.resx
- SharepointToolbox/App.xaml.cs
decisions:
- "OwnershipElevationService.ElevateAsync uses Tenant.SetSiteAdmin from PnP.Framework (Microsoft.Online.SharePoint.TenantAdministration)"
- "WasAutoElevated placed last with default=false in PermissionEntry positional record to avoid breaking all existing callsites"
- "AutoTakeOwnership in SettingsViewModel follows fire-and-forget pattern matching DataFolder setter"
metrics:
duration: "~15 minutes"
tasks_completed: 2
files_modified: 8
files_created: 4
completed_date: "2026-04-09"
---
# Phase 18 Plan 01: Auto-Take Ownership Settings Foundation Summary
**One-liner:** AppSettings, PermissionEntry, IOwnershipElevationService/impl, and SettingsView checkbox for auto-take-ownership toggle backed by full EN/FR localization and 10 new tests.
## Tasks Completed
| Task | Name | Commit | Files |
|------|------|--------|-------|
| 1 | Models + SettingsService + OwnershipElevationService + tests | 36fb312 | AppSettings.cs, PermissionEntry.cs, SettingsService.cs, IOwnershipElevationService.cs, OwnershipElevationService.cs, SettingsViewModel.cs, App.xaml.cs, 2 test files |
| 2 | SettingsView XAML + localization | 20948e4 | SettingsView.xaml, Strings.resx, Strings.fr.resx |
## What Was Built
- `AppSettings.AutoTakeOwnership` bool property defaulting to `false`, round-trips through JSON.
- `PermissionEntry.WasAutoElevated` optional positional parameter (last, default `false`) — zero callsite breakage.
- `SettingsService.SetAutoTakeOwnershipAsync(bool)` persists toggle following same pattern as `SetLanguageAsync`/`SetDataFolderAsync`.
- `IOwnershipElevationService` interface with `ElevateAsync(ClientContext, siteUrl, loginName, ct)`.
- `OwnershipElevationService` wraps `Tenant.SetSiteAdmin` from PnP.Framework.
- DI registration: `services.AddTransient<IOwnershipElevationService, OwnershipElevationService>()` in App.xaml.cs.
- `SettingsViewModel.AutoTakeOwnership` property loads from settings on `LoadAsync()`, persists on set via fire-and-forget `SetAutoTakeOwnershipAsync`.
- `SettingsView.xaml` "Site Ownership" section with `CheckBox` bound to `AutoTakeOwnership`, with description `TextBlock`.
- EN/FR localization keys: `settings.ownership.title`, `settings.ownership.auto`, `settings.ownership.description`.
- 10 new tests covering all behaviors; full suite: 328 passed, 28 skipped, 0 failed.
## Decisions Made
1. `OwnershipElevationService.ElevateAsync` uses `Tenant.SetSiteAdmin` (already available via PnP.Framework `Microsoft.Online.SharePoint.TenantAdministration`).
2. `WasAutoElevated` placed last with `= false` default in the positional record — no existing callsite needed updating.
3. `AutoTakeOwnership` ViewModel setter uses `_ = _settingsService.SetAutoTakeOwnershipAsync(value)` matching the `DataFolder` fire-and-forget pattern.
## Deviations from Plan
None - plan executed exactly as written.
## Test Results
- `dotnet build SharepointToolbox.slnx` — 0 errors, 0 warnings
- `dotnet test ... --filter OwnershipElevation|SettingsViewModelOwnership` — 8/8 passed
- `dotnet test ... --filter LocaleCompleteness` — 2/2 passed
- Full suite — 328 passed, 0 failed, 28 skipped
## Self-Check: PASSED
All created files exist. All commits verified. Full test suite green.