Skip to content

refactor: circular deps between app store and lib [4]#23829

Merged
hbjORbj merged 23 commits intomainfrom
refactor/lib-to-features
Sep 18, 2025
Merged

refactor: circular deps between app store and lib [4]#23829
hbjORbj merged 23 commits intomainfrom
refactor/lib-to-features

Conversation

@hbjORbj
Copy link
Copy Markdown
Contributor

@hbjORbj hbjORbj commented Sep 15, 2025

What does this PR do?

  • Migrated files:
  1. packages/lib/server/queries/teams/index.ts → packages/features/ee/teams/lib/queries.ts
  2. packages/lib/CalendarManager.ts → packages/features/calendars/lib/CalendarManager.ts
  3. packages/lib/CalendarManager.test.ts → packages/features/calendars/lib/CalendarManager.test.ts
  4. packages/lib/server/getTeamMemberEmailFromCrm.ts → packages/features/ee/teams/lib/getTeamMemberEmailFromCrm.ts
  5. packages/lib/event-types/getEventTypeById.ts → packages/features/eventtypes/lib/getEventTypeById.ts
  6. packages/lib/event-types/getEventTypeById.test.ts → packages/features/eventtypes/lib/getEventTypeById.test.ts
  7. packages/lib/EventManager.test.ts → packages/features/bookings/lib/EventManager.test.ts
  8. packages/lib/EventManager.ts → packages/features/bookings/lib/EventManager.ts
  • Purpose: Remove lib's dependency on app-store

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A - I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Tests passing are sufficient

@hbjORbj hbjORbj requested a review from a team September 15, 2025 06:14
@hbjORbj hbjORbj requested a review from a team as a code owner September 15, 2025 06:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 15, 2025

Walkthrough

This PR systematically updates import paths across the repository, moving many symbols from monolithic modules (e.g., @calcom/lib and @calcom/lib/*) into feature-scoped packages such as @calcom/features/bookings/lib/EventManager, @calcom/features/calendars/lib/CalendarManager, @calcom/features/ee/teams/lib/queries, and @calcom/app-store/locations. It also removes the proxy re-export from packages/lib/location.ts, updates platform re-exports, adjusts test mocks, and adds several ESLint suppression comments. No runtime logic, control flow, or public API signatures were changed in the diffs.

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "refactor: circular deps between app store and lib [4]" concisely and accurately summarizes the primary intent of the changeset — refactoring to break circular dependencies between the app-store and lib by migrating modules into feature-scoped locations. It is a short, single sentence that clearly relates to the listed file moves and the PR objective, and it avoids noisy file lists or vague wording.
Description Check ✅ Passed The PR description enumerates the migrated files, states the purpose (removing lib's dependency on app-store), and includes checklist items and a testing instruction, all of which directly match the changes in the diff summary. The description is on-topic and provides sufficient context for this lenient check.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/lib-to-features

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3f8d352 and c4ac1b7.

📒 Files selected for processing (1)
  • apps/web/components/apps/installation/ConfigureStepCard.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/components/apps/installation/ConfigureStepCard.tsx
⏰ 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

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.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

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.

❤️ Share

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

@graphite-app graphite-app bot requested a review from a team September 15, 2025 06:14
@keithwillcode keithwillcode added core area: core, team members only foundation labels Sep 15, 2025
@hbjORbj hbjORbj changed the title refactor: lib to features refactor: Move team prisma queries from @calcom/lib to @calcom/features Sep 15, 2025
@vercel
Copy link
Copy Markdown

vercel bot commented Sep 15, 2025

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

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

@dosubot dosubot bot added teams area: teams, round robin, collective, managed event-types 💻 refactor labels Sep 15, 2025
@hbjORbj hbjORbj marked this pull request as draft September 15, 2025 06:24
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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: use select and avoid include (policy requirement)

Limit fetched fields and replace include with select.

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 checks

Fetching all memberships to derive ownership and targets is heavier than needed. Prefer targeted lookups (findUnique for targetMembership and myMembership) and count for owners.

Example:

  • findUnique({ where: { userId_teamId } , select: { id, role, accepted } }) for both users
  • count({ where: { teamId, role: OWNER } }) for owner cardinality
packages/trpc/server/routers/viewer/organizations/utils.ts (1)

81-83: Async forEach doesn’t await — updates may be dropped

Array.forEach ignores 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 types

Current deleteMany can remove hosts from event types outside teamId if 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: avoid include, return only safe fields

This path returns a raw Team from Prisma (plus createdAt: null), risking exposure of fields like inviteToken or other internals. Replace include with a minimal select and 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 import

You import getTeamWithoutMembers from 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 bypass

isOrganisationAdmin 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 whether 0 should 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/teams while 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 export

Adopt 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.

📥 Commits

Reviewing files that changed from the base of the PR and between cbfd991 and ad48458.

📒 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/trpc/server/routers/viewer/teams/delete.handler.ts
  • packages/trpc/server/routers/viewer/teams/update.handler.ts
  • packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
  • packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts
  • packages/trpc/server/routers/viewer/teams/publish.handler.ts
  • packages/trpc/server/routers/viewer/teams/deleteInvite.handler.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
  • packages/features/pbac/services/role-management.factory.ts
  • packages/features/auth/signup/utils/organization.ts
  • packages/features/ee/dsync/lib/handleGroupEvents.ts
  • packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
  • packages/features/ee/sso/lib/saml.ts
  • packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts
  • packages/trpc/server/routers/viewer/teams/removeMember.handler.ts
  • packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts
  • packages/trpc/server/routers/viewer/teams/get.handler.ts
  • packages/trpc/server/routers/viewer/organizations/utils.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts
  • packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts
  • packages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.ts
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/platform/libraries/event-types.ts
  • packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts
  • packages/features/auth/signup/utils/createOrUpdateMemberships.ts
  • packages/features/ee/teams/lib/queries.ts
  • packages/trpc/server/routers/viewer/teams/createInvite.handler.ts
  • packages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/teams/update.handler.ts
  • packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
  • packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts
  • packages/trpc/server/routers/viewer/teams/publish.handler.ts
  • packages/trpc/server/routers/viewer/teams/deleteInvite.handler.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
  • packages/features/pbac/services/role-management.factory.ts
  • packages/features/auth/signup/utils/organization.ts
  • packages/features/ee/dsync/lib/handleGroupEvents.ts
  • packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
  • packages/features/ee/sso/lib/saml.ts
  • packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts
  • packages/trpc/server/routers/viewer/teams/removeMember.handler.ts
  • packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts
  • packages/trpc/server/routers/viewer/teams/get.handler.ts
  • packages/trpc/server/routers/viewer/organizations/utils.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts
  • packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts
  • apps/web/lib/team/[slug]/getServerSideProps.tsx
  • packages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.ts
  • apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsx
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/platform/libraries/event-types.ts
  • apps/web/components/team/screens/Team.tsx
  • packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts
  • packages/features/auth/signup/utils/createOrUpdateMemberships.ts
  • packages/features/ee/teams/lib/queries.ts
  • packages/trpc/server/routers/viewer/teams/createInvite.handler.ts
  • packages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/teams/update.handler.ts
  • packages/trpc/server/routers/viewer/teams/setInviteExpiration.handler.ts
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
  • packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts
  • packages/trpc/server/routers/viewer/teams/publish.handler.ts
  • packages/trpc/server/routers/viewer/teams/deleteInvite.handler.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
  • packages/features/pbac/services/role-management.factory.ts
  • packages/features/auth/signup/utils/organization.ts
  • packages/features/ee/dsync/lib/handleGroupEvents.ts
  • packages/trpc/server/routers/viewer/teams/acceptOrLeave.handler.ts
  • packages/features/ee/sso/lib/saml.ts
  • packages/trpc/server/routers/viewer/bookings/addGuests.handler.ts
  • packages/trpc/server/routers/viewer/teams/removeMember.handler.ts
  • packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts
  • packages/trpc/server/routers/viewer/teams/get.handler.ts
  • packages/trpc/server/routers/viewer/organizations/utils.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/inviteMemberUtils.test.ts
  • packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts
  • apps/web/lib/team/[slug]/getServerSideProps.tsx
  • packages/trpc/server/routers/viewer/teams/updateInternalNotesPresets.handler.ts
  • apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsx
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/platform/libraries/event-types.ts
  • apps/web/components/team/screens/Team.tsx
  • packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts
  • packages/features/auth/signup/utils/createOrUpdateMemberships.ts
  • packages/features/ee/teams/lib/queries.ts
  • packages/trpc/server/routers/viewer/teams/createInvite.handler.ts
  • packages/trpc/server/routers/viewer/teams/getMemberAvailability.handler.ts
  • packages/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.tsx
  • apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/roles/page.tsx
  • apps/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.ts
  • packages/trpc/server/routers/viewer/teams/publish.handler.ts
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
  • packages/features/auth/signup/utils/organization.ts
  • packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
  • packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts
  • packages/trpc/server/routers/viewer/organizations/utils.ts
  • packages/trpc/server/routers/viewer/me/updateProfile.handler.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/teams/addMembersToEventTypes.handler.ts
  • packages/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.ts
  • packages/features/auth/signup/utils/createOrUpdateMemberships.ts
  • packages/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 isTeamOwner has 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 isTeamAdmin has 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 isTeamAdmin has 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 addNewMembersToEventTypes has 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 getTeamWithMembers has 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 updateNewTeamMemberEventTypes and isTeamAdmin have 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 isTeamAdmin has 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 isTeamAdmin import 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 isTeamMember function 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 isTeamAdmin import 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 getTeamWithoutMembers function 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 updateNewTeamMemberEventTypes re-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 updateNewTeamMemberEventTypes import 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:

  • getBookerBaseUrlSync from relative to @calcom/lib/getBookerUrl/client
  • getTeam and getOrg from relative to @calcom/lib/server/repository/team
  • UserRepository from relative to @calcom/lib/server/repository/user
  • EventTypeSchema import relocated for better organization

These 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 good

EE 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 LGTM

No behavior change; authorization guard with isTeamMember remains intact.

packages/trpc/server/routers/viewer/organizations/utils.ts (1)

2-2: Import relocation LGTM

Switch to EE path is consistent with the PR’s direction.

packages/trpc/server/routers/viewer/teams/removeHostsFromEventTypes.handler.ts (1)

1-1: Import relocation LGTM

Matches the EE migration.

apps/web/lib/team/[slug]/getServerSideProps.tsx (1)

14-14: Import relocation LGTM

Move to EE queries is consistent and non-functional.

packages/trpc/server/routers/viewer/teams/getInternalNotesPresets.handler.ts (1)

1-1: Import relocation + least-privilege select look good

EE 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 exports

Change 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).

@hbjORbj hbjORbj changed the title refactor: Move team prisma queries from @calcom/lib to @calcom/features refactor: circular deps between app store and lib [4] Sep 15, 2025
@@ -1 +0,0 @@
export * from "@calcom/app-store/locations";
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rather, we now import directly from app-store

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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 appsStatus

You 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 include

Replace 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 → select

Per 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 client

Helper 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 helpers

Pass 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.

CalendarManagerMock is referenced in vi.mock and beforeEach before 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 with null if 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 select instead 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 cast as 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 null

Drop 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 helper

The “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 default

Switch 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 isFullDayEvent

Function 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 loop

This 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 default

Align 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 variable

calendarMock 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 default

Switch to a named export for consistency.

-export default roundRobinReassignment;
+export { roundRobinReassignment };
packages/lib/getConnectedDestinationCalendars.ts (1)

236-241: Avoid console.log in library code

Use 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 → Invalid

Rename 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 args

roundRobinReassignment 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 organizationId is 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.

📥 Commits

Reviewing files that changed from the base of the PR and between ad48458 and 5b12ad4.

📒 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.tsx
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • apps/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.tsx
  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts
  • packages/lib/server/getLuckyUser.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • apps/web/components/apps/installation/ConfigureStepCard.tsx
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • tests/libs/__mocks__/CalendarManager.ts
  • packages/features/bookings/lib/EventManager.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/lib/getConnectedDestinationCalendars.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/features/calendars/lib/CalendarManager.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/features/webhooks/lib/scheduleTrigger.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/api/availability/calendar/route.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/platform/libraries/index.ts
  • packages/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.tsx
  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts
  • packages/lib/server/getLuckyUser.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • apps/web/components/apps/installation/ConfigureStepCard.tsx
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • tests/libs/__mocks__/CalendarManager.ts
  • packages/features/bookings/lib/EventManager.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/lib/getConnectedDestinationCalendars.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/features/calendars/lib/CalendarManager.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/features/webhooks/lib/scheduleTrigger.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/api/availability/calendar/route.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/platform/libraries/index.ts
  • packages/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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts
  • packages/lib/server/getLuckyUser.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • tests/libs/__mocks__/CalendarManager.ts
  • packages/features/bookings/lib/EventManager.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/lib/getConnectedDestinationCalendars.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/features/calendars/lib/CalendarManager.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/features/webhooks/lib/scheduleTrigger.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/api/availability/calendar/route.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/api/v1/pages/api/destination-calendars/[id]/_patch.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/platform/libraries/index.ts
  • packages/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.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • packages/features/bookings/lib/EventManager.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/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.ts
  • packages/lib/server/getLuckyUser.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/api/availability/calendar/route.ts
  • apps/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.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • apps/web/app/api/availability/calendar/route.ts
  • packages/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.ts
  • packages/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.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/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.ts
  • apps/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.ts
  • apps/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";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 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/**' || true

Length 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/**' || true

Length 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" || true

Length 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.

@hbjORbj hbjORbj marked this pull request as draft September 15, 2025 07:46
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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 above

Also applies to: 144-145

packages/features/bookings/lib/handleSeats/create/createNewSeat.ts (2)

107-112: Use select with 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 above

Also 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 ergonomics

Switching 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 allocations

This 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 include

Per 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 — LGTM

Consider 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 handler

Optional, 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 CalendarManagerMock before 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 getEventTypeById as 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 createdEventSchema as 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 symbol

Prefer 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.

📥 Commits

Reviewing files that changed from the base of the PR and between ad48458 and 972ae1b.

📒 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/features/eventtypes/lib/getEventTypeById.test.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • apps/web/app/api/availability/calendar/route.ts
  • tests/libs/__mocks__/CalendarManager.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
  • packages/lib/getConnectedDestinationCalendars.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/features/bookings/lib/EventManager.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/lib/getBusyTimes.ts
  • packages/features/calendars/lib/CalendarManager.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/trpc/server/routers/viewer/teams/get.handler.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • packages/platform/libraries/event-types.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/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.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/features/eventtypes/lib/getEventTypeById.test.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • apps/web/app/api/availability/calendar/route.ts
  • tests/libs/__mocks__/CalendarManager.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
  • packages/lib/getConnectedDestinationCalendars.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/features/bookings/lib/EventManager.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/lib/getBusyTimes.ts
  • packages/features/calendars/lib/CalendarManager.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/trpc/server/routers/viewer/teams/get.handler.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • packages/platform/libraries/event-types.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/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.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/features/eventtypes/lib/getEventTypeById.test.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts
  • packages/trpc/server/routers/viewer/availability/calendarOverlay.handler.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/ownerRescheduleSeatedBooking.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • apps/web/app/api/availability/calendar/route.ts
  • tests/libs/__mocks__/CalendarManager.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
  • packages/lib/getConnectedDestinationCalendars.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/features/bookings/lib/EventManager.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/lib/getBusyTimes.ts
  • packages/features/calendars/lib/CalendarManager.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/trpc/server/routers/viewer/teams/get.handler.test.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • packages/platform/libraries/event-types.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/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.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/api/v1/test/lib/bookings/_post.test.ts
  • packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts
  • apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/bookings/lib/handleSeats/reschedule/attendee/attendeeRescheduleSeatedBooking.ts
  • packages/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.ts
  • packages/features/bookings/lib/handleNewBooking/test/team-bookings/round-robin.test.ts
  • apps/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.ts
  • packages/trpc/server/routers/viewer/me/getUserTopBanners.handler.ts
  • apps/api/v1/pages/api/destination-calendars/_post.ts
  • apps/web/app/api/availability/calendar/route.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.test.ts
  • packages/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.ts
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
  • apps/web/app/api/availability/calendar/route.ts
  • packages/trpc/server/routers/viewer/calendars/setDestinationCalendar.handler.ts
  • packages/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.ts
  • apps/web/app/api/availability/calendar/route.ts
  • packages/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.ts
  • packages/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.ts
  • packages/trpc/server/routers/viewer/eventTypes/get.handler.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/features/eventtypes/lib/getEventTypeById.ts
  • packages/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.ts
  • packages/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.ts
  • packages/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 — LGTM

Matches the new EE teams lib location.

packages/lib/getBusyTimes.ts (1)

2-2: CalendarManager import migration — LGTM

packages/features/ee/round-robin/roundRobinManualReassignment.test.ts (2)

25-25: Mock path update — LGTM

Module path now aligns with relocated EventManager.


180-180: Dynamic import path update — LGTM

Spy 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 — LGTM

Matches 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 required

Path 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 search

Import 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' || true
packages/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 include usage 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 path

Change 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 || true

packages/platform/libraries/index.ts (1)

56-56: Path realignment LGTM — verified

Searched 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).

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Sep 15, 2025

E2E results are ready!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

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: Replace customInputs: true with 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 type and meetingId from references. 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 57e59ac and 3f8d352.

📒 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • apps/api/v1/pages/api/event-types/_get.ts
  • apps/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.ts
  • apps/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.ts
  • apps/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

Copy link
Copy Markdown
Contributor

@emrysal emrysal left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

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

Labels

core area: core, team members only foundation ready-for-e2e 💻 refactor size/L teams area: teams, round robin, collective, managed event-types

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants