Skip to content

refactor(group): resolve org from the group instead of the request#1739

Open
AmanGIT07 wants to merge 1 commit into
mainfrom
refactor/group-rpcs
Open

refactor(group): resolve org from the group instead of the request#1739
AmanGIT07 wants to merge 1 commit into
mainfrom
refactor/group-rpcs

Conversation

@AmanGIT07

Copy link
Copy Markdown
Contributor

What changed

  • Removed org_id from the request protos of GetGroup, UpdateGroup,
    ListGroupUsers, RemoveGroupUser, EnableGroup, DisableGroup,
    DeleteGroup, and SetGroupMemberRole. Each addresses a group by its id.
  • These handlers resolve the org from the group record. The request no
    longer carries an org id.
  • GroupRepository.UpdateByID no longer writes org_id. A group's org is
    fixed at creation and cannot change through an update.
  • GroupService.GetByIDs takes an optional Filter. A new IncludeDisabled
    option lets EnableGroup find a group that is currently disabled.
  • group view CLI takes <group-id> only.
  • Regenerated proto from proton.

Behavior

  • A wrong or missing org_id on these calls used to return OrgNotFound.
    The field is gone. Clients that still send it are ignored (unknown JSON
    fields are dropped), so nothing breaks on the wire.
  • Reads and updates of a group in a disabled org return FailedPrecondition.
    A read of a disabled group returns NotFound.
  • DeleteGroup is no longer blocked when the group's org is disabled.
  • CreateGroup and ListOrganizationGroups keep org_id — the org is a
    real input there.

Testing

  • Unit: connect handlers, core group, cmd.
  • Repo (Docker): group repository, including the org-immutable update.
  • e2e (Docker): TestGroupAPI, including a disable → enable round-trip.

Depends on

  • The matching proton change on branch refactor/group-rpcs (removes
    org_id from the group request messages). Merge proton first, then bump
    PROTON_COMMIT to the merged SHA.

🤖 Generated with Claude Code

Group read and update RPCs took an org_id that was trusted but never
checked against the group. Remove org_id from those request protos and
derive the org from the group record. A group's org is now fixed at
creation and cannot change through an update.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment Jul 8, 2026 5:38am

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Group actions now work with just the group ID in more places, simplifying the CLI and API usage.
    • Disabled groups can be hidden from reads and later re-enabled.
  • Bug Fixes

    • Improved handling of group operations when organizations are disabled.
    • Group updates now keep the existing organization unchanged.
    • Group listing and membership actions now respect disabled-group visibility rules.

Walkthrough

Group operations across CLI, core service, Connect API handlers, Postgres repository, and tests are refactored to derive organization context from the group record instead of requiring an OrgId parameter. A new IncludeDisabled filter field enables fetching disabled groups, notably for the EnableGroup flow. A Makefile Proton commit hash is also bumped.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: rohilsurana

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 28920251707

Coverage decreased (-0.01%) to 44.865%

Details

  • Coverage decreased (-0.01%) from the base build.
  • Patch coverage: 10 uncovered changes across 3 files (55 of 65 lines covered, 84.62%).
  • 2 coverage regressions across 1 file.

Uncovered Changes

File Changed Covered %
internal/api/v1beta1connect/group.go 48 42 87.5%
cmd/group.go 4 2 50.0%
core/group/service.go 6 4 66.67%
Total (4 files) 65 55 84.62%

Coverage Regressions

2 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
internal/store/postgres/group_repository.go 2 76.03%

Coverage Stats

Coverage Status
Relevant Lines: 37593
Covered Lines: 16866
Line Coverage: 44.86%
Coverage Strength: 12.52 hits per line

💛 - Coveralls

@AmanGIT07 AmanGIT07 requested a review from whoAbhishekSah July 8, 2026 05:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/api/v1beta1connect/group.go (1)

398-418: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

EnableGroup returns Internal instead of NotFound for invalid group IDs.

h.groupService.GetByIDs can return group.ErrInvalidID (empty id) or group.ErrInvalidUUID (malformed id) — both are expected, "not found"-class errors elsewhere in this file (see getGroupInEnabledOrg). Here they're unconditionally wrapped as CodeInternal, unlike DisableGroup/GetGroup/etc., which correctly map these to CodeNotFound. This is an inconsistent API contract for the same class of client error.

🐛 Proposed fix
 	grps, err := h.groupService.GetByIDs(ctx, []string{request.Msg.GetId()}, group.Filter{IncludeDisabled: true})
 	if err != nil {
-		return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableGroup.GetByIDs: group_id=%s: %w", request.Msg.GetId(), err))
+		switch {
+		case errors.Is(err, group.ErrInvalidID), errors.Is(err, group.ErrInvalidUUID):
+			return nil, connect.NewError(connect.CodeNotFound, ErrGroupNotFound)
+		default:
+			return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("EnableGroup.GetByIDs: group_id=%s: %w", request.Msg.GetId(), err))
+		}
 	}
🧹 Nitpick comments (2)
internal/api/v1beta1connect/group.go (1)

264-274: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Dead error-mapping branches after removing org_id from update.

organization.ErrInvalidUUID and organization.ErrNotExist can no longer be returned by groupService.Update since UpdateByID no longer references org_id in its SET clause. These two cases are now unreachable.

♻️ Proposed cleanup
-		case errors.Is(err, group.ErrInvalidDetail), errors.Is(err, organization.ErrInvalidUUID), errors.Is(err, organization.ErrNotExist):
+		case errors.Is(err, group.ErrInvalidDetail):
 			return nil, connect.NewError(connect.CodeInvalidArgument, ErrBadRequest)
internal/api/v1beta1connect/group_test.go (1)

1443-1526: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Missing test coverage for invalid group id in EnableGroup.

None of the cases exercise GetByIDs returning group.ErrInvalidID/group.ErrInvalidUUID, which would have caught the Internal-vs-NotFound inconsistency flagged in group.go's EnableGroup handler.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6c995f43-09a8-4c41-ac5f-ce6be3796d2a

📥 Commits

Reviewing files that changed from the base of the PR and between b763d0a and 99e733c.

⛔ Files ignored due to path filters (1)
  • proto/v1beta1/frontier.pb.go is excluded by !**/*.pb.go, !proto/**
📒 Files selected for processing (12)
  • Makefile
  • cmd/group.go
  • cmd/group_test.go
  • core/group/filter.go
  • core/group/service.go
  • internal/api/v1beta1connect/group.go
  • internal/api/v1beta1connect/group_test.go
  • internal/api/v1beta1connect/interfaces.go
  • internal/api/v1beta1connect/mocks/group_service.go
  • internal/store/postgres/group_repository.go
  • internal/store/postgres/group_repository_test.go
  • test/e2e/regression/api_test.go

Comment on lines 883 to 892
s.Run("6. group admin update a new team with empty group id should return invalid arg", func() {
_, err := s.testBench.Client.UpdateGroup(ctxOrgAdminAuth, connect.NewRequest(&frontierv1beta1.UpdateGroupRequest{
Id: "",
OrgId: myOrg.GetId(),
Body: &frontierv1beta1.GroupRequestBody{},
Id: "",
Body: &frontierv1beta1.GroupRequestBody{},
}))
s.Assert().Equal(connect.CodeInvalidArgument, connect.CodeOf(err))
})
s.Run("7. group admin update a new team without group id should fail", func() {
_, err := s.testBench.Client.UpdateGroup(ctxOrgAdminAuth, connect.NewRequest(&frontierv1beta1.UpdateGroupRequest{
OrgId: myOrg.GetId(),
Body: &frontierv1beta1.GroupRequestBody{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect UpdateGroup handler to verify empty ID validation before getGroupInEnabledOrg

# Get the AST outline of the group handler file, focusing on UpdateGroup
ast-grep outline internal/api/v1beta1connect/group.go --match UpdateGroup --view expanded

# Then read the UpdateGroup handler implementation
rg -n -A 40 'func \(h \*ConnectHandler\) UpdateGroup' internal/api/v1beta1connect/group.go

Repository: raystack/frontier

Length of output: 2553


Return InvalidArgument for empty/missing group IDs

UpdateGroup sends empty or missing IDs into getGroupInEnabledOrg, which maps invalid IDs to NotFound. Validate the ID before that lookup, or subtests 6 and 7 will keep failing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants