feat(17-01): ResolvedMember model, ISharePointGroupResolver interface, SharePointGroupResolver CSOM+Graph implementation

- ResolvedMember record in Core/Models with DisplayName and Login
- ISharePointGroupResolver interface with ResolveGroupsAsync contract
- SharePointGroupResolver: CSOM group user loading + Graph transitive AAD resolution
- Internal static helpers IsAadGroup, ExtractAadGroupId, StripClaims (all green unit tests)
- Graceful error handling: exceptions return empty list per group, never throw
- OrdinalIgnoreCase result dict; lazy Graph client creation on first AAD group
This commit is contained in:
Dev
2026-04-09 13:04:56 +02:00
parent 0f8b1953e1
commit 543b863283
4 changed files with 217 additions and 7 deletions

View File

@@ -0,0 +1,10 @@
namespace SharepointToolbox.Core.Models;
/// <summary>
/// Represents a resolved leaf member of a SharePoint group or nested AAD group.
/// Used by <see cref="SharepointToolbox.Services.ISharePointGroupResolver"/> to return
/// transitive member lists for HTML report group expansion (Phase 17).
/// </summary>
/// <param name="DisplayName">The display name of the member (e.g. "Alice Smith").</param>
/// <param name="Login">The login / UPN of the member (e.g. "alice@contoso.com"), with claims prefix stripped.</param>
public record ResolvedMember(string DisplayName, string Login);