From 11e835f5865241192572c90cc0ad5ec4e4030163 Mon Sep 17 00:00:00 2001 From: Dev Date: Thu, 9 Apr 2026 14:25:47 +0200 Subject: [PATCH] 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 --- .planning/REQUIREMENTS.md | 4 +- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 15 ++-- .../18-auto-take-ownership/18-01-SUMMARY.md | 83 +++++++++++++++++++ 4 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 .planning/phases/18-auto-take-ownership/18-01-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index f14e461..82d9255 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -18,7 +18,7 @@ Requirements for v2.3 Tenant Management & Report Enhancements. Each maps to road ### 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) ### Report Enhancements @@ -54,7 +54,7 @@ Requirements for v2.3 Tenant Management & Report Enhancements. Each maps to road | APPREG-04 | Phase 19 | Pending | | APPREG-05 | Phase 19 | Pending | | APPREG-06 | Phase 19 | Pending | -| OWN-01 | Phase 18 | Pending | +| OWN-01 | Phase 18 | Complete | | OWN-02 | Phase 18 | Pending | | RPT-01 | Phase 17 | Complete | | RPT-02 | Phase 17 | Complete | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 768263c..257cad1 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -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) 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) -**Plans:** 2 plans +**Plans:** 1/2 plans executed Plans: - [ ] 18-01-PLAN.md — Settings toggle + OwnershipElevationService + PermissionEntry.WasAutoElevated flag - [ ] 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 | | 16. Report Consolidation Toggle | v2.3 | 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 | — | diff --git a/.planning/STATE.md b/.planning/STATE.md index 0739a5c..a362b67 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v2.3 milestone_name: Tenant Management & Report Enhancements status: planning -stopped_at: Completed 17-02-PLAN.md -last_updated: "2026-04-09T11:13:35.417Z" +stopped_at: Completed 18-01-PLAN.md +last_updated: "2026-04-09T12:25:36.302Z" last_activity: 2026-04-09 — Roadmap created for v2.3 (phases 15-19) progress: total_phases: 5 completed_phases: 3 - total_plans: 6 - completed_plans: 6 + total_plans: 8 + completed_plans: 7 --- # 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]: 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 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 @@ -82,7 +85,7 @@ None. ## Session Continuity -Last session: 2026-04-09T11:11:03.823Z -Stopped at: Completed 17-02-PLAN.md +Last session: 2026-04-09T12:25:29.455Z +Stopped at: Completed 18-01-PLAN.md Resume file: None Next step: `/gsd:plan-phase 15` diff --git a/.planning/phases/18-auto-take-ownership/18-01-SUMMARY.md b/.planning/phases/18-auto-take-ownership/18-01-SUMMARY.md new file mode 100644 index 0000000..a9f2d6c --- /dev/null +++ b/.planning/phases/18-auto-take-ownership/18-01-SUMMARY.md @@ -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()` 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.