refactor(group): migrate RemoveGroupUser handler to membership#1611
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThis PR adds group member removal functionality by implementing ChangesGroup Member Removal Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Coverage Report for CI Build 25851271234Coverage increased (+0.09%) to 42.373%Details
Uncovered Changes
Coverage Regressions4 previously-covered lines in 1 file lost coverage.
Coverage Stats
💛 - Coveralls |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
internal/api/v1beta1connect/group_test.go (1)
1387-1501: ⚡ Quick winAdd coverage for remaining new RemoveGroupUser error mappings.
Please add table cases for
membership.ErrInvalidPrincipalType/membership.ErrInvalidPrincipal(expectCodeInvalidArgument) anduser.ErrDisabled(expectCodeFailedPrecondition) to lock the handler contract introduced in this refactor.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 74ca9954-69e3-4ac7-ab4b-730a557c6c25
📒 Files selected for processing (7)
core/membership/service.gocore/membership/service_test.gointernal/api/v1beta1connect/group.gointernal/api/v1beta1connect/group_test.gointernal/api/v1beta1connect/interfaces.gointernal/api/v1beta1connect/mocks/membership_service.gopkg/auditrecord/consts.go
Manual Testing Results ✅Tested RemoveGroupUser API Tests
Ownership Transition Tests
Unit Tests (all pass)
|
The RemoveGroupUser RPC handler now delegates to a new membershipService.RemoveGroupMember, completing the symmetry with the AddGroupUsers migration (#1608). The proto RPC is unchanged. - Adds RemoveGroupMember to core/membership/service.go. Validates principal, enforces the min-owner constraint via the existing atomic DeleteWithMinRoleGuard, cleans up both group#owner and group#member relations, and emits an audit event. - Moves the min-owner pre-check out of the handler. Previously the handler called userService.ListByGroup(group.AdminRole) and compared counts; that race-prone two-step is replaced by validateMinGroupOwner + the atomic guard pattern already used by SetGroupMemberRole. - Adds the GroupMemberRemovedEvent audit constant. groupService.RemoveUsers / removeUsers are intentionally kept — they serve the user-cascade path (core/deleter and group.Delete), which must bypass the min-owner constraint when the user is being destroyed system-wide. Matches the org pattern where Service.RemoveUsers and RemoveOrganizationMember coexist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds table cases for user.ErrDisabled, membership.ErrInvalidPrincipalType, and membership.ErrInvalidPrincipal so the handler's error mapping contract is fully locked. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
d8819d4 to
56c4f79
Compare
Summary
Migrates the
RemoveGroupUserRPC handler offgroupService.RemoveUsersand onto a newmembershipService.RemoveGroupMember, mirroring the add-side work in #1608. Proto RPC unchanged.The new method enforces the min-owner constraint via the existing
DeleteWithMinRoleGuardatomic pattern (same asSetGroupMemberRole). This replaces the handler-level pre-check that compared owner counts viauserService.ListByGroup— that two-step had the same TOCTOU pattern fixed for org in #1590.Behavior
RemoveGroupUserunchanged: same error code (InvalidArgument+ErrGroupMinOwnerCount) on last-owner attempts.GroupMemberRemovedEventaudit record + context auditor log.RemoveGroupMemberrestricts principal types toapp/userfor now; the switch is extensible for future types (same convention asSetGroupMemberRole).What's intentionally not deleted
groupService.RemoveUsers/removeUsersstay. They serve the user-cascade path (core/deleter+group.Delete), which must bypass the min-owner constraint when the user is being destroyed system-wide. Matches the org pattern whereorg.Service.RemoveUsersandmembership.RemoveOrganizationMembercoexist.Test plan
go build ./...go test ./core/membership/... ./internal/api/v1beta1connect/...gofmt -lclean