docs(19-02): complete register/remove app UI plan
- 19-02-SUMMARY.md created - STATE.md: progress 100%, decisions, session updated - ROADMAP.md: phase 19 marked complete - REQUIREMENTS.md: APPREG-01, APPREG-04, APPREG-05 marked complete
This commit is contained in:
@@ -9,11 +9,11 @@ Requirements for v2.3 Tenant Management & Report Enhancements. Each maps to road
|
|||||||
|
|
||||||
### App Registration
|
### App Registration
|
||||||
|
|
||||||
- [ ] **APPREG-01**: User can register the app on a target tenant from the profile create/edit dialog
|
- [x] **APPREG-01**: User can register the app on a target tenant from the profile create/edit dialog
|
||||||
- [x] **APPREG-02**: App auto-detects if user has Global Admin permissions before attempting registration
|
- [x] **APPREG-02**: App auto-detects if user has Global Admin permissions before attempting registration
|
||||||
- [x] **APPREG-03**: App creates Azure AD application + service principal + grants required permissions atomically (with rollback on failure)
|
- [x] **APPREG-03**: App creates Azure AD application + service principal + grants required permissions atomically (with rollback on failure)
|
||||||
- [ ] **APPREG-04**: User sees guided fallback instructions when auto-registration is not possible (insufficient permissions)
|
- [x] **APPREG-04**: User sees guided fallback instructions when auto-registration is not possible (insufficient permissions)
|
||||||
- [ ] **APPREG-05**: User can remove the app registration from a target tenant
|
- [x] **APPREG-05**: User can remove the app registration from a target tenant
|
||||||
- [x] **APPREG-06**: App clears cached tokens and sessions when app registration is removed
|
- [x] **APPREG-06**: App clears cached tokens and sessions when app registration is removed
|
||||||
|
|
||||||
### Site Ownership
|
### Site Ownership
|
||||||
@@ -48,11 +48,11 @@ Requirements for v2.3 Tenant Management & Report Enhancements. Each maps to road
|
|||||||
|
|
||||||
| Requirement | Phase | Status |
|
| Requirement | Phase | Status |
|
||||||
|-------------|-------|--------|
|
|-------------|-------|--------|
|
||||||
| APPREG-01 | Phase 19 | Pending |
|
| APPREG-01 | Phase 19 | Complete |
|
||||||
| APPREG-02 | Phase 19 | Complete |
|
| APPREG-02 | Phase 19 | Complete |
|
||||||
| APPREG-03 | Phase 19 | Complete |
|
| APPREG-03 | Phase 19 | Complete |
|
||||||
| APPREG-04 | Phase 19 | Pending |
|
| APPREG-04 | Phase 19 | Complete |
|
||||||
| APPREG-05 | Phase 19 | Pending |
|
| APPREG-05 | Phase 19 | Complete |
|
||||||
| APPREG-06 | Phase 19 | Complete |
|
| APPREG-06 | Phase 19 | Complete |
|
||||||
| OWN-01 | Phase 18 | Complete |
|
| OWN-01 | Phase 18 | Complete |
|
||||||
| OWN-02 | Phase 18 | Complete |
|
| OWN-02 | Phase 18 | Complete |
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
- [x] **Phase 16: Report Consolidation Toggle** (2 plans) — Export settings toggle wired to PermissionConsolidator; first user-visible consolidation behavior (completed 2026-04-09)
|
- [x] **Phase 16: Report Consolidation Toggle** (2 plans) — Export settings toggle wired to PermissionConsolidator; first user-visible consolidation behavior (completed 2026-04-09)
|
||||||
- [x] **Phase 17: Group Expansion in HTML Reports** (2 plans) — Clickable group expansion in HTML exports with transitive membership resolution (completed 2026-04-09)
|
- [x] **Phase 17: Group Expansion in HTML Reports** (2 plans) — Clickable group expansion in HTML exports with transitive membership resolution (completed 2026-04-09)
|
||||||
- [x] **Phase 18: Auto-Take Ownership** (2 plans) — Global toggle and automatic site collection admin elevation on access denied (completed 2026-04-09)
|
- [x] **Phase 18: Auto-Take Ownership** (2 plans) — Global toggle and automatic site collection admin elevation on access denied (completed 2026-04-09)
|
||||||
- [ ] **Phase 19: App Registration & Removal** (2 plans) — Automated Entra app registration with guided fallback and clean removal
|
- [x] **Phase 19: App Registration & Removal** (2 plans) — Automated Entra app registration with guided fallback and clean removal (completed 2026-04-09)
|
||||||
|
|
||||||
## Phase Details
|
## Phase Details
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ Plans:
|
|||||||
3. Registration creates the Azure AD application, service principal, and grants all required API permissions in a single atomic operation — if any step fails, all partial changes are rolled back and the user sees a specific error explaining what failed and why
|
3. Registration creates the Azure AD application, service principal, and grants all required API permissions in a single atomic operation — if any step fails, all partial changes are rolled back and the user sees a specific error explaining what failed and why
|
||||||
4. A "Remove App" action in the profile dialog removes the Azure AD application registration from the target tenant
|
4. A "Remove App" action in the profile dialog removes the Azure AD application registration from the target tenant
|
||||||
5. After removal, all cached MSAL tokens and session state for that tenant are cleared, and subsequent operations require re-authentication
|
5. After removal, all cached MSAL tokens and session state for that tenant are cleared, and subsequent operations require re-authentication
|
||||||
**Plans:** 1/2 plans executed
|
**Plans:** 2/2 plans complete
|
||||||
Plans:
|
Plans:
|
||||||
- [ ] 19-01-PLAN.md — IAppRegistrationService + AppRegistrationResult model + TenantProfile.AppId + service implementation + unit tests
|
- [ ] 19-01-PLAN.md — IAppRegistrationService + AppRegistrationResult model + TenantProfile.AppId + service implementation + unit tests
|
||||||
- [ ] 19-02-PLAN.md — ViewModel RegisterApp/RemoveApp commands + XAML dialog UI + fallback panel + localization + VM tests
|
- [ ] 19-02-PLAN.md — ViewModel RegisterApp/RemoveApp commands + XAML dialog UI + fallback panel + localization + VM tests
|
||||||
@@ -133,4 +133,4 @@ Plans:
|
|||||||
| 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 | 2/2 | Complete | 2026-04-09 | — |
|
| 18. Auto-Take Ownership | 2/2 | Complete | 2026-04-09 | — |
|
||||||
| 19. App Registration & Removal | 1/2 | In Progress| | — |
|
| 19. App Registration & Removal | 2/2 | Complete | 2026-04-09 | — |
|
||||||
|
|||||||
@@ -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 19-01-PLAN.md
|
stopped_at: Completed 19-02-PLAN.md
|
||||||
last_updated: "2026-04-09T13:15:04.040Z"
|
last_updated: "2026-04-09T13:20:41.127Z"
|
||||||
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: 4
|
completed_phases: 5
|
||||||
total_plans: 10
|
total_plans: 10
|
||||||
completed_plans: 9
|
completed_plans: 10
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -79,6 +79,9 @@ Decisions are logged in PROJECT.md Key Decisions table.
|
|||||||
- [Phase 19-app-registration-removal]: AppRegistrationService uses AppGraphClientFactory alias to disambiguate from Microsoft.Graph.GraphClientFactory
|
- [Phase 19-app-registration-removal]: AppRegistrationService uses AppGraphClientFactory alias to disambiguate from Microsoft.Graph.GraphClientFactory
|
||||||
- [Phase 19-app-registration-removal]: BuildRequiredResourceAccess declared internal to enable direct unit testing without live Graph calls
|
- [Phase 19-app-registration-removal]: BuildRequiredResourceAccess declared internal to enable direct unit testing without live Graph calls
|
||||||
- [Phase 19-app-registration-removal]: SharePoint AllSites.FullControl GUID marked LOW confidence — must be verified against live tenant
|
- [Phase 19-app-registration-removal]: SharePoint AllSites.FullControl GUID marked LOW confidence — must be verified against live tenant
|
||||||
|
- [Phase 19-app-registration-removal]: ProfileManagementViewModel constructor gains IAppRegistrationService as last param — existing logo tests updated to 5-param
|
||||||
|
- [Phase 19-app-registration-removal]: TranslationSource.Instance used directly in ViewModel for status strings (consistent with runtime locale switching)
|
||||||
|
- [Phase 19-app-registration-removal]: BooleanToVisibilityConverter declared in Window.Resources (WPF built-in, no custom converter needed)
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -90,7 +93,7 @@ None.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-09T13:15:04.038Z
|
Last session: 2026-04-09T13:20:36.865Z
|
||||||
Stopped at: Completed 19-01-PLAN.md
|
Stopped at: Completed 19-02-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
Next step: `/gsd:plan-phase 15`
|
Next step: `/gsd:plan-phase 15`
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
phase: 19-app-registration-removal
|
||||||
|
plan: "02"
|
||||||
|
subsystem: ViewModels/UI
|
||||||
|
tags: [app-registration, viewmodel, xaml, localization, unit-tests]
|
||||||
|
dependency_graph:
|
||||||
|
requires: [19-01]
|
||||||
|
provides: [register-app-ui, remove-app-ui, fallback-instructions-panel]
|
||||||
|
affects: [ProfileManagementViewModel, ProfileManagementDialog, App.xaml.cs]
|
||||||
|
tech_stack:
|
||||||
|
added: []
|
||||||
|
patterns: [IAsyncRelayCommand, ObservableProperty, BooleanToVisibilityConverter, TranslationSource]
|
||||||
|
key_files:
|
||||||
|
created:
|
||||||
|
- SharepointToolbox.Tests/ViewModels/ProfileManagementViewModelRegistrationTests.cs
|
||||||
|
modified:
|
||||||
|
- SharepointToolbox/ViewModels/ProfileManagementViewModel.cs
|
||||||
|
- SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml
|
||||||
|
- SharepointToolbox/Localization/Strings.resx
|
||||||
|
- SharepointToolbox/Localization/Strings.fr.resx
|
||||||
|
- SharepointToolbox/App.xaml.cs
|
||||||
|
- SharepointToolbox.Tests/ViewModels/ProfileManagementViewModelLogoTests.cs
|
||||||
|
decisions:
|
||||||
|
- ProfileManagementViewModel constructor gains IAppRegistrationService as last param — existing logo tests updated to 5-param
|
||||||
|
- RegisterAppAsync/RemoveAppAsync use CancellationToken from IAsyncRelayCommand overload
|
||||||
|
- TranslationSource.Instance used directly in ViewModel for status strings (consistent with runtime locale switching)
|
||||||
|
- BooleanToVisibilityConverter declared in Window.Resources (WPF built-in, no custom converter needed)
|
||||||
|
metrics:
|
||||||
|
duration: ~5 minutes
|
||||||
|
completed_date: "2026-04-09"
|
||||||
|
tasks_completed: 2
|
||||||
|
files_modified: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 19 Plan 02: Register/Remove App UI Summary
|
||||||
|
|
||||||
|
Register and Remove app commands wired into ProfileManagementViewModel with fallback instructions panel, DI registration, EN/FR localization, and 7 passing unit tests.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
|
||||||
|
| # | Task | Commit | Status |
|
||||||
|
|---|------|--------|--------|
|
||||||
|
| 1 | ViewModel commands + DI + Localization | 42b5eda | Done |
|
||||||
|
| 2 | Profile dialog XAML + ViewModel tests | 809ac86 | Done |
|
||||||
|
|
||||||
|
## What Was Built
|
||||||
|
|
||||||
|
**ProfileManagementViewModel** gained:
|
||||||
|
- `IAppRegistrationService` constructor injection
|
||||||
|
- `RegisterAppCommand` / `RemoveAppCommand` (IAsyncRelayCommand)
|
||||||
|
- `IsRegistering`, `ShowFallbackInstructions`, `RegistrationStatus` observable properties
|
||||||
|
- `HasRegisteredApp` computed property
|
||||||
|
- `CanRegisterApp` / `CanRemoveApp` guards (profile selected, AppId null/non-null, not busy)
|
||||||
|
- `RegisterAppAsync`: admin check → fallback panel or full registration → AppId persistence
|
||||||
|
- `RemoveAppAsync`: app removal + MSAL clear + AppId null + persistence
|
||||||
|
- `OnIsRegisteringChanged` partial: notifies both commands on busy state change
|
||||||
|
|
||||||
|
**ProfileManagementDialog.xaml**:
|
||||||
|
- Height 750 (was 620)
|
||||||
|
- New Row 4: Register/Remove buttons, RegistrationStatus TextBlock, fallback instructions Border (6 steps)
|
||||||
|
- `BooleanToVisibilityConverter` added to `Window.Resources`
|
||||||
|
- Buttons row shifted from Row 4 to Row 5
|
||||||
|
|
||||||
|
**Localization**: 16 new keys in both Strings.resx and Strings.fr.resx (register/remove/fallback flow, all accented FR characters).
|
||||||
|
|
||||||
|
**App.xaml.cs**: `IAppRegistrationService` registered as singleton.
|
||||||
|
|
||||||
|
**Tests**: 7 unit tests, all passing — CanExecute guards, fallback on non-admin, AppId set on success, AppId cleared on remove.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 2 - Missing critical update] Updated ProfileManagementViewModelLogoTests to 5-param constructor**
|
||||||
|
- **Found during:** Task 2
|
||||||
|
- **Issue:** Existing logo tests used the 4-param constructor which no longer exists after adding IAppRegistrationService
|
||||||
|
- **Fix:** Added `Mock<IAppRegistrationService>` field and passed `_mockAppReg.Object` as 5th param in all 3 constructor calls
|
||||||
|
- **Files modified:** SharepointToolbox.Tests/ViewModels/ProfileManagementViewModelLogoTests.cs
|
||||||
|
- **Commit:** 809ac86
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
All key files found. Both task commits verified (42b5eda, 809ac86). Full solution builds clean. 7/7 tests pass.
|
||||||
Reference in New Issue
Block a user