refactor: circular deps between app store and lib [4]#23829
Conversation
WalkthroughThis PR systematically updates import paths across the repository, moving many symbols from monolithic modules (e.g., Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 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)
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
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 (13)
packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts (2)
53-57: Prisma: useselectand avoidinclude(policy requirement)Limit fetched fields and replace
includewithselect.Apply:
- const memberships = await prisma.membership.findMany({ - where: { - teamId: input.teamId, - }, - }); + const memberships = await prisma.membership.findMany({ + where: { teamId: input.teamId }, + select: { id: true, userId: true, role: true, accepted: true }, + });- const updatedMembership = await prisma.membership.findUnique({ - where: { - userId_teamId: { userId: input.memberId, teamId: input.teamId }, - }, - include: { - team: true, - user: true, - }, - }); + const updatedMembership = await prisma.membership.findUnique({ + where: { userId_teamId: { userId: input.memberId, teamId: input.teamId } }, + select: { + id: true, + role: true, + accepted: true, + team: { select: { id: true, name: true, slug: true } }, + user: { select: { id: true, name: true, username: true, avatarUrl: true } }, + }, + });Also applies to: 106-115
53-63: Avoid full-table fetch for role checksFetching all memberships to derive ownership and targets is heavier than needed. Prefer targeted lookups (findUnique for
targetMembershipandmyMembership) andcountfor owners.Example:
findUnique({ where: { userId_teamId } , select: { id, role, accepted } })for both userscount({ where: { teamId, role: OWNER } })for owner cardinalitypackages/trpc/server/routers/viewer/organizations/utils.ts (1)
81-83: AsyncforEachdoesn’t await — updates may be dropped
Array.forEachignores the returned promises; the handler may return before event types are updated.Apply:
- membershipData.forEach(async ({ userId, teamId }) => { - await updateNewTeamMemberEventTypes(userId, teamId); - }); + await Promise.all( + membershipData.map(({ userId, teamId }) => + updateNewTeamMemberEventTypes(userId, teamId) + ) + );packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts (1)
24-33: Authorization gap: restrict deletion to the specified team’s event typesCurrent
deleteManycan remove hosts from event types outsideteamIdif those IDs are provided. Constrain by relation to the team.Apply:
return await prisma.host.deleteMany({ where: { - eventTypeId: { - in: eventTypeIds, - }, + eventTypeId: { in: eventTypeIds }, + // Ensure these event types belong to the authorized team + eventType: { teamId }, userId: { in: userIds, }, }, });apps/web/lib/team/[slug]/getServerSideProps.tsx (1)
118-138: Potential data leakage + Prisma policy: avoidinclude, return only safe fieldsThis path returns a raw Team from Prisma (plus
createdAt: null), risking exposure of fields likeinviteTokenor other internals. Replaceincludewith a minimalselectand return a sanitized object.Apply:
- const unpublishedTeam = await prisma.team.findFirst({ - where: { - metadata: { - path: ["requestedSlug"], - equals: slug, - }, - }, - include: { - parent: { - select: { - id: true, - slug: true, - name: true, - isPrivate: true, - isOrganization: true, - metadata: true, - logoUrl: true, - }, - }, - }, - }); + const unpublishedTeam = await prisma.team.findFirst({ + where: { + metadata: { path: ["requestedSlug"], equals: slug }, + }, + select: { + id: true, + name: true, + slug: true, + bio: true, + isPrivate: true, + isOrganization: true, + metadata: true, + logoUrl: true, + parent: { + select: { + id: true, + slug: true, + name: true, + isPrivate: true, + isOrganization: true, + metadata: true, + logoUrl: true, + }, + }, + }, + }); @@ - return { - props: { - considerUnpublished: true, - team: { - ...unpublishedTeam, - parent: teamParent, - createdAt: null, - }, - }, - } as const; + const safeUnpublishedTeam = { + ...unpublishedTeam, + parent: teamParent, + // ensure sensitive fields never leak + inviteToken: undefined, + createdAt: null, + }; + return { props: { considerUnpublished: true, team: safeUnpublishedTeam } } as const;Also applies to: 140-151
packages/trpc/server/routers/viewer/teams/get.handler.test.ts (1)
15-17: Mocks target the old module path — tests won’t stub the actual importYou import
getTeamWithoutMembersfrom the EE path (Line 3) but mock the legacy path here, so calls won’t be mocked.Apply:
-vi.mock("@calcom/lib/server/queries/teams", () => ({ +vi.mock("@calcom/features/ee/teams/lib/queries", () => ({ getTeamWithoutMembers: vi.fn(), }));packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts (2)
36-41: Avoid fetching sensitive credentials; restrict nested fields with select.Don’t pull user.credentials here; it’s unused and risky. Use nested select to return only what you need.
Apply this diff:
- user: { - include: { - destinationCalendar: true, - credentials: true, - }, - }, + user: { + select: { + destinationCalendar: true, + }, + },
95-113: Prefer select over include (Prisma).Return only the attendee fields used downstream.
Apply this diff:
- include: { - attendees: true, - }, + select: { + attendees: { + select: { name: true, email: true, timeZone: true, locale: true }, + }, + },packages/trpc/server/routers/viewer/teams/createInvite.handler.ts (1)
37-46: Token expiry is computed incorrectly; do not use setHours for date math.setHours(168) sets absolute hours with overflow, not “+168 hours from now”.
Apply this diff:
await prisma.verificationToken.create({ data: { identifier: `invite-link-for-teamId-${teamId}`, token, - expires: new Date(new Date().setHours(168)), // +1 week, + expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // +1 week expiresInDays: 7, teamId, }, });packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts (2)
24-27: Use select instead of include and limit returned fields.Only parentId/isOrganization/id are used.
Apply this diff:
- include: { - team: true, - }, + select: { + team: { select: { id: true, parentId: true, isOrganization: true } }, + },
65-68: Use select instead of include for delete path as well.Only parentId is needed after deletion.
Apply this diff:
- include: { - team: true, - }, + select: { + team: { select: { parentId: true } }, + },packages/trpc/server/routers/viewer/teams/publish.handler.ts (1)
56-61: Critical: add missing await to isOrganisationAdmin — auth bypassisOrganisationAdmin is async (export async function in packages/lib/server/queries/organisations/index.ts); the call in packages/trpc/server/routers/viewer/teams/publish.handler.ts (lines 56–61) is missing await, which makes the authorization check ineffective.
- if (profile?.organizationId && !isOrganisationAdmin(ctx.user.id, profile.organizationId)) + if (profile?.organizationId && !(await isOrganisationAdmin(ctx.user.id, profile.organizationId))) throw new TRPCError({ code: "UNAUTHORIZED" });Also verify other call sites of isOrganisationAdmin are awaited.
packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts (1)
32-35: Fix zero-day handling and enforce schema validation
- Bug: expiresInDays is checked truthily so 0 becomes "never expire" — use a nullish check. Apply this diff:
- const expires = expiresInDays - ? new Date(Date.now() + expiresInDays * oneDay) - : new Date("9999-12-31T23:59:59Z"); //maximum possible date incase the link is set to never expire + const hasFiniteDuration = expiresInDays !== null && expiresInDays !== undefined; + const expires = hasFiniteDuration + ? new Date(Date.now() + expiresInDays * oneDay) + : new Date("9999-12-31T23:59:59Z"); // maximum possible date in case the link is set to never expire @@ - expiresInDays: expiresInDays ? expiresInDays : null, + expiresInDays: hasFiniteDuration ? expiresInDays : null,
- Schema: packages/trpc/server/routers/viewer/teams/setInviteExpiration.schema.ts currently has
expiresInDays: z.number().optional()(no non-negative/int enforcement). Change to enforce integers >= 0, e.g.z.number().int().nonnegative().optional()(or.int().min(0).optional()), and confirm whether0should mean immediate expiry or be rejected.
🧹 Nitpick comments (14)
packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts (1)
28-32: Update the mock path to match the new import location.The mock is still pointing to the old import path
@calcom/lib/server/queries/teamswhile the actual import has been moved to@calcom/features/ee/teams/lib/queries. This could cause test failures.Apply this diff to fix the mock path:
-vi.mock("@calcom/lib/server/queries/teams", () => { +vi.mock("@calcom/features/ee/teams/lib/queries", () => { return { isTeamAdmin: vi.fn(), }; });packages/trpc/server/routers/viewer/teams/deleteInvite.handler.ts (1)
36-36: Prefer named export over default exportAdopt named exports for better tree-shaking and refactors.
Apply:
-export default deleteInviteHandler; +export { deleteInviteHandler };packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts (1)
120-120: Prefer named export over default export-export default changeMemberRoleHandler; +export { changeMemberRoleHandler };packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts (1)
36-36: Prefer named export over default export-export default removeHostsFromEventTypesHandler; +export { removeHostsFromEventTypesHandler };packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts (1)
33-33: Prefer named export over default export-export default getInternalNotesPresetsHandler; +export { getInternalNotesPresetsHandler };packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts (1)
177-181: Log the error object for observability.Currently the actual error is dropped.
Apply this diff:
- } catch (err) { - console.log("Error sending AddGuestsEmails"); - } + } catch (err) { + console.error("Error sending AddGuestsEmails", err); + }packages/trpc/server/routers/viewer/teams/delete.handler.ts (1)
22-22: Prefer named exports over default exports.Improves tree‑shaking and refactors. Consider removing the default export and updating imports.
-export default deleteHandler; +// Use the named export `deleteHandler` at call sites instead of default export.packages/trpc/server/routers/viewer/teams/publish.handler.ts (3)
22-29: Dead code: parseMetadataOrThrow is unused.Remove to reduce noise.
30-53: Dead code: generateCheckoutSession is unused.Remove or wire into publish flow behind billing flag.
84-84: Prefer named exports over default exports.Use named export publishHandler and drop the default export.
-export default publishHandler; +// Use the named export `publishHandler` at call sites instead of default export.packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts (1)
41-41: Prefer named exports over default exports.Drop default export to align with repo guidance.
-export default addMembersToEventTypesHandler; +// Use the named export `addMembersToEventTypesHandler` at call sites instead of default export.packages/trpc/server/routers/viewer/teams/createInvite.handler.ts (1)
58-58: Prefer named exports over default exports.Drop default export to align with guidance.
-export default createInviteHandler; +// Use the named export `createInviteHandler` at call sites instead of default export.packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts (1)
83-83: Prefer named exports over default exports.Drop default export.
-export default acceptOrLeaveHandler; +// Use the named export `acceptOrLeaveHandler` at call sites instead of default export.packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts (1)
29-30: Use FORBIDDEN for permission failures (user is authenticated).UNAUTHORIZED suggests missing auth; this case is authenticated-but-not-allowed.
Apply:
- if (!verificationToken.teamId || !(await isTeamAdmin(ctx.user.id, verificationToken.teamId))) - throw new TRPCError({ code: "UNAUTHORIZED" }); + if (!verificationToken.teamId || !(await isTeamAdmin(ctx.user.id, verificationToken.teamId))) + throw new TRPCError({ code: "FORBIDDEN" });
📜 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 (32)
apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsx(1 hunks)apps/web/components/team/screens/Team.tsx(1 hunks)apps/web/lib/team/[slug]/getServerSideProps.tsx(1 hunks)packages/features/auth/signup/utils/createOrUpdateMemberships.ts(1 hunks)packages/features/auth/signup/utils/organization.ts(1 hunks)packages/features/ee/dsync/lib/handleGroupEvents.ts(1 hunks)packages/features/ee/sso/lib/saml.ts(1 hunks)packages/features/ee/teams/lib/queries.ts(1 hunks)packages/features/pbac/services/role-management.factory.ts(1 hunks)packages/platform/libraries/event-types.ts(1 hunks)packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts(1 hunks)packages/trpc/server/routers/viewer/me/updateProfile.handler.ts(1 hunks)packages/trpc/server/routers/viewer/organizations/utils.ts(1 hunks)packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/createInvite.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/delete.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/deleteInvite.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/get.handler.test.ts(1 hunks)packages/trpc/server/routers/viewer/teams/get.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts(1 hunks)packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts(1 hunks)packages/trpc/server/routers/viewer/teams/publish.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/removeMember.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/update.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.ts(1 hunks)packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/trpc/server/routers/viewer/teams/delete.handler.tspackages/trpc/server/routers/viewer/teams/update.handler.tspackages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.tspackages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.tspackages/trpc/server/routers/viewer/teams/changeMemberRole.handler.tspackages/trpc/server/routers/viewer/teams/publish.handler.tspackages/trpc/server/routers/viewer/teams/deleteInvite.handler.tspackages/trpc/server/routers/viewer/teams/inviteMember/utils.tspackages/features/pbac/services/role-management.factory.tspackages/features/auth/signup/utils/organization.tspackages/features/ee/dsync/lib/handleGroupEvents.tspackages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.tspackages/features/ee/sso/lib/saml.tspackages/trpc/server/routers/viewer/bookings/addGuests.handler.tspackages/trpc/server/routers/viewer/teams/removeMember.handler.tspackages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.tspackages/trpc/server/routers/viewer/teams/get.handler.tspackages/trpc/server/routers/viewer/organizations/utils.tspackages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.tspackages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.tspackages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.tspackages/trpc/server/routers/viewer/me/updateProfile.handler.tspackages/platform/libraries/event-types.tspackages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.tspackages/features/auth/signup/utils/createOrUpdateMemberships.tspackages/features/ee/teams/lib/queries.tspackages/trpc/server/routers/viewer/teams/createInvite.handler.tspackages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.tspackages/trpc/server/routers/viewer/teams/get.handler.test.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/delete.handler.tspackages/trpc/server/routers/viewer/teams/update.handler.tspackages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.tspackages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.tspackages/trpc/server/routers/viewer/teams/changeMemberRole.handler.tspackages/trpc/server/routers/viewer/teams/publish.handler.tspackages/trpc/server/routers/viewer/teams/deleteInvite.handler.tspackages/trpc/server/routers/viewer/teams/inviteMember/utils.tspackages/features/pbac/services/role-management.factory.tspackages/features/auth/signup/utils/organization.tspackages/features/ee/dsync/lib/handleGroupEvents.tspackages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.tspackages/features/ee/sso/lib/saml.tspackages/trpc/server/routers/viewer/bookings/addGuests.handler.tspackages/trpc/server/routers/viewer/teams/removeMember.handler.tspackages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.tspackages/trpc/server/routers/viewer/teams/get.handler.tspackages/trpc/server/routers/viewer/organizations/utils.tspackages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.tspackages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.tsapps/web/lib/team/[slug]/getServerSideProps.tsxpackages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.tsapps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsxpackages/trpc/server/routers/viewer/me/updateProfile.handler.tspackages/platform/libraries/event-types.tsapps/web/components/team/screens/Team.tsxpackages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.tspackages/features/auth/signup/utils/createOrUpdateMemberships.tspackages/features/ee/teams/lib/queries.tspackages/trpc/server/routers/viewer/teams/createInvite.handler.tspackages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.tspackages/trpc/server/routers/viewer/teams/get.handler.test.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/delete.handler.tspackages/trpc/server/routers/viewer/teams/update.handler.tspackages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.tspackages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.tspackages/trpc/server/routers/viewer/teams/changeMemberRole.handler.tspackages/trpc/server/routers/viewer/teams/publish.handler.tspackages/trpc/server/routers/viewer/teams/deleteInvite.handler.tspackages/trpc/server/routers/viewer/teams/inviteMember/utils.tspackages/features/pbac/services/role-management.factory.tspackages/features/auth/signup/utils/organization.tspackages/features/ee/dsync/lib/handleGroupEvents.tspackages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.tspackages/features/ee/sso/lib/saml.tspackages/trpc/server/routers/viewer/bookings/addGuests.handler.tspackages/trpc/server/routers/viewer/teams/removeMember.handler.tspackages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.tspackages/trpc/server/routers/viewer/teams/get.handler.tspackages/trpc/server/routers/viewer/organizations/utils.tspackages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.tspackages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.tsapps/web/lib/team/[slug]/getServerSideProps.tsxpackages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.tsapps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsxpackages/trpc/server/routers/viewer/me/updateProfile.handler.tspackages/platform/libraries/event-types.tsapps/web/components/team/screens/Team.tsxpackages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.tspackages/features/auth/signup/utils/createOrUpdateMemberships.tspackages/features/ee/teams/lib/queries.tspackages/trpc/server/routers/viewer/teams/createInvite.handler.tspackages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.tspackages/trpc/server/routers/viewer/teams/get.handler.test.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/lib/team/[slug]/getServerSideProps.tsxapps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsxapps/web/components/team/screens/Team.tsx
🧠 Learnings (10)
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
packages/trpc/server/routers/viewer/teams/update.handler.tspackages/trpc/server/routers/viewer/teams/publish.handler.tspackages/trpc/server/routers/viewer/me/updateProfile.handler.tspackages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.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/setInviteExpiration.handler.tspackages/trpc/server/routers/viewer/teams/inviteMember/utils.tspackages/features/auth/signup/utils/organization.tspackages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.tspackages/trpc/server/routers/viewer/teams/createInvite.handler.ts
📚 Learning: 2025-08-26T20:23:28.396Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:83-88
Timestamp: 2025-08-26T20:23:28.396Z
Learning: In calcom/cal.com PR #22995, the workflow update handler in packages/trpc/server/routers/viewer/workflows/update.handler.ts includes workflow-level authorization via isAuthorized(userWorkflow, ctx.user.id, "workflow.update") which validates the user can update the workflow before calling updateToolsFromAgentId (per maintainer Udit-takkar).
Applied to files:
packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
📚 Learning: 2025-09-12T07:15:58.030Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.030Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
📚 Learning: 2025-08-26T08:08:23.395Z
Learnt from: SinghaAnirban005
PR: calcom/cal.com#23343
File: packages/features/insights/server/trpc-router.ts:1080-1101
Timestamp: 2025-08-26T08:08:23.395Z
Learning: In packages/features/insights/server/trpc-router.ts, when filtering personal event types (userId provided, no teamId, not isAll), the query correctly uses user.id (authenticated user) instead of the input userId parameter for security reasons. This prevents users from accessing other users' personal event types by passing arbitrary user IDs.
Applied to files:
packages/trpc/server/routers/viewer/teams/publish.handler.tspackages/trpc/server/routers/viewer/teams/inviteMember/utils.tspackages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.tspackages/trpc/server/routers/viewer/organizations/utils.tspackages/trpc/server/routers/viewer/me/updateProfile.handler.tspackages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts
📚 Learning: 2025-08-05T07:42:06.335Z
Learnt from: sean-brydon
PR: calcom/cal.com#22618
File: packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts:113-113
Timestamp: 2025-08-05T07:42:06.335Z
Learning: In Cal.com's getUserEventGroups handler refactor (PR #22618), the membershipCount field for team event groups is intentionally set to 0 in the new createTeamEventGroup function, as confirmed by sean-brydon (PR author). This preserves the same behavior as the old implementation that was being refactored, maintaining backward compatibility. While other parts of the codebase may use actual member counts, this specific implementation maintains the previous behavior.
Applied to files:
packages/features/ee/dsync/lib/handleGroupEvents.tspackages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.tspackages/features/auth/signup/utils/createOrUpdateMemberships.ts
📚 Learning: 2025-08-05T07:42:06.335Z
Learnt from: sean-brydon
PR: calcom/cal.com#22618
File: packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts:113-113
Timestamp: 2025-08-05T07:42:06.335Z
Learning: In Cal.com's event type system, the membershipCount field for team event groups is intentionally set to 0, as confirmed by sean-brydon (PR author). This behavior was preserved during the refactor from the old getUserEventGroups.handler.ts implementation to the new createTeamEventGroup function in transformUtils.ts. This is not a bug but the intended behavior that maintains consistency with the previous implementation.
Applied to files:
packages/features/ee/dsync/lib/handleGroupEvents.ts
📚 Learning: 2025-08-29T22:57:31.407Z
Learnt from: bandhan-majumder
PR: calcom/cal.com#23454
File: packages/features/bookings/Booker/components/EventMeta.tsx:16-16
Timestamp: 2025-08-29T22:57:31.407Z
Learning: In Cal.com's Booker architecture, components become client-side through BookerStoreProvider.tsx which has "use client". Any component using useBookerStoreContext automatically runs on the client and should use client-appropriate utilities like markdownToSafeHTMLClient, regardless of whether they have explicit "use client" directives.
Applied to files:
apps/web/lib/team/[slug]/getServerSideProps.tsx
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/platform/libraries/event-types.tspackages/features/auth/signup/utils/createOrUpdateMemberships.tspackages/features/ee/teams/lib/queries.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
packages/trpc/server/routers/viewer/teams/createInvite.handler.ts
⏰ 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 (33)
apps/web/components/team/screens/Team.tsx (1)
6-6: LGTM! Import path correctly updated to EE module.The import path has been properly updated to point to the EE-specific teams queries module. This aligns with the PR's objective to consolidate team-related functionality into the Enterprise Edition module structure.
packages/trpc/server/routers/viewer/teams/removeMember.handler.ts (1)
5-5: LGTM! Import path correctly updated to EE module.The import path for
isTeamOwnerhas been properly updated to point to the EE-specific teams queries module, maintaining consistency with the broader refactoring effort in this PR.packages/features/ee/sso/lib/saml.ts (1)
4-4: LGTM! Import path correctly updated to EE module.The import path for
isTeamAdminhas been properly updated to point to the EE-specific teams queries module, which is consistent with the PR's refactoring pattern.packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts (1)
4-4: LGTM! Import path correctly updated to EE module.The import path for
isTeamAdminhas been properly updated to point to the EE-specific teams queries module, maintaining consistency with the broader refactoring effort.packages/features/ee/dsync/lib/handleGroupEvents.ts (1)
6-6: LGTM! Import path correctly updated to EE module.The import path for
addNewMembersToEventTypeshas been properly updated to point to the EE-specific teams queries module, maintaining consistency with the broader refactoring effort.apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsx (1)
14-14: LGTM! Import path correctly updated to EE module.The import path for
getTeamWithMembershas been properly updated to point to the EE-specific teams queries module, which aligns with the PR's objective to migrate team-related functionality to the Enterprise Edition module structure.packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts (1)
14-15: LGTM! Import paths correctly updated to EE module.Both import paths for
updateNewTeamMemberEventTypesandisTeamAdminhave been properly updated to point to the EE-specific teams queries module, maintaining consistency with the broader refactoring effort in this PR.packages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.ts (1)
1-1: LGTM! Import path correctly updated to EE module.The import path for
isTeamAdminhas been properly updated to point to the EE-specific teams queries module, which is consistent with the PR's refactoring pattern.packages/trpc/server/routers/viewer/teams/update.handler.ts (1)
6-6: Import path correctly updated to EE module.The relocation of
isTeamAdminimport to the Enterprise Edition module is consistent with the broader refactoring effort. The function call at line 28 remains functionally identical.packages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.ts (1)
3-3: Import path migration to EE module completed successfully.The
isTeamMemberfunction import has been correctly moved to the Enterprise Edition queries module. The usage pattern at line 20 and subsequent logic remain unchanged.packages/features/pbac/services/role-management.factory.ts (1)
3-3: PBAC role management now uses EE team queries.The
isTeamAdminimport migration to the Enterprise Edition module is appropriate for the Permission-Based Access Control (PBAC) system, ensuring team admin checks use the centralized EE implementation.packages/trpc/server/routers/viewer/teams/get.handler.ts (1)
1-1: Team query import successfully migrated to EE module.The
getTeamWithoutMembersfunction import has been properly relocated to the Enterprise Edition queries module. The function call at line 29 maintains the same signature and behavior.packages/platform/libraries/event-types.ts (1)
28-28: Platform library re-export updated to EE source.The
updateNewTeamMemberEventTypesre-export now correctly references the Enterprise Edition queries module, ensuring the platform API maintains consistency with the team management migration.packages/features/auth/signup/utils/createOrUpdateMemberships.ts (1)
1-1: Signup utilities now use EE team event types management.The
updateNewTeamMemberEventTypesimport has been appropriately moved to the Enterprise Edition module. The function call at line 87 maintains the same parameters and behavior during the membership creation transaction.packages/features/ee/teams/lib/queries.ts (1)
5-5: Import paths standardized to absolute aliases.The migration from relative imports to absolute alias imports improves maintainability and consistency:
getBookerBaseUrlSyncfrom relative to@calcom/lib/getBookerUrl/clientgetTeamandgetOrgfrom relative to@calcom/lib/server/repository/teamUserRepositoryfrom relative to@calcom/lib/server/repository/userEventTypeSchemaimport relocated for better organizationThese changes maintain the same runtime behavior while improving code organization.
Also applies to: 9-10, 22-22
packages/trpc/server/routers/viewer/teams/deleteInvite.handler.ts (1)
1-1: Import relocation + minimal Prisma select look goodEE path swap is fine, and the verificationToken query uses a minimal
select, aligning with our Prisma guidelines.Also applies to: 19-27
packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts (1)
2-2: Import relocation LGTMNo behavior change; authorization guard with
isTeamMemberremains intact.packages/trpc/server/routers/viewer/organizations/utils.ts (1)
2-2: Import relocation LGTMSwitch to EE path is consistent with the PR’s direction.
packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts (1)
1-1: Import relocation LGTMMatches the EE migration.
apps/web/lib/team/[slug]/getServerSideProps.tsx (1)
14-14: Import relocation LGTMMove to EE queries is consistent and non-functional.
packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts (1)
1-1: Import relocation + least-privilegeselectlook goodEE path switch is fine, and the query returns only necessary fields.
Also applies to: 21-30
packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts (1)
7-7: Import source migration looks good.EE module path aligns with the PR’s refactor.
packages/trpc/server/routers/viewer/teams/delete.handler.ts (1)
1-1: Import source migration looks good.packages/trpc/server/routers/viewer/teams/publish.handler.ts (1)
5-5: Import source migration looks good.packages/trpc/server/routers/viewer/me/updateProfile.handler.ts (1)
15-15: Import source migration looks good.No functional change; rest of handler already adheres to Prisma select best practices.
packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts (1)
1-1: Import source migration looks good.packages/features/auth/signup/utils/organization.ts (1)
1-1: Import source migration looks good.packages/trpc/server/routers/viewer/teams/createInvite.handler.ts (1)
4-4: Import source migration looks good.packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts (1)
2-2: Import source migration looks good.packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts (4)
19-26: Good Prisma usage: minimal select and no include.Only teamId is selected; aligned with our Prisma guideline to select only required fields.
16-18: Guard CAL-3076 email-invite flow behavior.Given the prior CAL-3076 email invitation work (pending members, teamInvite), please sanity-check that changing the import path for isTeamAdmin doesn’t affect invite-expiration updates for pending-email hosts.
46-46: Prefer named export; avoid default exportsChange the default export to a named export for better tree‑shaking and refactor safety; update any import sites.
File: packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts
-export default setInviteExpirationHandler; +export { setInviteExpirationHandler };Locate usages (examples):
rg -n --hidden -S "import\s+setInviteExpirationHandler\s+from" -g '!node_modules'
rg -n --hidden -S "\bsetInviteExpirationHandler\b" -g '!node_modules'
1-1: EE import migration verified — no remaining @calcom/lib/server/queries/teams imports.All isTeamAdmin imports now reference @calcom/features/ee/teams/lib/queries; tsconfig* contains @calcom/features and @calcom/features/* path mappings (-> ../../features).
| @@ -1 +0,0 @@ | |||
| export * from "@calcom/app-store/locations"; | |||
There was a problem hiding this comment.
Rather, we now import directly from app-store
There was a problem hiding this comment.
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 (7)
packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts (2)
104-105: Bug: returning undefined appsStatusYou set evt.appsStatus but return newBooking.appsStatus, which is never set.
Apply:
- return { ...foundBooking, appsStatus: newBooking.appsStatus }; + return { ...foundBooking, appsStatus: evt.appsStatus };
34-49: Use Prisma select, not includeReplace include with a minimal select per our guideline; also drop unused relations (e.g., payment) if not required by downstream code.
Example shape:
- const newBooking: (Booking & { appsStatus?: AppsStatus[] }) | null = await prisma.booking.update({ + const newBooking: Booking & { appsStatus?: AppsStatus[] } = await prisma.booking.update({ where: { id: seatedBooking.id }, - data: { ... }, - include: { - user: true, - references: true, - payment: true, - attendees: true, - }, + data: { /* unchanged */ }, + select: { + id: true, + references: true, + // add only fields actually used later (e.g., attendees if needed by handleAppsStatus) + }, });packages/features/ee/round-robin/roundRobinReassignment.ts (1)
344-355: Prisma include → selectPer guideline, avoid include; select only fields needed (and avoid credential.key).
Example:
- const credentials = await prisma.credential.findMany({ + const credentials = await prisma.credential.findMany({ where: { userId: organizer.id }, - include: { - user: { - select: { email: true }, - }, - }, + select: { + id: true, + type: true, + // ...other fields required by enrichUserWithDelegationCredentialsIncludeServiceAccountKey + user: { select: { email: true } }, + }, });packages/lib/getConnectedDestinationCalendars.ts (2)
81-88: Use injected Prisma clientHelper uses the imported prisma, not the injected one. This breaks transaction scoping.
-async function handleNoConnectedCalendars(user: UserWithCalendars) { +async function handleNoConnectedCalendars(db: PrismaClient, user: UserWithCalendars) { log.debug(`No connected calendars, deleting destination calendar if it exists for user ${user.id}`); if (!user.destinationCalendar) return user; - await prisma.destinationCalendar.delete({ + await db.destinationCalendar.delete({ where: { userId: user.id }, });And call with the same client:
- user = await handleNoConnectedCalendars(user); + user = await handleNoConnectedCalendars(prisma, user);Repeat for handleDestinationCalendarNotInConnectedCalendars below.
165-173: Propagate db client to all helpersPass the injected PrismaClient into handleDestinationCalendarNotInConnectedCalendars and use it instead of the imported prisma.
-async function handleDestinationCalendarNotInConnectedCalendars({ +async function handleDestinationCalendarNotInConnectedCalendars({ user, connectedCalendars, onboarding, + db, }: { user: UserWithCalendars; connectedCalendars: ConnectedCalendarsFromGetConnectedCalendars; onboarding: boolean; + db: PrismaClient; }) { ... - user.destinationCalendar = await prisma.destinationCalendar.update({ + user.destinationCalendar = await db.destinationCalendar.update({ where: { userId: user.id }, data: { integration, externalId, primaryEmail }, });And at call site:
- await handleDestinationCalendarNotInConnectedCalendars({ + await handleDestinationCalendarNotInConnectedCalendars({ user, connectedCalendars, onboarding, - }) + db: prisma, + })Also applies to: 193-201, 316-321, 328-336
tests/libs/__mocks__/CalendarManager.ts (1)
6-13: Fix TDZ: CalendarManagerMock used before initialization.
CalendarManagerMockis referenced invi.mockandbeforeEachbefore it’s defined; this will throw at runtime. Move the declaration above.-import type * as CalendarManager from "@calcom/features/calendars/lib/CalendarManager"; - -vi.mock("@calcom/features/calendars/lib/CalendarManager", () => CalendarManagerMock); +import type * as CalendarManager from "@calcom/features/calendars/lib/CalendarManager"; + +const CalendarManagerMock = mockDeep<typeof CalendarManager>(); +vi.mock("@calcom/features/calendars/lib/CalendarManager", () => CalendarManagerMock); beforeEach(() => { mockReset(CalendarManagerMock); }); -const CalendarManagerMock = mockDeep<typeof CalendarManager>(); +// moved above to avoid TDZ export default CalendarManagerMock;packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts (1)
78-103: Use top-level Prisma select (not include) — but include all form scalar fields required downstream.Repo guideline: switch the findFirst to a top-level select, but the suggested replacement is incomplete and will break getSerializableForm/getEnrichedSerializableForm. Ensure the select includes at minimum: id, userId, name, description, routes, fields, settings, createdAt, updatedAt, teamId — and keep the nested selects for team.parent.slug and user.{id,username,movedToProfileId}.
File: packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts (the prisma.app_RoutingForms_Form.findFirst call).
🧹 Nitpick comments (23)
packages/features/eventtypes/lib/getEventTypeById.ts (5)
135-139: Guard getBookerBaseUrl against null/undefined org IDs.Currently
getBookerBaseUrl(currentOrganizationId)can be called withnullif the owner exists but the user isn’t in an org. Avoid passing null and fall back to WEBSITE_URL.- bookerUrl: restEventType.team - ? await getBookerBaseUrl(restEventType.team.parentId) - : restEventType.owner - ? await getBookerBaseUrl(currentOrganizationId) - : WEBSITE_URL, + bookerUrl: + restEventType.team?.parentId + ? await getBookerBaseUrl(restEventType.team.parentId) + : restEventType.owner && currentOrganizationId + ? await getBookerBaseUrl(currentOrganizationId) + : WEBSITE_URL,
245-253: Use explicit Prisma select for destinationCalendar to avoid overfetching.Per repo guidance, use
selectinstead of returning the full record. Also double‑check that no sensitive fields are exposed over tRPC.If acceptable for clients, add a constrained select (adjust keys to your model):
- destinationCalendar = await prisma.destinationCalendar.findFirst({ - where: { - userId: userId, - eventTypeId: null, - }, - }); + destinationCalendar = await prisma.destinationCalendar.findFirst({ + where: { userId, eventTypeId: null }, + // TODO: confirm exact fields required by consumers; expand only as needed. + select: { id: true, userId: true, eventTypeId: true, credentialId: true, integration: true, externalId: true, name: true, primaryEmail: true }, + });Optionally centralize:
const DESTINATION_CALENDAR_PUBLIC_SELECT = { id: true, userId: true, eventTypeId: true, credentialId: true, integration: true, externalId: true, name: true, primaryEmail: true, } satisfies Prisma.DestinationCalendarSelect;Then
select: DESTINATION_CALENDAR_PUBLIC_SELECT.
289-289: Remove default export; keep named export only.Matches the import recommendation and repo guideline against default exports.
-export default getEventTypeById;
131-131: Avoid double castas unknown as LocationObject[].Double casts mask type mismatches. Prefer a narrow helper or schema validation to ensure the shape at runtime.
Example:
function toLocationObjects(v: unknown): LocationObject[] { // validate/transform or return [] return Array.isArray(v) ? (v as LocationObject[]) : []; } ... locations: toLocationObjects(locations),
76-84: Parallelize sequential awaits to reduce latency.The three loops await inside iteration; switch to Promise.all maps.
- const eventTeamMembershipsWithUserProfile = []; - for (const eventTeamMembership of rawEventType.team?.members || []) { - eventTeamMembershipsWithUserProfile.push({ - ...eventTeamMembership, - user: await userRepo.enrichUserWithItsProfile({ - user: eventTeamMembership.user, - }), - }); - } + const eventTeamMembershipsWithUserProfile = await Promise.all( + (rawEventType.team?.members ?? []).map(async (m) => ({ + ...m, + user: await userRepo.enrichUserWithItsProfile({ user: m.user }), + })) + ); - const childrenWithUserProfile = []; - for (const child of rawEventType.children || []) { - childrenWithUserProfile.push({ - ...child, - owner: child.owner - ? await userRepo.enrichUserWithItsProfile({ - user: child.owner, - }) - : null, - }); - } + const childrenWithUserProfile = await Promise.all( + (rawEventType.children ?? []).map(async (child) => ({ + ...child, + owner: child.owner ? await userRepo.enrichUserWithItsProfile({ user: child.owner }) : null, + })) + ); - const eventTypeUsersWithUserProfile = []; - for (const eventTypeUser of rawEventType.users) { - eventTypeUsersWithUserProfile.push( - await userRepo.enrichUserWithItsProfile({ - user: eventTypeUser, - }) - ); - } + const eventTypeUsersWithUserProfile = await Promise.all( + rawEventType.users.map((u) => userRepo.enrichUserWithItsProfile({ user: u })) + );Also applies to: 86-96, 99-105
packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts (3)
34-41: Tighten types: update() never returns nullDrop the nullable type on newBooking and the follow‑on null assumptions.
Apply (already shown above) and rely on Prisma throwing on missing record.
Also applies to: 55-56
57-61: Duplicate logic: extract to helperThe “reset evt.description to eventType.description before emailing” pattern appears elsewhere; extract to a shared util to avoid drift.
107-107: Prefer named export over defaultSwitch to a named export for better tree‑shaking and refactors.
-export default moveSeatedBookingToNewTimeSlot; +export { moveSeatedBookingToNewTimeSlot };packages/lib/server/getLuckyUser.ts (2)
155-161: Return a boolean from isFullDayEventFunction currently returns true or undefined; make it explicit.
function isFullDayEvent(date1: Date, date2: Date) { const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; const difference = Math.abs(date1.getTime() - date2.getTime()); - if (difference % MILLISECONDS_IN_A_DAY === 0) return true; + return difference % MILLISECONDS_IN_A_DAY === 0; }
834-847: Reduce dayjs work inside loopThis runs per busy time; cache now/earliestStartTime outside, and use dayjs.tz directly to avoid repeated Date constructions.
- userBusyTimesOfInterval.forEach((userBusyTime) => { + const now = Date.now(); + const monthStartUtc = Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), 1); + userBusyTimesOfInterval.forEach((userBusyTime) => { const fullDayBusyTimes = userBusyTime.busyTimes .filter((busyTime) => { if (!busyTime.timeZone) return false; - const timezoneOffset = dayjs(busyTime.start).tz(busyTime.timeZone).utcOffset() * 60000; - let start = new Date(new Date(busyTime.start).getTime() + timezoneOffset); - const end = new Date(new Date(busyTime.end).getTime() + timezoneOffset); + const startLocal = dayjs.tz(busyTime.start, busyTime.timeZone); + const endLocal = dayjs.tz(busyTime.end, busyTime.timeZone); + let start = new Date(startLocal.valueOf()); + const end = new Date(endLocal.valueOf()); - const earliestStartTime = new Date(Date.UTC(new Date().getFullYear(), new Date().getMonth(), 1)); + const earliestStartTime = new Date(monthStartUtc); if (start < earliestStartTime) start = earliestStartTime; - return end.getTime() < new Date().getTime() && isFullDayEvent(start, end); + return end.getTime() < now && isFullDayEvent(start, end); })packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts (1)
56-56: Prefer named export over defaultAlign with repo guidance on named exports.
-export default ownerRescheduleSeatedBooking; +export { ownerRescheduleSeatedBooking };packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts (1)
152-158: Remove unused variablecalendarMock is unused; drop it to keep tests lean.
- const calendarMock = mockCalendarToHaveNoBusySlots("googlecalendar", { + mockCalendarToHaveNoBusySlots("googlecalendar", { create: { id: "MOCKED_GOOGLE_CALENDAR_EVENT_ID", iCalUID: "MOCKED_GOOGLE_CALENDAR_ICS_ID", }, });packages/features/ee/round-robin/roundRobinReassignment.ts (1)
508-508: Prefer named export over defaultSwitch to a named export for consistency.
-export default roundRobinReassignment; +export { roundRobinReassignment };packages/lib/getConnectedDestinationCalendars.ts (1)
236-241: Avoid console.log in library codeUse logger.debug for consistency.
- console.log( - `Upsert the selectedCalendar record to the DB for user ${user.id} with details ${JSON.stringify( - selectedCalendar - )}` - ); + log.debug( + `Upserting selectedCalendar for user ${user.id}: ${JSON.stringify(selectedCalendar)}` + );packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts (1)
44-58: Typo: Inavlid → InvalidRename for clarity.
- const appsWithInavlidCredentials = checkInvalidAppCredentials({ ctx }); + const appsWithInvalidCredentials = checkInvalidAppCredentials({ ctx }); ... - appsWithInavlidCredentials, + appsWithInvalidCredentials, ... - invalidAppCredentialBanners.status === "fulfilled" ? invalidAppCredentialBanners.value : [], + invalidAppCredentialBanners.status === "fulfilled" ? invalidAppCredentialBanners.value : [],Also applies to: 60-67
packages/features/ee/round-robin/roundRobinReassignment.test.ts (1)
163-166: Tests call function without required argsroundRobinReassignment requires orgId and reassignedById; tests pass only bookingId. Either make these params optional with safe defaults or update tests to pass them.
Quick test fix:
- await roundRobinReassignment({ - bookingId: 123, - }); + await roundRobinReassignment({ + bookingId: 123, + orgId: null, + reassignedById: 0, + });Also applies to: 273-276
packages/features/bookings/lib/handleCancelBooking.ts (1)
232-236: Micro: limit Prisma fields to what’s used.Only
organizationIdis read later; select it explicitly to avoid fetching the full profile.- const ownerProfile = await prisma.profile.findFirst({ - where: { - userId: bookingToDelete.userId, - }, - }); + const ownerProfile = await prisma.profile.findFirst({ + where: { userId: bookingToDelete.userId }, + select: { organizationId: true }, + });packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts (1)
81-88: Use Vitest typings instead of Jest cast.Prefer
vi.mocked(getConnectedCalendars)over(getConnectedCalendars as jest.Mock).- // Mock the getConnectedCalendars response - (getConnectedCalendars as jest.Mock).mockResolvedValue({ + // Mock the getConnectedCalendars response + vi.mocked(getConnectedCalendars).mockResolvedValue({ connectedCalendars: [ {packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts (1)
291-293: Use logger instead of console.log.Keep logging consistent and structured.
- } catch (error) { - console.log("Error sending LocationChangeEmails", safeStringify(error)); - } + } catch (error) { + logger.error("Error sending LocationChangeEmails", safeStringify(error)); + }packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts (1)
71-79: Trim blacklisted emails to avoid false mismatches.Environment lists often contain spaces; normalize input.
- const blacklistedGuestEmails = process.env.BLACKLISTED_GUEST_EMAILS - ? process.env.BLACKLISTED_GUEST_EMAILS.split(",").map((email) => email.toLowerCase()) + const blacklistedGuestEmails = process.env.BLACKLISTED_GUEST_EMAILS + ? process.env.BLACKLISTED_GUEST_EMAILS.split(",").map((email) => email.trim().toLowerCase()) : [];packages/features/bookings/lib/EventManager.ts (1)
135-135: Prefer named exports over default for libraries.Default exports make refactors harder and reduce tree‑shaking. Consider switching to a named export in a follow‑up.
-export default class EventManager { +export class EventManager {Note: would require updating import sites; do in a dedicated PR.
packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts (1)
304-309: Avoid unconditional console.log in request path.Log only when _enablePerf is true or use the structured logger at debug level.
Apply:
- console.log("_enablePerf, _concurrency", _enablePerf, _concurrency); - if (_enablePerf) { + if (_enablePerf) { + console.debug("_enablePerf, _concurrency", _enablePerf, _concurrency); const serverTimingHeader = getServerTimingHeader(timeTaken); ctx.res?.setHeader("Server-Timing", serverTimingHeader); - console.log("Server-Timing", serverTimingHeader); + console.debug("Server-Timing", serverTimingHeader); }packages/features/webhooks/lib/scheduleTrigger.ts (1)
80-92: Prisma: prefer select over include per repo guidelines.Switch include to select and enumerate only needed fields to reduce payloads and comply with the “never use include” rule for Prisma.
If changing the selection alters the payload saved in webhookScheduledTriggers, gate behind a migration or keep shape compatible.
📜 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 (51)
apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts(1 hunks)apps/api/v1/pages/api/destination-calendars/_post.ts(1 hunks)apps/api/v1/test/lib/bookings/_post.test.ts(1 hunks)apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts(1 hunks)apps/web/app/api/availability/calendar/route.ts(1 hunks)apps/web/components/apps/installation/ConfigureStepCard.tsx(1 hunks)apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts(1 hunks)apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts(1 hunks)apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx(1 hunks)apps/web/modules/apps/installation/[[...step]]/step-view.tsx(1 hunks)packages/app-store/_utils/payments/handlePaymentSuccess.ts(1 hunks)packages/features/bookings/lib/EventManager.ts(1 hunks)packages/features/bookings/lib/handleCancelBooking.ts(1 hunks)packages/features/bookings/lib/handleConfirmation.ts(1 hunks)packages/features/bookings/lib/handleNewBooking.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts(1 hunks)packages/features/bookings/lib/handleSeats/create/createNewSeat.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts(1 hunks)packages/features/calendars/lib/CalendarManager.ts(1 hunks)packages/features/credentials/handleDeleteCredential.ts(1 hunks)packages/features/ee/payments/api/webhook.ts(1 hunks)packages/features/ee/round-robin/handleRescheduleEventManager.ts(1 hunks)packages/features/ee/round-robin/roundRobinManualReassignment.test.ts(2 hunks)packages/features/ee/round-robin/roundRobinManualReassignment.ts(1 hunks)packages/features/ee/round-robin/roundRobinReassignment.test.ts(3 hunks)packages/features/ee/round-robin/roundRobinReassignment.ts(1 hunks)packages/features/eventtypes/lib/getEventTypeById.test.ts(1 hunks)packages/features/eventtypes/lib/getEventTypeById.ts(1 hunks)packages/features/eventtypes/lib/types.ts(1 hunks)packages/features/webhooks/lib/scheduleTrigger.ts(1 hunks)packages/lib/getBusyTimes.ts(1 hunks)packages/lib/getConnectedDestinationCalendars.ts(1 hunks)packages/lib/location.ts(0 hunks)packages/lib/server/getLuckyUser.ts(1 hunks)packages/platform/libraries/event-types.ts(2 hunks)packages/platform/libraries/index.ts(2 hunks)packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts(1 hunks)packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts(1 hunks)packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts(1 hunks)packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts(1 hunks)packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts(1 hunks)packages/trpc/server/routers/viewer/eventTypes/get.handler.ts(1 hunks)packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts(1 hunks)packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/get.handler.test.ts(2 hunks)packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts(2 hunks)tests/libs/__mocks__/CalendarManager.ts(1 hunks)
💤 Files with no reviewable changes (1)
- packages/lib/location.ts
✅ Files skipped from review due to trivial changes (3)
- packages/features/eventtypes/lib/getEventTypeById.test.ts
- packages/lib/getBusyTimes.ts
- packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts
- packages/trpc/server/routers/viewer/teams/get.handler.test.ts
- packages/platform/libraries/event-types.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.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/lib/team/[slug]/[type]/getServerSideProps.tsxapps/web/modules/apps/installation/[[...step]]/step-view.tsxapps/web/components/apps/installation/ConfigureStepCard.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/lib/team/[slug]/[type]/getServerSideProps.tsxapps/web/lib/apps/installation/[[...step]]/getServerSideProps.tspackages/features/ee/round-robin/handleRescheduleEventManager.tspackages/app-store/_utils/payments/handlePaymentSuccess.tsapps/web/modules/apps/installation/[[...step]]/step-view.tsxpackages/features/ee/round-robin/roundRobinReassignment.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/bookings/lib/handleConfirmation.tspackages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.tspackages/lib/server/getLuckyUser.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tsapps/web/components/apps/installation/ConfigureStepCard.tsxpackages/features/ee/round-robin/roundRobinManualReassignment.test.tstests/libs/__mocks__/CalendarManager.tspackages/features/bookings/lib/EventManager.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/lib/getConnectedDestinationCalendars.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/features/bookings/lib/handleNewBooking.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/credentials/handleDeleteCredential.tspackages/features/calendars/lib/CalendarManager.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/features/webhooks/lib/scheduleTrigger.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/api/availability/calendar/route.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleCancelBooking.tsapps/api/v1/pages/api/destination-calendars/[id]/_patch.tspackages/features/eventtypes/lib/types.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/features/ee/payments/api/webhook.tspackages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/platform/libraries/index.tspackages/trpc/server/routers/viewer/bookings/addGuests.handler.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:
apps/web/lib/team/[slug]/[type]/getServerSideProps.tsxapps/web/lib/apps/installation/[[...step]]/getServerSideProps.tspackages/features/ee/round-robin/handleRescheduleEventManager.tspackages/app-store/_utils/payments/handlePaymentSuccess.tsapps/web/modules/apps/installation/[[...step]]/step-view.tsxpackages/features/ee/round-robin/roundRobinReassignment.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/bookings/lib/handleConfirmation.tspackages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.tspackages/lib/server/getLuckyUser.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tsapps/web/components/apps/installation/ConfigureStepCard.tsxpackages/features/ee/round-robin/roundRobinManualReassignment.test.tstests/libs/__mocks__/CalendarManager.tspackages/features/bookings/lib/EventManager.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/lib/getConnectedDestinationCalendars.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/features/bookings/lib/handleNewBooking.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/credentials/handleDeleteCredential.tspackages/features/calendars/lib/CalendarManager.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/features/webhooks/lib/scheduleTrigger.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/api/availability/calendar/route.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleCancelBooking.tsapps/api/v1/pages/api/destination-calendars/[id]/_patch.tspackages/features/eventtypes/lib/types.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/features/ee/payments/api/webhook.tspackages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/platform/libraries/index.tspackages/trpc/server/routers/viewer/bookings/addGuests.handler.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/web/lib/apps/installation/[[...step]]/getServerSideProps.tspackages/features/ee/round-robin/handleRescheduleEventManager.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/ee/round-robin/roundRobinReassignment.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/bookings/lib/handleConfirmation.tspackages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.tspackages/lib/server/getLuckyUser.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tspackages/features/ee/round-robin/roundRobinManualReassignment.test.tstests/libs/__mocks__/CalendarManager.tspackages/features/bookings/lib/EventManager.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/lib/getConnectedDestinationCalendars.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/features/bookings/lib/handleNewBooking.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/credentials/handleDeleteCredential.tspackages/features/calendars/lib/CalendarManager.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/features/webhooks/lib/scheduleTrigger.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/api/availability/calendar/route.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleCancelBooking.tsapps/api/v1/pages/api/destination-calendars/[id]/_patch.tspackages/features/eventtypes/lib/types.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/features/ee/payments/api/webhook.tspackages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/platform/libraries/index.tspackages/trpc/server/routers/viewer/bookings/addGuests.handler.ts
🧠 Learnings (16)
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
packages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tspackages/features/ee/round-robin/roundRobinManualReassignment.test.tspackages/features/bookings/lib/EventManager.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleCancelBooking.tspackages/features/eventtypes/lib/types.tspackages/features/ee/payments/api/webhook.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/app-store/_utils/payments/handlePaymentSuccess.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/features/eventtypes/lib/types.tspackages/features/eventtypes/lib/getEventTypeById.ts
📚 Learning: 2025-08-05T12:04:29.037Z
Learnt from: din-prajapati
PR: calcom/cal.com#21854
File: packages/app-store/office365calendar/__tests__/unit_tests/SubscriptionManager.test.ts:0-0
Timestamp: 2025-08-05T12:04:29.037Z
Learning: In packages/app-store/office365calendar/lib/CalendarService.ts, the fetcher method in Office365CalendarService class is public, not private. It was specifically changed from private to public in this PR to support proper testing and external access patterns.
Applied to files:
packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/lib/server/getLuckyUser.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/api/availability/calendar/route.tsapps/api/v1/pages/api/destination-calendars/[id]/_patch.ts
📚 Learning: 2025-08-26T08:08:23.395Z
Learnt from: SinghaAnirban005
PR: calcom/cal.com#23343
File: packages/features/insights/server/trpc-router.ts:1080-1101
Timestamp: 2025-08-26T08:08:23.395Z
Learning: In packages/features/insights/server/trpc-router.ts, when filtering personal event types (userId provided, no teamId, not isAll), the query correctly uses user.id (authenticated user) instead of the input userId parameter for security reasons. This prevents users from accessing other users' personal event types by passing arbitrary user IDs.
Applied to files:
packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
📚 Learning: 2025-09-12T07:15:58.030Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.030Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/features/eventtypes/lib/types.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
packages/features/ee/round-robin/roundRobinReassignment.test.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tsapps/web/app/api/availability/calendar/route.tspackages/platform/libraries/index.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/ee/round-robin/roundRobinReassignment.test.ts
📚 Learning: 2025-08-21T13:55:23.470Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/service/FormWebhookService.ts:0-0
Timestamp: 2025-08-21T13:55:23.470Z
Learning: In the new webhook architecture for Cal.com, schedulePayload is considered legacy code that doesn't fit the clean architecture. The new architecture keeps webhook scheduling logic within the Service layer, specifically through a new method WebhookService.scheduleDelayedWebhooks, rather than using the old centralized schedulePayload helper.
Applied to files:
packages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/handleCancelBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/handleCancelBooking.tspackages/features/ee/payments/api/webhook.ts
📚 Learning: 2025-09-12T11:23:34.118Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.118Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/ee/round-robin/roundRobinManualReassignment.test.tsapps/api/v1/test/lib/bookings/_post.test.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: In the Cal.com codebase, some calendar integrations like google-calendar already use SelectedCalendarRepository.create for selectedCalendar creation, which automatically triggers reconnection logic, while others like feishucalendar use direct prisma.selectedCalendar.create calls that bypass the repository hooks.
Applied to files:
packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tsapps/web/app/api/availability/calendar/route.ts
📚 Learning: 2025-09-01T07:31:00.963Z
Learnt from: nangelina
PR: calcom/cal.com#23486
File: packages/app-store/kyzon-space/config.json:5-5
Timestamp: 2025-09-01T07:31:00.963Z
Learning: In Cal.com's video integration system, credential types (e.g., "kyzon-space_video") are transformed to app names by removing underscores using `cred.type.split("_").join("")` in videoClient.ts line 28. This means the key in packages/app-store/index.ts should match the underscore-removed version (e.g., "kyzon-spacevideo") rather than the original type name. This same pattern is used in other parts of the system like getCalendar.ts.
Applied to files:
packages/features/credentials/handleDeleteCredential.ts
📚 Learning: 2025-09-01T07:31:00.963Z
Learnt from: nangelina
PR: calcom/cal.com#23486
File: packages/app-store/kyzon-space/config.json:5-5
Timestamp: 2025-09-01T07:31:00.963Z
Learning: In Cal.com's video integration system, credential types (e.g., "kyzon-space_video") are transformed to app names by removing underscores using `cred.type.split("_").join("")` in videoClient.ts line 28. This means the key in packages/app-store/index.ts should match the underscore-removed version (e.g., "kyzon-spacevideo") rather than the original type name.
Applied to files:
packages/features/credentials/handleDeleteCredential.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/ee/payments/api/webhook.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/bookings/addGuests.handler.ts
| export { getConnectedDestinationCalendarsAndEnsureDefaultsInDb } from "@calcom/lib/getConnectedDestinationCalendars"; | ||
|
|
||
| export { getBusyCalendarTimes } from "@calcom/lib/CalendarManager"; | ||
| export { getBusyCalendarTimes } from "@calcom/features/calendars/lib/CalendarManager"; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Re‑export path switch for getBusyCalendarTimes: sanity checks.
Validate that consumers import from the platform barrel and that the new source path exports the symbol.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Confirm new source exports getBusyCalendarTimes"
fd -a --glob "features/**/CalendarManager.ts"
rg -nP -C1 '\bexport\s+const\s+getBusyCalendarTimes\b' packages/features/calendars/lib/CalendarManager.ts
echo "Find consumers via platform barrel"
rg -nP -C1 'getBusyCalendarTimes[\\s\\S]*from\\s+[\'"]@calcom/platform/libraries[\'"]' -g '!**/node_modules/**' || true
echo "Ensure no lingering imports from old lib path"
rg -nP -C1 'getBusyCalendarTimes[\\s\\S]*from\\s+[\'"]@calcom/lib/CalendarManager[\'"]' -g '!**/node_modules/**' || trueLength of output: 215
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "1) Confirm export in new source (packages/features/calendars/lib/CalendarManager.ts)"
rg -n --no-ignore -S '\bexport\b.*\bgetBusyCalendarTimes\b' packages/features/calendars/lib/CalendarManager.ts || true
echo
echo "2) Find all occurrences of getBusyCalendarTimes (skip node_modules)"
rg -n --hidden -S -C2 "getBusyCalendarTimes" -g '!**/node_modules/**' || true
echo
echo "3) Show import lines that import from @calcom/platform/libraries"
rg -n --hidden -C2 "from ['\"]@calcom/platform/libraries['\"]" -g '!**/node_modules/**' || true
echo
echo "4) Show import lines that import from @calcom/lib/CalendarManager (old path)"
rg -n --hidden -C2 "from ['\"]@calcom/lib/CalendarManager['\"]" -g '!**/node_modules/**' || trueLength of output: 792
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "A) Confirm export in features CalendarManager file"
rg -n --no-ignore -S '\bexport\b.*\bgetBusyCalendarTimes\b' packages/features/calendars/lib/CalendarManager.ts || true
echo
echo "B) Show platform barrel (packages/platform/libraries/index.ts) around export"
if [ -f packages/platform/libraries/index.ts ]; then
sed -n '1,240p' packages/platform/libraries/index.ts || true
else
echo "packages/platform/libraries/index.ts not found"
fi
echo
echo "C) Search for imports from @calcom/platform/libraries"
rg -n --no-ignore -S "from ['\"]@calcom/platform/libraries['\"]" || true
echo
echo "D) Search for direct imports from features CalendarManager (consumers bypassing barrel)"
rg -n --no-ignore -S "from ['\"]@calcom/features/calendars/lib/CalendarManager['\"]" || true
echo
echo "E) Search for imports from old path @calcom/lib/CalendarManager"
rg -n --no-ignore -S "@calcom/lib/CalendarManager" || true
echo
echo "F) Find all usages of getBusyCalendarTimes"
rg -n --no-ignore -S "getBusyCalendarTimes" || trueLength of output: 12314
Re-export path switch for getBusyCalendarTimes — verified; migrate direct imports
- Verified: packages/features/calendars/lib/CalendarManager.ts exports getBusyCalendarTimes (export const getBusyCalendarTimes at line 226).
- Issue: consumers still import directly from "@calcom/features/calendars/lib/CalendarManager". Affected files (representative):
- packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
- packages/lib/getBusyTimes.ts
- packages/lib/server/getLuckyUser.ts
- packages/lib/getCalendarsEvents.ts
- tests/libs/mocks/CalendarManager.ts
- (platform barrel already re-exports it at packages/platform/libraries/index.ts:56)
- Action: update these imports to import { getBusyCalendarTimes } from "@calcom/platform/libraries" (and adjust tests/mocks), or justify/keep direct imports if intentional.
🤖 Prompt for AI Agents
In packages/platform/libraries/index.ts around line 56, getBusyCalendarTimes was
re-exported from the platform barrel but many consumers still import directly
from "@calcom/features/calendars/lib/CalendarManager"; update those consumer
imports (e.g.,
packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts,
packages/lib/getBusyTimes.ts, packages/lib/server/getLuckyUser.ts,
packages/lib/getCalendarsEvents.ts, tests/libs/__mocks__/CalendarManager.ts) to
import { getBusyCalendarTimes } from "@calcom/platform/libraries" (and update
mocks/tests accordingly) so all code uses the new re-exported path, or
document/justify any remaining direct imports if intentional.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/features/credentials/handleDeleteCredential.ts (1)
91-96: Avoid Prisma include; select only needed fields to prevent loading credential.key.We only use destinationCalendar.id and destinationCalendar.credential.appId here. Selecting narrowly improves safety and follows our guideline.
- destinationCalendar: { - include: { - credential: true, - }, - }, + destinationCalendar: { + select: { + id: true, + credential: { select: { appId: true } }, + }, + },packages/lib/getConnectedDestinationCalendars.ts (1)
6-6: Don't mix Prisma clients; thread the same Prisma instance through helpers.Helpers use the module‑level prisma import while the main function receives a prisma param. This can break transactional boundaries and complicate testing.
Apply:
-import prisma from "@calcom/prisma"; +// use the prisma instance passed into the main function; remove module import -async function handleNoConnectedCalendars(user: UserWithCalendars) { +async function handleNoConnectedCalendars(user: UserWithCalendars, prisma: PrismaClient) { log.debug(`No connected calendars, deleting destination calendar if it exists for user ${user.id}`); if (!user.destinationCalendar) return user; await prisma.destinationCalendar.delete({ where: { userId: user.id }, }); return { ...user, destinationCalendar: null }; } -async function handleDestinationCalendarNotInConnectedCalendars({ +async function handleDestinationCalendarNotInConnectedCalendars({ user, connectedCalendars, onboarding, -}: { + prisma, +}: { user: UserWithCalendars; connectedCalendars: ConnectedCalendarsFromGetConnectedCalendars; onboarding: boolean; + prisma: PrismaClient; }) { let calendarToEnsureIsEnabledForConflictCheck: ToggledCalendarDetails | null = null; log.debug( `Destination calendar isn't in connectedCalendars, update it to the first primary connected calendar for user ${user.id}` ); const { integration = "", externalId = "", email: primaryEmail } = connectedCalendars[0].primary ?? {}; // Select the first calendar matching the primary by default since that will also be the destination calendar if (onboarding && externalId) { @@ user.destinationCalendar = await prisma.destinationCalendar.update({ where: { userId: user.id }, data: { integration, externalId, primaryEmail, }, }); return { user, connectedCalendars, calendarToEnsureIsEnabledForConflictCheck }; } @@ - user = await handleNoConnectedCalendars(user); + user = await handleNoConnectedCalendars(user, prisma); } else if (!user.destinationCalendar) { - ({ user, calendarToEnsureIsEnabledForConflictCheck, connectedCalendars } = - await handleNoDestinationCalendar({ - user, - connectedCalendars, - onboarding, - })); + ({ user, calendarToEnsureIsEnabledForConflictCheck, connectedCalendars } = + await handleNoDestinationCalendar({ user, connectedCalendars, onboarding })); } else { @@ - ({ user, calendarToEnsureIsEnabledForConflictCheck, connectedCalendars } = - await handleDestinationCalendarNotInConnectedCalendars({ - user, - connectedCalendars, - onboarding, - })); + ({ user, calendarToEnsureIsEnabledForConflictCheck, connectedCalendars } = + await handleDestinationCalendarNotInConnectedCalendars({ + user, + connectedCalendars, + onboarding, + prisma, + }));Also applies to: 81-88, 165-201, 313-321, 328-336
packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts (1)
33-51: Replace Prisma include with explicit select (narrow the shape).Downstream uses attendee.id, email, name, timeZone, locale and checks bookingSeat (and bookingSeat.id). Replace the include with an explicit select:
const newTimeSlotBooking = await prisma.booking.findFirst({ where: { startTime: dayjs(evt.startTime).toDate(), eventTypeId: eventType.id, status: BookingStatus.ACCEPTED, }, - select: { - id: true, - uid: true, - iCalUID: true, - userId: true, - attendees: { - include: { - bookingSeat: true, - }, - }, - references: true, - }, + select: { + id: true, + uid: true, + iCalUID: true, + userId: true, + attendees: { + select: { + id: true, + email: true, + name: true, + timeZone: true, + locale: true, + bookingSeat: { select: { id: true } }, + }, + }, + references: { select: { type: true, meetingId: true, meetingPassword: true, meetingUrl: true } }, + }, });[must fix]
🧹 Nitpick comments (35)
packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts (3)
90-101: Use a lightweight existence check (avoid fetching whole row).Replace findFirst with count/select to follow our Prisma guideline and reduce data fetch.
Apply:
- if ( - !(await prisma.eventType.findFirst({ - where: { - id: eventTypeId, - userId: user.id, - }, - })) - ) { + const hasAccess = await prisma.eventType.count({ + where: { id: eventTypeId, userId: user.id }, + }); + if (!hasAccess) { throw new TRPCError({ code: "UNAUTHORIZED", message: `You don't have access to event type ${eventTypeId}`, }); }
64-64: Minor: prefer flatMap for readability.Equivalent but clearer than map(...).flat().
- const allCals = connectedCalendars.map((cal) => cal.calendars ?? []).flat(); + const allCals = connectedCalendars.flatMap((c) => c.calendars ?? []);
74-76: Type the where variable to avoid implicit any.Small TS hygiene to keep types tight.
- let where; + let where: { eventTypeId?: number; userId?: number };packages/trpc/server/routers/viewer/teams/get.handler.test.ts (1)
82-82: Type the mock as vi.Mock (not jest.Mock).You’re on Vitest; using jest.Mock can cause type drift.
- (getConnectedCalendars as jest.Mock).mockResolvedValue({ + (getConnectedCalendars as unknown as vi.Mock).mockResolvedValue({packages/features/credentials/handleDeleteCredential.ts (1)
490-491: Prefer named export over default for consistency and tree‑shaking.Switching to a named export matches our repo conventions.
-export default handleDeleteCredential; +export { handleDeleteCredential };Note: add/update imports accordingly.
packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts (1)
82-82: Use vi.Mock instead of jest.Mock.Stay consistent with Vitest types.
- (getConnectedCalendars as jest.Mock).mockResolvedValue({ + (getConnectedCalendars as unknown as vi.Mock).mockResolvedValue({packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts (1)
291-293: Use logger instead of console.log for errors.Keeps observability consistent.
- } catch (error) { - console.log("Error sending LocationChangeEmails", safeStringify(error)); - } + } catch (error) { + logger.warn("Error sending LocationChangeEmails", safeStringify(error)); + }packages/features/ee/round-robin/roundRobinReassignment.ts (2)
268-275: Guard the non-null assertion on previousRRHostAttendee.Avoid potential runtime crash if attendee not found.
- const previousRRHostAttendee = booking.attendees.find( - (attendee) => attendee.email === previousRRHost.email - ); - await prisma.attendee.update({ - where: { - id: previousRRHostAttendee!.id, - }, + const previousRRHostAttendee = booking.attendees.find( + (a) => a.email === previousRRHost.email + ); + if (!previousRRHostAttendee) { + throw new Error("Previous RR host attendee not found"); + } + await prisma.attendee.update({ + where: { id: previousRRHostAttendee.id }, data: { name: reassignedRRHost.name || "", email: reassignedRRHost.email, timeZone: reassignedRRHost.timeZone, locale: reassignedRRHost.locale, }, });
508-509: Prefer named export over default.Improves tree‑shaking and refactorability.
-export default roundRobinReassignment; +export { roundRobinReassignment };Note: update import sites accordingly.
packages/lib/getConnectedDestinationCalendars.ts (2)
236-241: Use the app logger instead of console.log.Replace noisy console logs with the structured logger.
- console.log( + log.debug( `Upsert the selectedCalendar record to the DB for user ${user.id} with details ${JSON.stringify( selectedCalendar )}` );
342-359: Replace Array.every early‑exit hack with clearer some/loop.Improves readability without behavior change.
- // We use every so that we can exit early once we find the matching calendar - connectedCalendars.every((cal) => { + // Stop at first match + connectedCalendars.some((cal) => { const index = (cal.calendars || []).findIndex( (calendar) => calendar.externalId === destinationCal.externalId && calendar.integration === destinationCal.integration ); if (index >= 0 && cal.calendars) { cal.calendars[index].isSelected = true; calendarToEnsureIsEnabledForConflictCheck = { externalId: destinationCal.externalId, integration: destinationCal.integration || "", }; - return false; + return true; } - - return true; + return false; });packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts (1)
786-786: Updated EventManager path: ok. Consider named export to avoid default.When feasible, switch EventManager to a named export to align with repo guidelines; tests can then
const { EventManager } = await import(...).If you want, I can raise a follow‑up PR to convert EventManager to named export and update call sites.
packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts (1)
20-26: Prefer named export over default.Optional, but aligns with tree‑shaking and refactor hygiene.
-const rescheduleSeatedBooking = async ( +export const rescheduleSeatedBooking = async ( // If this function is being called then rescheduleUid is defined rescheduleSeatedBookingObject: RescheduleSeatedBookingObject, @@ -export default rescheduleSeatedBooking; +// named export aboveAlso applies to: 144-145
packages/features/bookings/lib/handleSeats/create/createNewSeat.ts (2)
107-112: Useselectwith findUnique to limit fields.Return only fields you actually need from BookingSeat.
- const newBookingSeat = await prisma.bookingSeat.findUnique({ - where: { - referenceUid: attendeeUniqueId, - }, - }); + const newBookingSeat = await prisma.bookingSeat.findUnique({ + where: { referenceUid: attendeeUniqueId }, + select: { id: true, referenceUid: true }, // extend if more fields are required downstream + });
24-29: Prefer named export over default.Keeps exports consistent across the feature module.
-const createNewSeat = async ( +export const createNewSeat = async ( rescheduleSeatedBookingObject: NewSeatedBookingObject, @@ -export default createNewSeat; +// named export aboveAlso applies to: 225-226
apps/api/v1/pages/api/destination-calendars/_post.ts (1)
100-109: Narrow Prisma fetch for existence check.Only presence is needed; select just the id.
- if (parsedBody.eventTypeId) { - const eventType = await prisma.eventType.findFirst({ - where: { id: parsedBody.eventTypeId, userId: parsedBody.userId }, - }); + if (parsedBody.eventTypeId) { + const eventType = await prisma.eventType.findFirst({ + where: { id: parsedBody.eventTypeId, userId: parsedBody.userId }, + select: { id: true }, + });packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts (2)
5-5: Prefer named export for EventManager (if available)If EventManager is (or can be) a named export, prefer it for tree‑shaking and consistency.
-import type EventManager from "@calcom/features/bookings/lib/EventManager"; +import type { EventManager } from "@calcom/features/bookings/lib/EventManager";
107-107: Avoid default export for module ergonomicsSwitching to a named export improves refactors and IDE tooling. Non‑blocking for this PR.
-export default attendeeRescheduleSeatedBooking; +export { attendeeRescheduleSeatedBooking };packages/lib/getBusyTimes.ts (1)
132-179: Day.js in hot loops — consider minimizing allocationsThis reduce/map path is hot; repeated dayjs() and toDate() calls add GC pressure. Cache conversions or use numeric epochs where possible; keep .utc() where required.
Also applies to: 249-265
packages/trpc/server/routers/viewer/eventTypes/get.handler.ts (1)
1-1: Prefer named import for getEventTypeById (if exported)Aligns with our guideline to avoid default exports.
-import getEventTypeById from "@calcom/features/eventtypes/lib/getEventTypeById"; +import { getEventTypeById } from "@calcom/features/eventtypes/lib/getEventTypeById";packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts (1)
78-103: Use Prisma select instead of includePer repo guideline, avoid include so we don’t fetch unnecessary base scalar fields. Switch to select and enumerate only needed fields.
- const form = await prisma.app_RoutingForms_Form.findFirst({ + const form = await prisma.app_RoutingForms_Form.findFirst({ where: { id: formId, ...entityPrismaWhereClause({ userId: user.id }), }, - include: { - team: { - select: { - parentId: true, - parent: { - select: { - slug: true, - }, - }, - metadata: true, - }, - }, - user: { - select: { - id: true, - username: true, - movedToProfileId: true, - }, - }, - }, + select: { + id: true, + teamId: true, + // Add other scalar fields used by getSerializableForm if required + team: { + select: { + parentId: true, + parent: { select: { slug: true } }, + metadata: true, + }, + }, + user: { select: { id: true, username: true, movedToProfileId: true } }, + }, });If getSerializableForm needs additional fields, expand the select accordingly (you can derive a typed select via Prisma.validator for compile‑time safety).
packages/features/bookings/lib/handleNewBooking.ts (2)
39-39: EventManager import path migration — LGTMConsider exposing EventManager as a named export to match our no‑default‑exports guideline (non‑blocking).
-import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager"; +import { EventManager, placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager";
2402-2402: Prefer named export for handlerOptional, but aligns with our export policy and eases refactors.
-export default handler; +export { handler };tests/libs/__mocks__/CalendarManager.ts (1)
4-6: Path update LGTM; declare the mock before vi.mock to avoid TDZ gotchas.The new module path is correct. Minor nit: define
CalendarManagerMockbefore registering the factory so the closure can’t hit TDZ if executed earlier by Vitest.Apply this diff:
-import type * as CalendarManager from "@calcom/features/calendars/lib/CalendarManager"; - -vi.mock("@calcom/features/calendars/lib/CalendarManager", () => CalendarManagerMock); +import type * as CalendarManager from "@calcom/features/calendars/lib/CalendarManager"; +// Declare mock before registering the factory +const CalendarManagerMock = mockDeep<typeof CalendarManager>(); +vi.mock("@calcom/features/calendars/lib/CalendarManager", () => CalendarManagerMock); @@ -const CalendarManagerMock = mockDeep<typeof CalendarManager>(); export default CalendarManagerMock;packages/features/ee/round-robin/roundRobinManualReassignment.ts (1)
26-26: Import path updated — consider moving EventManager to a named export later.Non-blocking: named exports ease tree‑shaking and refactors; keep default for now to minimize churn.
packages/features/eventtypes/lib/getEventTypeById.ts (4)
247-253: Limit Prisma select on destinationCalendar.Per guidelines, avoid returning full rows. Select only required fields to prevent accidental leakage.
Apply:
- destinationCalendar = await prisma.destinationCalendar.findFirst({ - where: { - userId: userId, - eventTypeId: null, - }, - }); + destinationCalendar = await prisma.destinationCalendar.findFirst({ + where: { userId, eventTypeId: null }, + select: { + id: true, + integration: true, + externalId: true, + primaryEmail: true, + }, + });
76-85: Parallelize profile enrichments to reduce latency.The three for-loops await sequentially; use Promise.all to parallelize.
- const eventTeamMembershipsWithUserProfile = []; - for (const eventTeamMembership of rawEventType.team?.members || []) { - eventTeamMembershipsWithUserProfile.push({ - ...eventTeamMembership, - user: await userRepo.enrichUserWithItsProfile({ - user: eventTeamMembership.user, - }), - }); - } + const eventTeamMembershipsWithUserProfile = await Promise.all( + (rawEventType.team?.members || []).map(async (m) => ({ + ...m, + user: await userRepo.enrichUserWithItsProfile({ user: m.user }), + })) + ); @@ - const childrenWithUserProfile = []; - for (const child of rawEventType.children || []) { - childrenWithUserProfile.push({ - ...child, - owner: child.owner - ? await userRepo.enrichUserWithItsProfile({ - user: child.owner, - }) - : null, - }); - } + const childrenWithUserProfile = await Promise.all( + (rawEventType.children || []).map(async (child) => ({ + ...child, + owner: child.owner ? await userRepo.enrichUserWithItsProfile({ user: child.owner }) : null, + })) + ); @@ - const eventTypeUsersWithUserProfile = []; - for (const eventTypeUser of rawEventType.users) { - eventTypeUsersWithUserProfile.push( - await userRepo.enrichUserWithItsProfile({ - user: eventTypeUser, - }) - ); - } + const eventTypeUsersWithUserProfile = await Promise.all( + rawEventType.users.map((u) => userRepo.enrichUserWithItsProfile({ user: u })) + );Also applies to: 86-96, 98-105
131-131: Avoid unknown cast for locations.Prefer tightening getRawEventType’s return type so locations are typed as LocationObject[] at the source, avoiding
as unknown as ...here.
289-289: Prefer named export over default.To improve tree‑shaking and refactors, export
getEventTypeByIdas named. Consider a follow‑up codemod to migrate imports.-export default getEventTypeById; +export { getEventTypeById };packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts (1)
56-56: Prefer named export.Switch to a named export to align with repo guidelines.
-export default ownerRescheduleSeatedBooking; +export { ownerRescheduleSeatedBooking };packages/features/bookings/lib/EventManager.ts (4)
128-128: Type alias name collides with value; rename for clarity.Avoid using
createdEventSchemaas both a value and a type alias name.-type createdEventSchema = z.infer<typeof createdEventSchema>; +type CreatedEvent = z.infer<typeof createdEventSchema>; @@ - let createdEventObj: createdEventSchema | null = null; + let createdEventObj: CreatedEvent | null = null;Also applies to: 383-399
879-881: Use safeStringify in logs (avoid leaking PII).Two logs still use JSON.stringify.
- log.silly("Creating Calendar event", JSON.stringify({ destination })); + log.silly("Creating Calendar event", safeStringify({ destination })); @@ - log.silly("updateAllCalendarEvents", JSON.stringify({ event, booking, newBookingId })); + log.silly("updateAllCalendarEvents", safeStringify({ event, booking, newBookingId }));Also applies to: 1071-1071
1046-1050: Reject with Error instance (not string).Helps error handling and stack traces.
- return Promise.reject( - `No suitable credentials given for the requested integration name:${event.location}` - ); + return Promise.reject( + new Error(`No suitable credentials given for the requested integration name: ${event.location}`) + );
1313-1313: Consider named export instead of default class export.Non-blocking, but aligns with repo guidance and tree‑shaking.
-export default class EventManager { +export class EventManager {Follow-up: update imports across callers.
packages/platform/libraries/event-types.ts (1)
1-1: Avoid default-import bridge; directly re-export named symbolPrefer a direct named re-export to improve tree-shaking and remove an unnecessary binding.
Apply:
-import EventManager from "@calcom/features/bookings/lib/EventManager"; +export { EventManager } from "@calcom/features/bookings/lib/EventManager"; @@ -export { EventManager };
📜 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 (51)
apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts(1 hunks)apps/api/v1/pages/api/destination-calendars/_post.ts(1 hunks)apps/api/v1/test/lib/bookings/_post.test.ts(1 hunks)apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts(1 hunks)apps/web/app/api/availability/calendar/route.ts(1 hunks)apps/web/components/apps/installation/ConfigureStepCard.tsx(1 hunks)apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts(1 hunks)apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts(1 hunks)apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx(1 hunks)apps/web/modules/apps/installation/[[...step]]/step-view.tsx(1 hunks)packages/app-store/_utils/payments/handlePaymentSuccess.ts(1 hunks)packages/features/bookings/lib/EventManager.ts(1 hunks)packages/features/bookings/lib/handleCancelBooking.ts(1 hunks)packages/features/bookings/lib/handleConfirmation.ts(1 hunks)packages/features/bookings/lib/handleNewBooking.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts(1 hunks)packages/features/bookings/lib/handleSeats/create/createNewSeat.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts(1 hunks)packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts(1 hunks)packages/features/calendars/lib/CalendarManager.ts(1 hunks)packages/features/credentials/handleDeleteCredential.ts(1 hunks)packages/features/ee/payments/api/webhook.ts(1 hunks)packages/features/ee/round-robin/handleRescheduleEventManager.ts(1 hunks)packages/features/ee/round-robin/roundRobinManualReassignment.test.ts(2 hunks)packages/features/ee/round-robin/roundRobinManualReassignment.ts(1 hunks)packages/features/ee/round-robin/roundRobinReassignment.test.ts(3 hunks)packages/features/ee/round-robin/roundRobinReassignment.ts(1 hunks)packages/features/eventtypes/lib/getEventTypeById.test.ts(1 hunks)packages/features/eventtypes/lib/getEventTypeById.ts(1 hunks)packages/features/eventtypes/lib/types.ts(1 hunks)packages/features/webhooks/lib/scheduleTrigger.ts(1 hunks)packages/lib/getBusyTimes.ts(1 hunks)packages/lib/getConnectedDestinationCalendars.ts(1 hunks)packages/lib/location.ts(0 hunks)packages/lib/server/getLuckyUser.ts(1 hunks)packages/platform/libraries/event-types.ts(2 hunks)packages/platform/libraries/index.ts(2 hunks)packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts(1 hunks)packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts(1 hunks)packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts(1 hunks)packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts(1 hunks)packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts(1 hunks)packages/trpc/server/routers/viewer/eventTypes/get.handler.ts(1 hunks)packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts(1 hunks)packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts(1 hunks)packages/trpc/server/routers/viewer/teams/get.handler.test.ts(2 hunks)packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts(2 hunks)tests/libs/__mocks__/CalendarManager.ts(1 hunks)
💤 Files with no reviewable changes (1)
- packages/lib/location.ts
✅ Files skipped from review due to trivial changes (6)
- apps/web/modules/apps/installation/[[...step]]/step-view.tsx
- packages/lib/server/getLuckyUser.ts
- packages/features/webhooks/lib/scheduleTrigger.ts
- apps/web/components/apps/installation/ConfigureStepCard.tsx
- packages/features/ee/payments/api/webhook.ts
- apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts
- packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/ee/round-robin/roundRobinManualReassignment.test.tspackages/features/credentials/handleDeleteCredential.tspackages/features/eventtypes/lib/getEventTypeById.test.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/features/eventtypes/lib/types.tspackages/features/ee/round-robin/roundRobinReassignment.tsapps/web/app/api/availability/calendar/route.tstests/libs/__mocks__/CalendarManager.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.tspackages/lib/getConnectedDestinationCalendars.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/features/bookings/lib/EventManager.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/ee/round-robin/handleRescheduleEventManager.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/lib/getBusyTimes.tspackages/features/calendars/lib/CalendarManager.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/trpc/server/routers/viewer/teams/get.handler.test.tspackages/features/bookings/lib/handleCancelBooking.tsapps/web/lib/apps/installation/[[...step]]/getServerSideProps.tspackages/platform/libraries/event-types.tspackages/features/bookings/lib/handleConfirmation.tspackages/platform/libraries/index.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/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/ee/round-robin/roundRobinManualReassignment.test.tspackages/features/credentials/handleDeleteCredential.tspackages/features/eventtypes/lib/getEventTypeById.test.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/features/eventtypes/lib/types.tspackages/features/ee/round-robin/roundRobinReassignment.tsapps/web/app/api/availability/calendar/route.tstests/libs/__mocks__/CalendarManager.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.tspackages/lib/getConnectedDestinationCalendars.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tsapps/web/lib/team/[slug]/[type]/getServerSideProps.tsxpackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/features/bookings/lib/EventManager.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/ee/round-robin/handleRescheduleEventManager.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/lib/getBusyTimes.tspackages/features/calendars/lib/CalendarManager.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/trpc/server/routers/viewer/teams/get.handler.test.tspackages/features/bookings/lib/handleCancelBooking.tsapps/web/lib/apps/installation/[[...step]]/getServerSideProps.tspackages/platform/libraries/event-types.tspackages/features/bookings/lib/handleConfirmation.tspackages/platform/libraries/index.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/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/ee/round-robin/roundRobinManualReassignment.test.tspackages/features/credentials/handleDeleteCredential.tspackages/features/eventtypes/lib/getEventTypeById.test.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.tspackages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/features/eventtypes/lib/types.tspackages/features/ee/round-robin/roundRobinReassignment.tsapps/web/app/api/availability/calendar/route.tstests/libs/__mocks__/CalendarManager.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.tspackages/lib/getConnectedDestinationCalendars.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tsapps/web/lib/team/[slug]/[type]/getServerSideProps.tsxpackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/features/bookings/lib/EventManager.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/ee/round-robin/handleRescheduleEventManager.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/lib/getBusyTimes.tspackages/features/calendars/lib/CalendarManager.tspackages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/trpc/server/routers/viewer/teams/get.handler.test.tspackages/features/bookings/lib/handleCancelBooking.tsapps/web/lib/apps/installation/[[...step]]/getServerSideProps.tspackages/platform/libraries/event-types.tspackages/features/bookings/lib/handleConfirmation.tspackages/platform/libraries/index.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/lib/team/[slug]/[type]/getServerSideProps.tsx
🧠 Learnings (14)
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
packages/features/ee/round-robin/roundRobinManualReassignment.test.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tspackages/features/ee/round-robin/roundRobinReassignment.test.tspackages/trpc/server/routers/viewer/bookings/editLocation.handler.tspackages/features/eventtypes/lib/types.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/api/v1/test/lib/bookings/_post.test.tspackages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.tsapps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.tspackages/features/bookings/lib/handleCancelBooking.ts
📚 Learning: 2025-09-12T11:23:34.118Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.118Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/ee/round-robin/roundRobinManualReassignment.test.tspackages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.tsapps/api/v1/test/lib/bookings/_post.test.ts
📚 Learning: 2025-08-05T12:04:29.037Z
Learnt from: din-prajapati
PR: calcom/cal.com#21854
File: packages/app-store/office365calendar/__tests__/unit_tests/SubscriptionManager.test.ts:0-0
Timestamp: 2025-08-05T12:04:29.037Z
Learning: In packages/app-store/office365calendar/lib/CalendarService.ts, the fetcher method in Office365CalendarService class is public, not private. It was specifically changed from private to public in this PR to support proper testing and external access patterns.
Applied to files:
packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.tspackages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tsapps/api/v1/pages/api/destination-calendars/_post.tsapps/web/app/api/availability/calendar/route.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.tspackages/features/calendars/lib/CalendarManager.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tspackages/features/ee/round-robin/roundRobinReassignment.test.tsapps/web/app/api/availability/calendar/route.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.tspackages/platform/libraries/index.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: In the Cal.com codebase, some calendar integrations like google-calendar already use SelectedCalendarRepository.create for selectedCalendar creation, which automatically triggers reconnection logic, while others like feishucalendar use direct prisma.selectedCalendar.create calls that bypass the repository hooks.
Applied to files:
packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.tsapps/web/app/api/availability/calendar/route.tspackages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/ee/round-robin/roundRobinReassignment.test.ts
📚 Learning: 2025-09-12T07:15:58.030Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.030Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/eventtypes/lib/types.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/eventtypes/lib/types.tspackages/trpc/server/routers/viewer/eventTypes/get.handler.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/features/eventtypes/lib/getEventTypeById.tspackages/platform/libraries/event-types.ts
📚 Learning: 2025-09-06T11:00:34.372Z
Learnt from: ShashwatPS
PR: calcom/cal.com#23638
File: packages/trpc/server/routers/viewer/calendars/setDestinationReminder.handler.test.ts:198-199
Timestamp: 2025-09-06T11:00:34.372Z
Learning: In calcom/cal.com PR #23638, the maintainer ShashwatPS determined that authorization checks in the setDestinationReminder handler are "not applicable" when CodeRabbit suggested adding user-scoped WHERE clauses to prevent users from modifying other users' destination calendar reminder settings.
Applied to files:
packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
📚 Learning: 2025-08-26T08:08:23.395Z
Learnt from: SinghaAnirban005
PR: calcom/cal.com#23343
File: packages/features/insights/server/trpc-router.ts:1080-1101
Timestamp: 2025-08-26T08:08:23.395Z
Learning: In packages/features/insights/server/trpc-router.ts, when filtering personal event types (userId provided, no teamId, not isAll), the query correctly uses user.id (authenticated user) instead of the input userId parameter for security reasons. This prevents users from accessing other users' personal event types by passing arbitrary user IDs.
Applied to files:
packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.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,tsx} : Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js `.utc()` in hot paths like loops
Applied to files:
packages/lib/getBusyTimes.ts
📚 Learning: 2025-08-21T13:55:23.470Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/service/FormWebhookService.ts:0-0
Timestamp: 2025-08-21T13:55:23.470Z
Learning: In the new webhook architecture for Cal.com, schedulePayload is considered legacy code that doesn't fit the clean architecture. The new architecture keeps webhook scheduling logic within the Service layer, specifically through a new method WebhookService.scheduleDelayedWebhooks, rather than using the old centralized schedulePayload helper.
Applied to files:
packages/features/bookings/lib/handleCancelBooking.tspackages/features/bookings/lib/handleConfirmation.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/handleCancelBooking.tspackages/features/bookings/lib/handleConfirmation.ts
⏰ 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). (3)
- GitHub Check: Production builds / Build API v2
- GitHub Check: Production builds / Build Web App
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (43)
packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts (1)
1-1: Import path update looks good.Matches the feature lib relocation and keeps consumers consistent.
packages/trpc/server/routers/viewer/teams/get.handler.test.ts (2)
3-3: Updated import path is correct.Test now targets the EE queries module.
15-17: Mock path update is correct.Keeps test doubles aligned with the new module location.
apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts (1)
11-11: Type import path switch looks good.No runtime impact; aligns with removal of the lib proxy.
packages/features/credentials/handleDeleteCredential.ts (1)
17-17: Import path update is correct.Keeps location types sourced from app-store.
packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts (2)
15-15: Import path update is correct.Aligns test with relocated CalendarManager.
23-26: Mock path update is correct.Keeps vi.mock targeting the new module path.
packages/app-store/_utils/payments/handlePaymentSuccess.ts (1)
10-10: EventManager import path update looks good.Consistent with features/bookings relocation.
packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts (1)
7-7: EventManager import relocation looks good.No API or behavior change.
packages/features/ee/round-robin/roundRobinReassignment.ts (1)
22-22: EventManager import path update looks good.Matches relocation to features/bookings.
packages/lib/getConnectedDestinationCalendars.ts (1)
1-1: Import path migration looks good.Dependency now points to the relocated CalendarManager under features.
packages/features/eventtypes/lib/types.ts (1)
6-6: Import source swap looks correct.Type‑only import from @calcom/app-store/locations aligns with the relocation.
packages/features/eventtypes/lib/getEventTypeById.test.ts (1)
1-1: Mock import path correction looks good.No behavioral change in tests.
packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts (1)
4-4: Import path migration is correct.packages/features/bookings/lib/handleSeats/create/createNewSeat.ts (1)
13-13: Import path migration is correct.apps/api/v1/pages/api/destination-calendars/_post.ts (1)
3-3: Import path migration is correct.apps/web/app/api/availability/calendar/route.ts (1)
9-9: Import path migration is correct.apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts (1)
10-10: Test import path update — LGTMMatches the new EE teams lib location.
packages/lib/getBusyTimes.ts (1)
2-2: CalendarManager import migration — LGTMpackages/features/ee/round-robin/roundRobinManualReassignment.test.ts (2)
25-25: Mock path update — LGTMModule path now aligns with relocated EventManager.
180-180: Dynamic import path update — LGTMSpy continues to wrap the mocked class prototype as before.
packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts (1)
72-74: Dynamic import path migration — LGTMMatches the EE teams path and keeps the same named export.
packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts (1)
1-1: CalendarManager import migration — LGTM; local verification requiredPath swap looks correct and keeps named imports. Sandbox search using
rg -nP '@calcom/lib/(CalendarManager|EventManager)|@calcom/lib/server/getTeamMemberEmailFromCrm'
produced no output/couldn't be verified — run that command locally and confirm there are no remaining matches.packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts (1)
2-2: Updated import path is correct and consistent with the refactor.packages/features/ee/round-robin/roundRobinReassignment.test.ts (2)
24-24: Mock target switched to new EventManager path — OK.
65-65: Dynamic imports updated to new EventManager path — OK.Matches the mocked path; spies will bind correctly.
Also applies to: 198-198
packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts (1)
6-6: Type-only import path migration looks good.packages/features/ee/round-robin/handleRescheduleEventManager.ts (1)
7-9: EventManager and its InitParams type moved to features/bookings — OK.Types still align with constructor usage below.
packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts (1)
5-5: Type-only import path migration looks good.packages/features/bookings/lib/handleCancelBooking.ts (1)
20-20: Import path migration to features/bookings looks good — re-run deprecated-imports searchImport path migration to features/bookings looks good; no behavioral change and resolves circular deps. The prior rg run reported "No files were searched" (rg skipped files). Re-run with flags that include ignored files to confirm no deprecated imports remain:
#!/bin/bash set -euo pipefail echo "Searching for deprecated imports (including ignored files)..." rg -nP --hidden -uu \ --glob '!dist/**' --glob '!build/**' --glob '!.next/**' --glob '!out/**' \ -e '@calcom/lib/EventManager' \ -e '@calcom/lib/CalendarManager' \ -e '@calcom/lib/server/queries/teams' || truepackages/features/eventtypes/lib/getEventTypeById.ts (2)
6-9: Import path updates look correct.The new absolute imports resolve the circular dependency; no functional risk spotted.
Also applies to: 13-13
274-287: Verify EventTypeRepository selects & ensure credential.key is never returned.
- EventTypeRepository.findById / findByIdForOrgAdmin were not found by the search — confirm their file(s) and ensure those methods use explicit Prisma select (no include) and only the minimal fields.
- Search shows Prisma
includeusage in packages/prisma/selects/event-types.ts and tRPC handlers that include credentials (packages/trpc/server/routers/viewer/bookings/util.ts, packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts). Audit these selections to ensure credential.key is not selected or returned to clients.packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts (2)
2-2: Import path update looks good.
1-3: Keep the eslint-disable — the rule is still configured.eslintrc.js still defines "no-restricted-imports" (lines 13 and 25) and many files (including packages/features/bookings/lib/EventManager.ts and this file) use the disable; do not remove the disable here unless you also update the ESLint config to allow this import.
Likely an incorrect or invalid review comment.
apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts (1)
137-138: Dynamic import path change LGTM.Keeps lazy loading while resolving to the new EE module.
apps/api/v1/test/lib/bookings/_post.test.ts (1)
89-112: Updated mock path LGTM.The mocked surface matches the real module’s default and named export shape.
apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx (1)
110-112: Dynamic import path change LGTM.packages/features/calendars/lib/CalendarManager.ts (1)
14-16: Use of library getCalendarsEvents is correct.Signatures match current usage; reduces local duplication.
packages/features/bookings/lib/EventManager.ts (1)
37-41: Import relocations LGTM.Decouples from old lib paths without altering behavior.
packages/features/bookings/lib/handleConfirmation.ts (2)
14-16: Import path updates LGTM.
9-13: Prefer WebhookService.scheduleDelayedWebhooks over sendOrSchedulePayload (follow-up)Repository/docs and issue threads show no public migration — main still uses scheduleTrigger/sendOrSchedulePayload for BOOKING_CREATED/BOOKING_PAID. Migrate these dispatches to WebhookService.scheduleDelayedWebhooks where feasible to centralize retries/backoff.
Location: packages/features/bookings/lib/handleConfirmation.ts — imports (lines 9–13) and also lines 418–444, 480–496, 540–557.
packages/platform/libraries/event-types.ts (1)
23-26: Approve — sweep for stale imports to old pathChange is correct; automated verification in sandbox couldn't search the repo (ripgrep: "No files were searched"). Run locally to confirm no remaining refs to '@calcom/lib/event-types/getEventTypeById' and sweep for stale imports:
rg -n --hidden -S "@calcom/lib/event-types/getEventTypeById" -g '!node_modules/' -C3 || true
rg -n --hidden -S "@calcom/lib/event-types" -g '!node_modules/' -C3 || true
rg -n --hidden -S -w "getEventTypeById" -g '!node_modules/**' -C3 || truepackages/platform/libraries/index.ts (1)
56-56: Path realignment LGTM — verifiedSearched the repo for '@calcom/lib/CalendarManager' — no occurrences found; CalendarManager imports point to '@calcom/features/calendars/lib/CalendarManager' (e.g. packages/platform/libraries/index.ts and other handlers/tests).
E2E results are ready! |
d44986c to
57e59ac
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/api/v1/pages/api/event-types/_get.ts (1)
58-65: ReplacecustomInputs: truewith an explicit Prisma select of only needed fields.File: apps/api/v1/pages/api/event-types/_get.ts (lines ~58–65)
Use a targeted projection and remove the eslint-disable. Example change:
- include: { - // eslint-disable-next-line @calcom/eslint/no-prisma-include-true - customInputs: true, + include: { + customInputs: { + select: { + id: true, + label: true, + type: true, + options: true, + required: true, + placeholder: true, + }, + }, hashedLink: { select: { link: true } }, team: { select: { slug: true } }, hosts: { select: { userId: true, isFixed: true } }, owner: { select: { username: true, id: true } }, children: { select: { id: true, userId: true } },
🧹 Nitpick comments (2)
apps/api/v1/pages/api/event-types/_get.ts (1)
67-71: Instantiating HttpError without throwing is a no‑op; either throw or remove.Current code never returns 404. Pick one behavior and enforce it explicitly to avoid confusion.
- // this really should return [], but backwards compatibility.. - if (data.length === 0) new HttpError({ statusCode: 404, message: "No event types were found" }); + // For backwards compatibility, return 404 when no event types are found. + if (data.length === 0) { + throw new HttpError({ statusCode: 404, message: "No event types were found" }); + }apps/api/v1/pages/api/bookings/[id]/transcripts/[recordingId]/_get.ts (1)
61-66: Use select instead of include; fetch only fields you read.We only need
typeandmeetingIdfromreferences. This removes the lint suppression and reduces data load.- const booking = await prisma.booking.findUnique({ - where: { id: bookingId }, - // eslint-disable-next-line @calcom/eslint/no-prisma-include-true - include: { references: true }, - }); + const booking = await prisma.booking.findUnique({ + where: { id: bookingId }, + select: { + references: { + select: { type: true, meetingId: 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 (11)
apps/api/v1/lib/helpers/rateLimitApiKey.test.ts(10 hunks)apps/api/v1/pages/api/bookings/[id]/_get.ts(1 hunks)apps/api/v1/pages/api/bookings/[id]/recordings/_get.ts(1 hunks)apps/api/v1/pages/api/bookings/[id]/transcripts/[recordingId]/_get.ts(1 hunks)apps/api/v1/pages/api/bookings/[id]/transcripts/_get.ts(1 hunks)apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts(1 hunks)apps/api/v1/pages/api/destination-calendars/_post.ts(1 hunks)apps/api/v1/pages/api/event-types/_get.ts(1 hunks)apps/api/v1/pages/api/payments/[id].ts(1 hunks)apps/api/v1/pages/api/schedules/[id]/_get.ts(1 hunks)apps/api/v1/pages/api/teams/[teamId]/_patch.ts(1 hunks)
✅ Files skipped from review due to trivial changes (7)
- apps/api/v1/pages/api/bookings/[id]/recordings/_get.ts
- apps/api/v1/pages/api/teams/[teamId]/_patch.ts
- apps/api/v1/pages/api/payments/[id].ts
- apps/api/v1/lib/helpers/rateLimitApiKey.test.ts
- apps/api/v1/pages/api/bookings/[id]/transcripts/_get.ts
- apps/api/v1/pages/api/schedules/[id]/_get.ts
- apps/api/v1/pages/api/bookings/[id]/_get.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/api/v1/pages/api/destination-calendars/_post.ts
- apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v1/pages/api/event-types/_get.tsapps/api/v1/pages/api/bookings/[id]/transcripts/[recordingId]/_get.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:
apps/api/v1/pages/api/event-types/_get.tsapps/api/v1/pages/api/bookings/[id]/transcripts/[recordingId]/_get.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:
apps/api/v1/pages/api/event-types/_get.tsapps/api/v1/pages/api/bookings/[id]/transcripts/[recordingId]/_get.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
apps/api/v1/pages/api/event-types/_get.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:
apps/api/v1/pages/api/event-types/_get.ts
What does this PR do?
packages/lib/server/queries/teams/index.ts → packages/features/ee/teams/lib/queries.tspackages/lib/CalendarManager.ts → packages/features/calendars/lib/CalendarManager.tspackages/lib/CalendarManager.test.ts → packages/features/calendars/lib/CalendarManager.test.tspackages/lib/server/getTeamMemberEmailFromCrm.ts → packages/features/ee/teams/lib/getTeamMemberEmailFromCrm.tspackages/lib/event-types/getEventTypeById.ts → packages/features/eventtypes/lib/getEventTypeById.tspackages/lib/event-types/getEventTypeById.test.ts → packages/features/eventtypes/lib/getEventTypeById.test.tspackages/lib/EventManager.test.ts → packages/features/bookings/lib/EventManager.test.tspackages/lib/EventManager.ts → packages/features/bookings/lib/EventManager.tsMandatory Tasks (DO NOT REMOVE)
How should this be tested?