- 19-01-SUMMARY.md: service layer implementation with rollback pattern - STATE.md: progress 98%, decisions added, session updated - ROADMAP.md: phase 19 in-progress (1/2 plans) - REQUIREMENTS.md: APPREG-02, APPREG-03, APPREG-06 marked complete
5.6 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | |||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 19-app-registration-removal | 01 | Services / Models |
|
|
|
|
|
|
Phase 19 Plan 01: AppRegistrationService — Models, Interface, Implementation, and Tests Summary
One-liner: AppRegistrationService with atomic Graph API registration/rollback using transitiveMemberOf admin check, MSAL eviction, and AppRegistrationResult discriminated result type.
Tasks Completed
| # | Name | Commit | Key Files |
|---|---|---|---|
| 1 | Models + Interface + Service implementation | 93dbb8c |
AppRegistrationResult.cs, TenantProfile.cs, IAppRegistrationService.cs, AppRegistrationService.cs |
| 2 | Unit tests for AppRegistrationService | 8083cdf |
AppRegistrationServiceTests.cs |
What Was Built
AppRegistrationResult (Core/Models)
Discriminated result type with three static factory methods:
Success(appId)— IsSuccess=true, carries appIdFailure(message)— IsSuccess=false, carries error messageFallbackRequired()— IsFallback=true, neither success nor error
TenantProfile (Core/Models)
Added nullable AppId property. Defaults to null; stored to JSON via System.Text.Json when ProfileService persists profiles.
IAppRegistrationService (Services)
Four-method interface:
IsGlobalAdminAsync— transitiveMemberOf check, returns false on any exceptionRegisterAsync— sequential 4-step registration with rollback on failureRemoveAsync— deletes by appId, swallows exceptions (logs warning)ClearMsalSessionAsync— SessionManager + MSAL account eviction + cache unregister
AppRegistrationService (Services)
Full implementation using GraphClientFactory (identical alias pattern to GraphUserDirectoryService). Registration flow:
- Create Application object with RequiredResourceAccess (Graph + SharePoint scopes)
- Create ServicePrincipal with AppId
- Look up Microsoft Graph resource SP by filter
- Look up SharePoint Online resource SP by filter
- Post OAuth2PermissionGrant for Graph delegated scopes
- Post OAuth2PermissionGrant for SharePoint delegated scopes
- Rollback (best-effort DELETE) if any step fails
Unit Tests (12 passing)
- AppRegistrationResult: 3 factory method tests
- TenantProfile.AppId: null default + JSON round-trip (null and non-null)
- Service constructor/interface check
- BuildRequiredResourceAccess: 2 resources, 4 Graph scopes, 1 SharePoint scope, all Type="Scope"
Deviations from Plan
Auto-fixed Issues
1. [Rule 3 - Blocking] GraphClientFactory namespace ambiguity
- Found during: Task 1 build
- Issue:
GraphClientFactoryis ambiguous betweenSharepointToolbox.Infrastructure.Auth.GraphClientFactoryandMicrosoft.Graph.GraphClientFactory - Fix: Applied
AppGraphClientFactoryalias (same pattern used in GraphUserDirectoryService) - Files modified: AppRegistrationService.cs
- Commit:
93dbb8c
2. [Rule 3 - Blocking] Graph SDK v5 PostAsync CancellationToken position
- Found during: Task 1 build
- Issue:
PostAsync(body, ct)fails — Kiota-based SDK expects(body, requestConfig?, cancellationToken)soctwas matched torequestConfigparameter - Fix: Used named parameter
cancellationToken: cton all PostAsync calls - Files modified: AppRegistrationService.cs
- Commit:
93dbb8c
3. [Rule 3 - Blocking] Using alias placement in test file
- Found during: Task 2 compile
- Issue: Placed
usingaliases at bottom of file — C# requires allusingdeclarations before namespace body - Fix: Moved aliases to top of file with other using directives
- Files modified: AppRegistrationServiceTests.cs
- Commit:
8083cdf
Self-Check: PASSED
Files exist:
- SharepointToolbox/Core/Models/AppRegistrationResult.cs — FOUND
- SharepointToolbox/Core/Models/TenantProfile.cs — FOUND (modified)
- SharepointToolbox/Services/IAppRegistrationService.cs — FOUND
- SharepointToolbox/Services/AppRegistrationService.cs — FOUND
- SharepointToolbox.Tests/Services/AppRegistrationServiceTests.cs — FOUND
Commits verified:
93dbb8c— feat(19-01): add AppRegistrationService with rollback, model, and interface8083cdf— test(19-01): add unit tests for AppRegistrationService and models
Tests: 12 passed, 0 failed Build: 0 errors, 0 warnings