fix: resilient member lookup across Tharga.Team / MongoDB / Blazor / Service#66
Merged
Conversation
…Service Resolves #64 — drives ThrowMoreThanOneMatchException to zero when Team.Members or ApiKey collections contain duplicate-keyed rows. - New ResilientMemberLookup helper in Tharga.Team exposing PickOneOrDefault (two overloads) and ReplaceByReference extensions. - Replaced .Single/.SingleOrDefault at 13 call sites across TeamRepository (6), TeamServiceBase (4), TeamComponent.razor / TeamInviteView.razor (2), and ApiKeyAdministrationService (2). - Fixed the symmetric strip-siblings bug in TeamRepository writes by using ReplaceByReference instead of Where(x => x.Key != userKey) so duplicate-keyed siblings are preserved on save. - Promoted the existing internal TeamMemberResolver helper from Tharga.Team.Blazor into the new public helper; updated 5 razor callers; removed the old internal helper. 14 new tests, 289 / 289 passing.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves #64 — the comprehensive
.Single(predicate)sweep that follows up on #59. DrivesThrowMoreThanOneMatchExceptionto zero across the Platform stack whenTeam.MembersorApiKeycollections happen to contain duplicate-keyed rows.Tharga.Team.ResilientMemberLookupwith threeIEnumerable<T>extensions:PickOneOrDefault(two overloads — team-member-domain and single-context) andReplaceByReference..Single/.SingleOrDefaultat 13 call sites acrossTeamRepository(6),TeamServiceBase(4),TeamComponent.razor/TeamInviteView.razor(2), andApiKeyAdministrationService(2). Each site picks the first match and logs aWarningcarrying the team key, lookup key, and match count so duplicates are findable for out-of-band cleanup.TeamRepositorywrites: every formerWhere(x => x.Key != userKey).Union([member])is nowmembers.ReplaceByReference(target, updated), so duplicate-keyed siblings are preserved on save rather than silently dropped.TeamMemberResolverfromTharga.Team.Blazorinto the new public helper; updated 5 razor callers; removed the old helper.Behaviour change for consumers
TeamServiceBaseandTeamRepositoryconstructors now accept an optionalILogger<>(defaultnull). Existing subclasses (TeamServiceRepositoryBase, customTeamServiceimplementations) continue to compile without change. WireAddLogging()in your composition root to capture the new duplicate-row warnings.ApiKeyAdministrationServiceconstructor adds an optionalILogger<ApiKeyAdministrationService>parameter (defaultnull).Out of scope
UserServiceBase.GetUserAsyncrace (#65) — separate feature.Test plan
dotnet build -c Release— 0 warnings, 0 errorsdotnet test -c Release— 289 / 289 passing (14 new tests)ResilientMemberLookupTests(10 tests) — bothPickOneOrDefaultoverloads andReplaceByReference, including the strip-siblings preservation testResilientLookupCallSiteTests(3 tests) —RemoveMemberAsync+TransferOwnershipAsyncwith duplicate-keyed membersApiKeyAdministrationServiceTests(+1 test) — two stored keys both verify true → first-match returned, no throw