improvement(perm-groups): allow workspace filter for permission groups#5070
improvement(perm-groups): allow workspace filter for permission groups#5070icecrasher321 wants to merge 10 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryHigh Risk Overview Backend: migration adds API/UI: create/update/list groups carry workspace scope; new GET org workspaces for the picker; Access Control UI adds workspace multi-select and detail layout tweaks; modal fix for stale Docs and contract tests updated for the new membership and precedence rules. Reviewed by Cursor Bugbot for commit da3bc56. Configure here. |
Greptile SummaryThis PR extends permission groups to support workspace-scoped targeting: groups can now govern all workspaces (existing behavior, default) or a specific subset. A new
Confidence Score: 5/5Safe to merge — the TOCTOU race flagged in the previous review is now properly addressed with a per-org advisory lock, conflict detection runs inside the same transaction as the write, and existing groups are unaffected by the migration default. The advisory lock serializes all membership and scope writes for an org, and findScopeConflicts + the insert are now atomic. DB migration defaults appliesToAllWorkspaces = true so all existing groups continue to govern every workspace. Resolution logic is a single LEFT JOIN query with clear precedence rules. No correctness issues were found in conflict detection, workspace scope validation, or the Zod contract refinements. No files require special attention — the core locking and conflict logic in utils.ts and the three member/scope mutation routes are the most sensitive paths and all look correct. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client
participant MemberRoute as POST /members (or /bulk)
participant DB as Postgres
Client->>MemberRoute: "POST {userId(s)}"
MemberRoute->>DB: loadGroupInOrganization() [outside tx]
MemberRoute->>DB: BEGIN TRANSACTION
MemberRoute->>DB: "SET lock_timeout = 5000ms"
MemberRoute->>DB: pg_advisory_xact_lock(hash(org_id))
Note over MemberRoute,DB: Concurrent writes for same org queue here
MemberRoute->>DB: loadGroupInOrganization() [re-read under lock]
MemberRoute->>DB: getGroupWorkspaces() if specific scope
MemberRoute->>DB: findScopeConflicts(candidateUserIds)
Note over MemberRoute,DB: Checks: all-vs-all OR specific-vs-specific(shared workspace)
alt conflicts found
MemberRoute->>DB: ROLLBACK
MemberRoute-->>Client: 409 conflict message
else no conflicts
MemberRoute->>DB: INSERT permissionGroupMember(s)
MemberRoute->>DB: COMMIT
MemberRoute-->>Client: "201 {member(s)}"
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Client
participant MemberRoute as POST /members (or /bulk)
participant DB as Postgres
Client->>MemberRoute: "POST {userId(s)}"
MemberRoute->>DB: loadGroupInOrganization() [outside tx]
MemberRoute->>DB: BEGIN TRANSACTION
MemberRoute->>DB: "SET lock_timeout = 5000ms"
MemberRoute->>DB: pg_advisory_xact_lock(hash(org_id))
Note over MemberRoute,DB: Concurrent writes for same org queue here
MemberRoute->>DB: loadGroupInOrganization() [re-read under lock]
MemberRoute->>DB: getGroupWorkspaces() if specific scope
MemberRoute->>DB: findScopeConflicts(candidateUserIds)
Note over MemberRoute,DB: Checks: all-vs-all OR specific-vs-specific(shared workspace)
alt conflicts found
MemberRoute->>DB: ROLLBACK
MemberRoute-->>Client: 409 conflict message
else no conflicts
MemberRoute->>DB: INSERT permissionGroupMember(s)
MemberRoute->>DB: COMMIT
MemberRoute-->>Client: "201 {member(s)}"
end
Reviews (5): Last reviewed commit: "Merge branch 'staging' into improvement/..." | Re-trigger Greptile |
|
bugbot run |
|
@greptile |
|
bugbot run |
|
@greptile |
|
@greptile |
|
bugbot run |
|
@greptile |
|
bugbot run |
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit da3bc56. Configure here.
Summary
Allow workspace specific application of permission groups.
No backwards compatibility issues.
Type of Change
Testing
Tested manually
Checklist