Skip to content

Comments

refactor: replace checkAdminOrOwner with team.create permission in teams page#24116

Merged
Udit-takkar merged 4 commits intomainfrom
devin/1758898927-remove-checkadminorowner-teams
Sep 29, 2025
Merged

refactor: replace checkAdminOrOwner with team.create permission in teams page#24116
Udit-takkar merged 4 commits intomainfrom
devin/1758898927-remove-checkadminorowner-teams

Conversation

@eunjae-lee
Copy link
Contributor

@eunjae-lee eunjae-lee commented Sep 26, 2025

What does this PR do?

This PR refactors the teams server page to migrate from role-based access control to Permission-Based Access Control (PBAC), following the established PBAC refactoring guide patterns.

Key Changes:

  • Replaces checkAdminOrOwner with PermissionCheckService to check team.create permission
  • Updates TeamsListing component to use a permissions object instead of isOrgAdmin boolean prop
  • Maintains existing functionality while moving to server-side permission checks

Files Modified:

  • apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx - Permission check logic
  • packages/features/ee/teams/components/TeamsListing.tsx - Component props interface

Link to Devin run: https://app.devin.ai/sessions/24bad72c8df24c66852409ffe4222142
Requested by: @eunjae-lee

How should this be tested?

⚠️ Important: Local testing was limited due to authentication issues during development.

Test Scenarios:

  1. Organization Admin/Owner: Should see enabled "Create Team" button
  2. Organization Member: Should see disabled "Create Team" button
  3. Non-organization User: Should see enabled "Create Team" button
  4. Various permission levels: Test users with different team membership roles

Test Steps:

  1. Navigate to /teams page with different user permission levels
  2. Verify create team button state matches user permissions
  3. Test team creation flow works for authorized users
  4. Verify error handling for unauthorized access attempts

Mandatory Tasks

  • I have self-reviewed the code
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A - follows existing PBAC patterns
  • I confirm automated tests are in place that prove my fix is effective or that my feature works. Note: Limited testing due to local auth issues

Review Focus Areas

Critical Review Points:

  1. Permission Logic Correctness: Verify getTeamIdsWithPermission with team.create permission correctly replaces checkAdminOrOwner behavior
  2. Fallback Roles: Confirm [MembershipRole.ADMIN, MembershipRole.OWNER] matches original role check logic
  3. Edge Cases: Review logic for users without organization membership (!orgId || teamIdsWithCreatePermission.includes(orgId))
  4. Component Interface: Ensure no other TeamsListing call sites are broken by the props change
  5. UI Behavior: Test create team button state with various user permission levels

Security Considerations:

  • Permission checks are now performed server-side (improvement)
  • Uses established PBAC service patterns
  • Maintains principle of least privilege

Checklist

  • My code follows the style guidelines of this project
  • I have checked if my changes generate no new warnings
  • I have followed the PBAC refactoring guide patterns

…ams page

- Replace role-based access control with PBAC using team.create permission
- Follow PBAC refactoring guide pattern for server-side permission checking
- Use permission-specific variable naming (canCreateTeam)
- Maintain existing TeamsListing component interface

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 26, 2025

Walkthrough

  • Replaces admin/owner role checks with PermissionCheckService canCreateTeam, scoped by orgId (defaults to false when orgId is absent).
  • Updates server-page.tsx imports to use PermissionCheckService and MembershipRole; removes checkAdminOrOwner usage.
  • Main now computes and passes permissions.canCreateTeam to child components.
  • CTA rendering switches to use permissions.canCreateTeam or absence of orgId.
  • TeamsListing props updated from isOrgAdmin to permissions with canCreateTeam, and all related conditional UI logic adjusted accordingly.
  • Public component signature of TeamsListing changed to accept permissions: { canCreateTeam: boolean }.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly summarizes the primary refactoring from role-based “checkAdminOrOwner” to permission-based “team.create” checks on the teams page, clearly reflecting the main change without unnecessary detail.
Description Check ✅ Passed The description provides a clear overview of the migration to Permission-Based Access Control, outlines key changes, modified files, testing steps, and relevant context, directly reflecting the changes in the pull request.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1758898927-remove-checkadminorowner-teams

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 and usage tips.

@keithwillcode keithwillcode added consumer core area: core, team members only labels Sep 26, 2025
- Replace isOrgAdmin prop with permissions object containing canCreateTeam
- Follow PBAC refactoring guide pattern for UI components
- Update TeamsListing component to use permissions.canCreateTeam
- Maintain existing functionality while improving code structure
- All type checking and linting verification passed

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
@pull-request-size pull-request-size bot added size/M and removed size/S labels Sep 26, 2025
@vercel
Copy link

vercel bot commented Sep 26, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Sep 29, 2025 7:29am
cal-eu Ignored Ignored Sep 29, 2025 7:29am

@eunjae-lee eunjae-lee marked this pull request as ready for review September 26, 2025 15:35
@graphite-app graphite-app bot requested a review from a team September 26, 2025 15:35
@dosubot dosubot bot added the 🧹 Improvements Improvements to existing features. Mostly UX/UI label Sep 26, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx (1)

69-71: Use object property shorthand for brevity.

Minor readability tweak.

-        permissions={{
-          canCreateTeam: canCreateTeam,
-        }}
+        permissions={{ canCreateTeam }}
packages/features/ee/teams/components/TeamsListing.tsx (2)

22-24: Props refactor to permissions object is sound; consider extracting a shared type.

Define and reuse a named type to keep server/client in sync.

 type TeamsListingProps = {
   orgId: number | null;
-  permissions: {
-    canCreateTeam: boolean;
-  };
+  permissions: TeamsListingPermissions;
   teams: RouterOutputs["viewer"]["teams"]["list"];
   teamNameFromInvite: string | null;
   errorMsgFromInvite: string | null;
 };
+
+type TeamsListingPermissions = {
+  canCreateTeam: boolean;
+};

56-56: Avoid double-negation and truthy pitfalls with number orgId.

Explicit boolean expression reads clearer.

-  const isCreateTeamButtonDisabled = !!(orgId && !permissions.canCreateTeam);
+  const isCreateTeamButtonDisabled = orgId !== null && !permissions.canCreateTeam;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d261a23 and 5af33bd.

📒 Files selected for processing (2)
  • apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx (2 hunks)
  • packages/features/ee/teams/components/TeamsListing.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
  • packages/features/ee/teams/components/TeamsListing.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
  • packages/features/ee/teams/components/TeamsListing.tsx
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
  • packages/features/ee/teams/components/TeamsListing.tsx
🧬 Code graph analysis (2)
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx (2)
packages/features/pbac/services/permission-check.service.ts (1)
  • PermissionCheckService (19-306)
packages/features/ee/teams/components/TeamsListing.tsx (1)
  • TeamsListing (30-174)
packages/features/ee/teams/components/TeamsListing.tsx (1)
packages/trpc/react/trpc.ts (1)
  • RouterOutputs (143-143)
🔇 Additional comments (4)
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx (2)

76-76: CTA gating aligns with new permission model.

Showing CTA when no org or when canCreateTeam is true matches the UI logic downstream.


54-62: Approve PBAC check for team.create. Verified the permission string is used correctly here and no legacy checkAdminOrOwner remains in this file.

packages/features/ee/teams/components/TeamsListing.tsx (2)

133-146: Buttons visibility now correctly depends on permissions.canCreateTeam (or no org).

This matches server CTA logic and preserves legacy behavior for non-org users.


20-36: All TeamsListing calls match the new prop signature; no isOrgAdmin prop remains.

@github-actions
Copy link
Contributor

E2E results are ready!

Copy link
Contributor

@Udit-takkar Udit-takkar left a comment

Choose a reason for hiding this comment

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

LGTM

@Udit-takkar Udit-takkar merged commit 752f7fc into main Sep 29, 2025
39 checks passed
@Udit-takkar Udit-takkar deleted the devin/1758898927-remove-checkadminorowner-teams branch September 29, 2025 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

consumer core area: core, team members only 🧹 Improvements Improvements to existing features. Mostly UX/UI ready-for-e2e size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants