Files
Sharepoint-Toolbox/.planning/milestones/v1.0-phases/04-bulk-operations-and-provisioning/04-04-SUMMARY.md
Dev 655bb79a99
All checks were successful
Release zip package / release (push) Successful in 10s
chore: complete v1.0 milestone
Archive 5 phases (36 plans) to milestones/v1.0-phases/.
Archive roadmap, requirements, and audit to milestones/.
Evolve PROJECT.md with shipped state and validated requirements.
Collapse ROADMAP.md to one-line milestone summary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 09:15:14 +02:00

8.1 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
04-bulk-operations-and-provisioning 04 bulk-operations
microsoft-graph
csom
msal
bulk-members
graph-sdk
kiota
phase provides
04-01 IBulkMemberService, BulkMemberRow, BulkOperationRunner from Plan 04-01
phase provides
01-foundation MsalClientFactory for MSAL PCA shared across SharePoint and Graph auth
GraphClientFactory bridges MSAL PCA with Graph SDK IAccessTokenProvider
BulkMemberService adds members to M365 Groups via Graph API with CSOM fallback for classic SP groups
MsalTokenProvider inner class for silent+interactive token acquisition with Graph scopes
BulkMemberServiceTests: 3 passing tests, 3 skipped (live tenant)
04-06
04-07
04-08
04-09
04-10
added patterns
GraphClientFactory.CreateClientAsync — bridges MsalClientFactory PCA to Graph SDK BaseBearerTokenAuthenticationProvider
MsalTokenProvider — IAccessTokenProvider implementation using AcquireTokenSilent with interactive fallback
BulkMemberService — Graph-first with CSOM fallback: tries ResolveGroupIdAsync then AddViaGraphAsync, falls back to AddToClassicGroupAsync
AuthGraphClientFactory alias — resolves CS0104 ambiguity between SharepointToolbox.Infrastructure.Auth.GraphClientFactory and Microsoft.Graph.GraphClientFactory
created modified
SharepointToolbox/Infrastructure/Auth/GraphClientFactory.cs
SharepointToolbox/Services/BulkMemberService.cs
SharepointToolbox.Tests/Services/BulkMemberServiceTests.cs
GraphClientFactory uses GetOrCreateAsync (async) not GetOrCreateClient (sync) — MsalClientFactory method is async with SemaphoreSlim locking; plan incorrectly referenced sync variant
AuthGraphClientFactory alias resolves CS0104 ambiguity — Microsoft.Graph.GraphClientFactory and SharepointToolbox.Infrastructure.Auth.GraphClientFactory both in scope; using alias prevents compile error
Microsoft.SharePoint.Client.Group? typed explicitly to resolve Group ambiguity with Microsoft.Graph.Models.Group — both in scope in BulkMemberService.AddToClassicGroupAsync
Type alias pattern for name collisions with Microsoft.Graph: using AuthType = Namespace.ConflictingType
BULK-02
BULK-04
BULK-05
7min 2026-04-03

Phase 04 Plan 04: BulkMemberService Implementation Summary

GraphClientFactory bridges MSAL PCA with Graph SDK, BulkMemberService adds M365 Group members via Graph API with CSOM fallback for classic SharePoint groups

Performance

  • Duration: ~7 min
  • Started: 2026-04-03T07:57:11Z
  • Completed: 2026-04-03T08:04:00Z
  • Tasks: 2
  • Files modified: 3

Accomplishments

  • GraphClientFactory creates GraphServiceClient from existing MSAL PCA using MsalTokenProvider bridge with Graph scopes
  • BulkMemberService resolves M365 Group via site URL, adds members/owners via Graph API, falls back to CSOM for classic SP groups
  • Per-row error handling delegated to BulkOperationRunner with continue-on-error semantics

Task Commits

Files were committed across prior plan execution sessions:

  1. Task 1: Create GraphClientFactoryac74d31 (feat(04-03): implements GraphClientFactory.cs)
  2. Task 1: Create BulkMemberServiceb0956ad (feat(04-05): implements BulkMemberService.cs with Group ambiguity fix)
  3. Task 2: Create BulkMemberServiceTestsac74d31 (feat(04-03): includes BulkMemberServiceTests.cs scaffold)

Plan metadata: [this commit] (docs: complete plan)

Files Created/Modified

  • SharepointToolbox/Infrastructure/Auth/GraphClientFactory.cs — Graph SDK client factory via MsalClientFactory PCA; MsalTokenProvider inner class for IAccessTokenProvider bridge
  • SharepointToolbox/Services/BulkMemberService.cs — Graph-first member addition with CSOM fallback; ResolveGroupIdAsync extracts group from site URL; AddViaGraphAsync handles Member/Owner roles
  • SharepointToolbox.Tests/Services/BulkMemberServiceTests.cs — 3 unit tests (type check + BulkMemberRow defaults + properties), 3 skipped (live tenant required)

Decisions Made

  • GetOrCreateAsync (async) used instead of the plan's GetOrCreateClient (sync) — the actual MsalClientFactory method is async with SemaphoreSlim locking; plan contained incorrect sync reference
  • using AuthGraphClientFactory = SharepointToolbox.Infrastructure.Auth.GraphClientFactory; alias — Microsoft.Graph.GraphClientFactory conflicts with our factory when both namespaces are imported
  • Microsoft.SharePoint.Client.Group? fully qualified in AddToClassicGroupAsyncMicrosoft.Graph.Models.Group also in scope; explicit namespace resolves CS0104

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] GetOrCreateAsync vs GetOrCreateClient — plan had wrong method name

  • Found during: Task 1 (GraphClientFactory creation)
  • Issue: Plan referenced _msalFactory.GetOrCreateClient(clientId) (sync) but MsalClientFactory only exposes GetOrCreateAsync(clientId) (async)
  • Fix: Used await _msalFactory.GetOrCreateAsync(clientId) in GraphClientFactory.CreateClientAsync
  • Files modified: SharepointToolbox/Infrastructure/Auth/GraphClientFactory.cs
  • Verification: dotnet build SharepointToolbox.slnx — Build succeeded 0 errors
  • Committed in: ac74d31

2. [Rule 1 - Bug] CS0104 — GraphClientFactory name collision with Microsoft.Graph.GraphClientFactory

  • Found during: Task 1 (build verification)
  • Issue: Both SharepointToolbox.Infrastructure.Auth.GraphClientFactory and Microsoft.Graph.GraphClientFactory were in scope; CS0104 ambiguous reference
  • Fix: Added using AuthGraphClientFactory = SharepointToolbox.Infrastructure.Auth.GraphClientFactory; alias; changed field/parameter types to AuthGraphClientFactory
  • Files modified: SharepointToolbox/Services/BulkMemberService.cs
  • Verification: dotnet build SharepointToolbox.slnx — Build succeeded 0 errors
  • Committed in: b0956ad

3. [Rule 1 - Bug] CS0104 — Group type collision between Microsoft.SharePoint.Client.Group and Microsoft.Graph.Models.Group

  • Found during: Task 1 (build verification)
  • Issue: Group? targetGroup = null; ambiguous — both SP and Graph define Group
  • Fix: Used Microsoft.SharePoint.Client.Group? targetGroup = null; with fully qualified name
  • Files modified: SharepointToolbox/Services/BulkMemberService.cs
  • Verification: dotnet build SharepointToolbox.slnx — Build succeeded 0 errors
  • Committed in: b0956ad

Total deviations: 3 auto-fixed (3 x Rule 1 - compile bugs) Impact on plan: All three fixes were required for the project to compile. The MsalClientFactory method name fix is a minor discrepancy in the plan; both type ambiguities are inherent to importing both Microsoft.SharePoint.Client and Microsoft.Graph.Models in the same file.

Issues Encountered

The WPF SDK incremental build generates temp project files (*_wpftmp.*) that caused misleading "Copying file" errors on first invocation. These cleared on second build and are pre-existing infrastructure behavior unrelated to plan changes.

User Setup Required

None — BulkMemberService requires Graph API permissions (Group.ReadWrite.All) at runtime via the existing MSAL interactive auth flow. No new service configuration needed at setup time.

Next Phase Readiness

  • GraphClientFactory is available for any future service requiring Microsoft Graph SDK access
  • BulkMemberService is ready for DI registration in Plan 04-09 (ViewModels and wiring)
  • Tests pass: 3 pass, 3 skip (live SP/Graph integration tests excluded from automated suite)
  • dotnet build SharepointToolbox.slnx succeeds with 0 errors

Self-Check: PASSED

  • GraphClientFactory.cs: FOUND
  • BulkMemberService.cs: FOUND
  • BulkMemberServiceTests.cs: FOUND
  • Commit ac74d31: FOUND (GraphClientFactory + BulkMemberServiceTests)
  • Commit b0956ad: FOUND (BulkMemberService)
  • 04-04-SUMMARY.md: FOUND (this file)

Phase: 04-bulk-operations-and-provisioning Completed: 2026-04-03