-
Notifications
You must be signed in to change notification settings - Fork 10.6k
feat: auto-accept team invitations for existing users #24091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Change email button text from 'View Invitation' to 'Accept Invite' - Implement auto-accept flow when clicking email CTA - Update TeamService.inviteMemberByToken to support auto-acceptance - Add new autoAcceptInvite tRPC endpoint for handling auto-acceptance - Update invitation link generation to include autoAccept parameter - Handle both team and organization invitation scenarios - Maintain payment/billing flow integration with TeamBilling.updateQuantity - Preserve backward compatibility with existing manual flow - Update all locale files with new 'Accept Invite' button text Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
WalkthroughAdds an autoAccept query parameter to team invitation flows and propagates it through login callback URLs. Server pages and TeamsListing accept an autoAccept flag; when true and a token is present the flow calls TeamService.acceptInvitationByToken to auto-accept invites. TeamService gains acceptOrLeaveTeamMembership and acceptInvitationByToken to centralize accept/remove logic and profile/event updates. Invitation utilities centralize verification token creation and adjust join link construction; resend-invitation now defaults to /teams?token=...&autoAccept=true. Email CTA keys and locale strings are added and E2E tests for auto-accept and wrong-user errors are included. Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
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 |
- Keep only English 'Accept Invite' translation - Revert all other locale files to original 'View Invitation' translations - Maintain core auto-accept invitation functionality Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
The latest updates on your projects. Learn more about Vercel for GitHub. |
- Remove autoAccept parameter from TeamService.inviteMemberByToken - Always auto-accept invitations for existing users clicking email links - Remove autoAccept logic from teams server-page.tsx - Remove autoAccept=true from invitation URLs - Delete autoAcceptInvite handler and schema files - Remove autoAcceptInvite endpoint from tRPC router - Simplify invitation flow to match new user pattern Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
58d45f1
to
0712b27
Compare
- Change expectation from accepted: false to accepted: true - Update test description to reflect auto-accept behavior - Fix TypeScript type casting to use Pick<TeamRepository, 'deleteById'> - Aligns with new default auto-acceptance for team invitations Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
…://github.com/calcom/cal.com into devin/1758863155-auto-accept-team-invitations
- Fix duplicate property assignments in mock user objects - Use proper email format (user@example.com) for email fields - Use proper username format (testuser) for username fields - Fix logic error in acceptInvitationByToken (|| to &&) - Add autoAccept parameter to resendInvitation.handler.ts - All 16 tests passing with proper TypeScript types Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
- Add test for existing user auto-accepting team invitation via email link - Add test for error handling when wrong user tries to use invitation link - Verify proper user identity validation and database state changes - Follow existing e2e test patterns with browser context isolation - Fix ESLint warnings: replace conditional with assertion and remove unused browser parameter Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/features/ee/teams/components/TeamsListing.tsx (1)
91-110
: Don’t show success toast if auto-accept failed.This short-circuits on autoAccept regardless of server outcome, masking errors. Show error first, then success only if no error.
Apply this diff:
useEffect(() => { if (!token) { return; } - if (autoAccept) { - showToast(t("successfully_joined"), "success"); - return; - } + if (errorMsgFromInvite) { + showToast(errorMsgFromInvite, "error"); + return; + } + + if (autoAccept) { + showToast(t("successfully_joined"), "success"); + return; + } if (teamNameFromInvite) { showToast(t("team_invite_received", { teamName: teamNameFromInvite }), "success"); return; } - if (errorMsgFromInvite) { - showToast(errorMsgFromInvite, "error"); - return; - } - }, []); + }, [token, autoAccept, teamNameFromInvite, errorMsgFromInvite, t]);packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts (1)
505-516
: Fix token mismatch in signup invite linkYou generate a local
token
and also create a verification token, but the joinLink uses the local (unsaved) token, breaking signup flows. Use the token returned bycreateVerificationToken
and remove the unused local token.try { - const token: string = randomBytes(32).toString("hex"); - - await createVerificationToken(usernameOrEmail, teamId); + const verificationToken = await createVerificationToken(usernameOrEmail, teamId); await sendTeamInviteEmail({ language: translation, from: inviterName || `${team.name}'s admin`, to: usernameOrEmail, teamName: team.name, - joinLink: `${WEBAPP_URL}/signup?token=${token}&callbackUrl=/getting-started`, + joinLink: `${WEBAPP_URL}/signup?token=${verificationToken.token}&callbackUrl=/getting-started`, isCalcomMember: false, isOrg: isOrg, parentTeamName: team?.parent?.name, isAutoJoin: false, isExistingUserMovedToOrg: false,
🧹 Nitpick comments (8)
apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx (1)
26-27
: Encode callbackUrl when embedding it into the login URL.You build a safe callbackUrl (params encoded), but when passing it to
/auth/login?callbackUrl=...
it should be wrapped in encodeURIComponent to avoid parameter confusion.Suggested change outside the shown range (Line 30):
redirect(callbackUrl ? `/auth/login?callbackUrl=${encodeURIComponent(callbackUrl)}` : "/auth/login");apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx (1)
35-36
: Auto-accept: surface success/failure explicitly to the UI.Currently the service call returns void; UI infers success from autoAccept query. Prefer returning a success flag or team name from acceptInvitationByToken and pass it through, so the client can toast success only on actual acceptance. Also consider cache invalidation if you rely on tags elsewhere.
Also applies to: 43-47, 65-66
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts (1)
721-736
: Avoid reusing expired tokens when building invite linksWhen reusing an existing token, you don’t check its validity. If the token is expired, the auto-accept flow will fail. Filter by validity (expiry) and only reuse valid tokens; otherwise create a fresh one. Also, select only needed fields.
As per coding guidelines
- } else if (!isAutoJoin) { - let verificationToken = await prisma.verificationToken.findFirst({ - where: { - identifier: user.email, - teamId: teamId, - }, - }); + } else if (!isAutoJoin) { + let verificationToken = await prisma.verificationToken.findFirst({ + where: { + identifier: user.email, + teamId: teamId, + OR: [{ expiresInDays: null }, { expires: { gte: new Date() } }], + }, + select: { token: true }, + }); if (!verificationToken) { verificationToken = await createVerificationToken(user.email, teamId); } inviteTeamOptions.joinLink = `${WEBAPP_URL}/teams?token=${verificationToken.token}&autoAccept=true`; }packages/lib/server/service/teamService.test.ts (2)
334-366
: Add assertion that invite token is invalidated after acceptanceAfter a successful acceptance by token, we should delete the token. Add an expectation to ensure the service invalidates the token (see suggested change in TeamService).
Example assertion to add after calling
acceptInvitationByToken
:expect(prismaMock.verificationToken.deleteMany).toHaveBeenCalledWith({ where: { token: "valid-token" }, });
367-399
: Also assert token invalidation for username-identifier pathMirror the deletion assertion for the username match case to cover both identifier variants.
packages/lib/server/service/teamService.ts (3)
294-296
: Replace console.log with structured loggerUse the existing logger with context; avoid
console.log
in server code.- } catch (e) { - console.log(e); - } + } catch (e) { + logger.error("Failed to delete membership(s) on invite rejection", { userId, teamId, error: e }); + }
231-276
: Consider wrapping acceptance operations in a transactionAccepting child and parent memberships plus optional profile creation should be atomic to avoid partial state if one step fails.
343-350
: Invalidate the verification token after successful acceptancePrevent re-use of the invite link by deleting the token post-acceptance.
await TeamService.acceptOrLeaveTeamMembership({ accept: true, userId, teamId: verificationToken.teamId, userEmail: currentUser.email, username: currentUser.username, }); + await prisma.verificationToken.deleteMany({ where: { token: acceptanceToken } });
📜 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.
📒 Files selected for processing (11)
apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx
(1 hunks)apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
(2 hunks)apps/web/playwright/team/team-invitation.e2e.ts
(3 hunks)apps/web/public/static/locales/en/common.json
(1 hunks)packages/emails/src/templates/TeamInviteEmail.tsx
(1 hunks)packages/features/ee/teams/components/TeamsListing.tsx
(3 hunks)packages/lib/server/service/teamService.test.ts
(5 hunks)packages/lib/server/service/teamService.ts
(2 hunks)packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
(2 hunks)packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
(3 hunks)packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts
: For Prisma queries, only select data you need; never useinclude
, always useselect
Ensure thecredential.key
field is never returned from tRPC endpoints or APIs
Files:
packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
packages/lib/server/service/teamService.test.ts
apps/web/playwright/team/team-invitation.e2e.ts
packages/lib/server/service/teamService.ts
**/*.{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:
packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
packages/emails/src/templates/TeamInviteEmail.tsx
packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
packages/lib/server/service/teamService.test.ts
apps/web/playwright/team/team-invitation.e2e.ts
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
packages/features/ee/teams/components/TeamsListing.tsx
packages/lib/server/service/teamService.ts
**/*.{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:
packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
packages/emails/src/templates/TeamInviteEmail.tsx
packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
packages/lib/server/service/teamService.test.ts
apps/web/playwright/team/team-invitation.e2e.ts
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
packages/features/ee/teams/components/TeamsListing.tsx
packages/lib/server/service/teamService.ts
**/*.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/page.tsx
packages/emails/src/templates/TeamInviteEmail.tsx
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
packages/features/ee/teams/components/TeamsListing.tsx
**/*Service.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Service files must include
Service
suffix, use PascalCase matching exported class, and avoid generic names (e.g.,MembershipService.ts
)
Files:
packages/lib/server/service/teamService.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-08-27T16:39:38.192Z
Learning: anglerfishlyy successfully implemented CAL-3076 email invitation feature for Cal.com team event-types in PR #23312. The feature allows inviting people via email directly from assignment flow, with automatic team invitation if email doesn't belong to existing team member. Implementation includes Host type modifications (userId?: number, email?: string, isPending?: boolean), CheckedTeamSelect component updates with CreatableSelect, TRPC schema validation with zod email validation, and integration with existing teamInvite system.
📚 Learning: 2025-09-16T08:59:45.884Z
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-09-16T08:59:45.884Z
Learning: anglerfishlyy's PR #23467 demonstrates excellent software architecture with proper email validation (regex + zod), secure token generation using randomBytes, comprehensive host type system using discriminated unions (userId OR email), and smart reuse of existing team invitation infrastructure. The implementation includes robust error handling, type safety, and maintains backward compatibility while adding CreatableSelect-based email invitation functionality.
Applied to files:
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
apps/web/playwright/team/team-invitation.e2e.ts
📚 Learning: 2025-08-27T16:39:38.192Z
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-08-27T16:39:38.192Z
Learning: anglerfishlyy successfully implemented CAL-3076 email invitation feature for Cal.com team event-types in PR #23312. The feature allows inviting people via email directly from assignment flow, with automatic team invitation if email doesn't belong to existing team member. Implementation includes Host type modifications (userId?: number, email?: string, isPending?: boolean), CheckedTeamSelect component updates with CreatableSelect, TRPC schema validation with zod email validation, and integration with existing teamInvite system.
Applied to files:
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
packages/emails/src/templates/TeamInviteEmail.tsx
packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
apps/web/playwright/team/team-invitation.e2e.ts
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx
packages/lib/server/service/teamService.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
packages/emails/src/templates/TeamInviteEmail.tsx
🧬 Code graph analysis (6)
packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts (1)
packages/lib/constants.ts (1)
WEBAPP_URL
(12-18)
packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts (1)
packages/lib/constants.ts (1)
WEBAPP_URL
(12-18)
packages/lib/server/service/teamService.test.ts (2)
packages/lib/server/service/teamService.ts (1)
TeamService
(54-569)packages/lib/createAProfileForAnExistingUser.ts (1)
createAProfileForAnExistingUser
(13-104)
apps/web/playwright/team/team-invitation.e2e.ts (1)
apps/web/playwright/lib/localize.ts (1)
localize
(4-11)
apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx (1)
packages/lib/server/service/teamService.ts (1)
TeamService
(54-569)
packages/lib/server/service/teamService.ts (1)
packages/lib/createAProfileForAnExistingUser.ts (1)
createAProfileForAnExistingUser
(13-104)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (7)
packages/emails/src/templates/TeamInviteEmail.tsx (1)
64-65
: CTA label logic looks correct and matches new i18n keys.The conditional picks the intended keys (login/accept_invite/join_now). No issues spotted.
apps/web/public/static/locales/en/common.json (1)
2153-2156
: New strings align with usage.Keys accept_invite, join_now, and successfully_joined are added and referenced by the UI/email changes.
Please ensure these keys are added in other locales or that fallbacks are acceptable for this release.
packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts (1)
14-20
: Good delegation to service.Handler now cleanly delegates to TeamService with the necessary context. No issues.
packages/features/ee/teams/components/TeamsListing.tsx (1)
21-21
: Prop addition is clear and typed.Public surface updated to accept autoAccept: boolean. No issues.
apps/web/playwright/team/team-invitation.e2e.ts (3)
50-50
: LGTM: assert invite link presenceThis improves deterministic behavior over early returns.
195-257
: LGTM: solid coverage of auto‑accept happy pathEnd-to-end verifies link shape, pre/post membership state, login gating, and success toast.
259-326
: LGTM: negative path for wrong user is well coveredValidates error message and ensures no unauthorized membership changes.
There was a problem hiding this 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 (2)
apps/web/playwright/team/team-invitation.e2e.ts (2)
226-249
: Narrow Prisma membership selects in this testThese lookups only need the
accepted
boolean, but they currently fetch the entire membership row. Please add explicitselect
clauses here (and to the similar lookup a few lines below) to comply with our Prisma query guidelines.As per coding guidelines
- const membership = await prisma.membership.findFirst({ - where: { - userId: invitedUser.id, - teamId: team.id, - }, - }); + const membership = await prisma.membership.findFirst({ + where: { + userId: invitedUser.id, + teamId: team.id, + }, + select: { accepted: true }, + });
301-315
: Apply explicit selects when checking membershipsSame issue here: these assertions only require minimal fields (
id
andaccepted
), so let’s scope the selects accordingly to avoid pulling full membership records.As per coding guidelines
- const membership = await prisma.membership.findFirst({ + const membership = await prisma.membership.findFirst({ where: { userId: wrongUser.id, teamId: team.id, }, + select: { id: true }, }); ... - const invitedMembership = await prisma.membership.findFirst({ + const invitedMembership = await prisma.membership.findFirst({ where: { userId: invitedUser.id, teamId: team.id, }, + select: { accepted: true }, });
📜 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.
📒 Files selected for processing (2)
apps/web/playwright/team/team-invitation.e2e.ts
(3 hunks)packages/lib/server/service/teamService.ts
(3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*Service.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Service files must include
Service
suffix, use PascalCase matching exported class, and avoid generic names (e.g.,MembershipService.ts
)
Files:
packages/lib/server/service/teamService.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts
: For Prisma queries, only select data you need; never useinclude
, always useselect
Ensure thecredential.key
field is never returned from tRPC endpoints or APIs
Files:
packages/lib/server/service/teamService.ts
apps/web/playwright/team/team-invitation.e2e.ts
**/*.{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:
packages/lib/server/service/teamService.ts
apps/web/playwright/team/team-invitation.e2e.ts
**/*.{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:
packages/lib/server/service/teamService.ts
apps/web/playwright/team/team-invitation.e2e.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-08-27T16:39:38.192Z
Learning: anglerfishlyy successfully implemented CAL-3076 email invitation feature for Cal.com team event-types in PR #23312. The feature allows inviting people via email directly from assignment flow, with automatic team invitation if email doesn't belong to existing team member. Implementation includes Host type modifications (userId?: number, email?: string, isPending?: boolean), CheckedTeamSelect component updates with CreatableSelect, TRPC schema validation with zod email validation, and integration with existing teamInvite system.
📚 Learning: 2025-08-27T16:39:38.192Z
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-08-27T16:39:38.192Z
Learning: anglerfishlyy successfully implemented CAL-3076 email invitation feature for Cal.com team event-types in PR #23312. The feature allows inviting people via email directly from assignment flow, with automatic team invitation if email doesn't belong to existing team member. Implementation includes Host type modifications (userId?: number, email?: string, isPending?: boolean), CheckedTeamSelect component updates with CreatableSelect, TRPC schema validation with zod email validation, and integration with existing teamInvite system.
Applied to files:
packages/lib/server/service/teamService.ts
apps/web/playwright/team/team-invitation.e2e.ts
📚 Learning: 2025-09-16T08:59:45.884Z
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-09-16T08:59:45.884Z
Learning: anglerfishlyy's PR #23467 demonstrates excellent software architecture with proper email validation (regex + zod), secure token generation using randomBytes, comprehensive host type system using discriminated unions (userId OR email), and smart reuse of existing team invitation infrastructure. The implementation includes robust error handling, type safety, and maintains backward compatibility while adding CreatableSelect-based email invitation functionality.
Applied to files:
packages/lib/server/service/teamService.ts
apps/web/playwright/team/team-invitation.e2e.ts
📚 Learning: 2025-07-28T11:50:23.946Z
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: Applies to **/*.ts : For Prisma queries, only select data you need; never use `include`, always use `select`
Applied to files:
packages/lib/server/service/teamService.ts
📚 Learning: 2025-08-07T18:42:34.081Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/lib/server/repository/PrismaPhoneNumberRepository.ts:412-417
Timestamp: 2025-08-07T18:42:34.081Z
Learning: In Cal.com codebase, the coding guideline requiring explicit `select` clauses instead of `include` for Prisma queries applies to read operations but not to update operations. Update operations don't need explicit select clauses.
Applied to files:
packages/lib/server/service/teamService.ts
🧬 Code graph analysis (1)
apps/web/playwright/team/team-invitation.e2e.ts (1)
apps/web/playwright/lib/localize.ts (1)
localize
(4-11)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (2)
packages/lib/server/service/teamService.ts (2)
241-246
: Limit team fields returned when accepting membershipWe still pull the full team object here. Please tighten the selection to the fields actually used (
id
,parentId
,isOrganization
) so we stay compliant with the Prisma query policy.As per coding guidelines
- select: { - team: true, - }, + select: { + team: { + select: { + id: true, + parentId: true, + isOrganization: true, + }, + }, + },
281-284
: Also narrow the team shape when deleting membershipSame concern in the removal path: only
parentId
andid
are referenced later, so please trim this selection too.As per coding guidelines
- const membership = await prisma.membership.delete({ + const membership = await prisma.membership.delete({ where: { userId_teamId: { userId, teamId }, }, select: { - team: true, + team: { + select: { + id: true, + parentId: true, + }, + }, }, });
E2E results are ready! |
What does this PR do?
This PR implements auto-accept functionality for team invitations sent to existing Cal.com users. When an existing user clicks the "Accept Invite" button in their invitation email, the invitation is automatically accepted and they are redirected to the
/teams
page, eliminating the need for manual acceptance.