Skip to content

feat: Round Robin groups#22296

Merged
CarinaWolli merged 105 commits intomainfrom
feat/rr-groups
Aug 8, 2025
Merged

feat: Round Robin groups#22296
CarinaWolli merged 105 commits intomainfrom
feat/rr-groups

Conversation

@CarinaWolli
Copy link
Copy Markdown
Member

@CarinaWolli CarinaWolli commented Jul 7, 2025

What does this PR do?

Introduces Round Robin host groups. From each group one host needs to attend the event. To find the Round Robin host to attend for each group the existing Round Robin logic is used. Empty groups are ignored, so if a group has no host's we are still showing available slots.

No-name groups:
Screenshot 2025-07-22 at 9 56 19 AM

Named groups:
Screenshot 2025-07-22 at 9 55 53 AM


Summary by cubic

Added support for Round Robin host groups, allowing event organizers to assign hosts into groups so that one host from each group is selected per booking.

  • New Features

    • Hosts can now be organized into groups for Round Robin events.
    • UI updated to manage host groups and assign members.
    • Booking and availability logic updated to require at least one available host from each group.
  • Fixes Round Robin Groups #22002

  • Fixes CAL-5975

@github-actions github-actions bot added the ❗️ migrations contains migration files label Jul 7, 2025
@keithwillcode keithwillcode added consumer core area: core, team members only labels Jul 7, 2025
@delve-auditor
Copy link
Copy Markdown

delve-auditor bot commented Jul 7, 2025

No security or compliance issues detected. Reviewed everything up to 8363d04.

Security Overview
  • 🔎 Scanned files: 46 changed file(s)
Detected Code Changes

The diff is too large to display a summary of code changes.

Reply to this PR with @delve-auditor followed by a description of what change you want and we'll auto-submit a change to this PR to implement it.

@vercel
Copy link
Copy Markdown

vercel bot commented Jul 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Visit Preview Aug 8, 2025 9:16am
cal-eu ⬜️ Ignored (Inspect) Visit Preview Aug 8, 2025 9:16am

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

🧹 Nitpick comments (1)
packages/features/bookings/lib/handleNewBooking.ts (1)

809-946: Well-implemented group-aware lucky user selection logic

The refactoring successfully implements Round Robin groups by:

  • Grouping non-fixed users by their group IDs
  • Selecting one lucky user per group while maintaining fairness
  • Proper validation to ensure all non-empty groups have available hosts

The implementation correctly handles edge cases and maintains backward compatibility. The complexity is justified given the feature requirements.

Minor suggestion for future optimization:
Consider extracting the inner lucky user selection logic (lines 838-910) into a separate helper function to improve readability and testability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99be2ea and b4140a1.

📒 Files selected for processing (14)
  • apps/web/components/booking/BookingListItem.tsx (4 hunks)
  • apps/web/lib/plain/PlainContactForm.tsx (1 hunks)
  • apps/web/public/static/locales/en/common.json (4 hunks)
  • packages/features/bookings/lib/handleNewBooking.ts (6 hunks)
  • packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts (3 hunks)
  • packages/features/bookings/lib/handleNewBooking/types.ts (1 hunks)
  • packages/features/eventtypes/lib/types.ts (2 hunks)
  • packages/lib/constants.ts (1 hunks)
  • packages/lib/defaultEvents.ts (1 hunks)
  • packages/lib/server/repository/eventTypeRepository.ts (4 hunks)
  • packages/platform/atoms/event-types/hooks/useEventTypeForm.ts (1 hunks)
  • packages/prisma/schema.prisma (3 hunks)
  • packages/trpc/server/routers/viewer/bookings/get.handler.ts (1 hunks)
  • packages/trpc/server/routers/viewer/slots/util.ts (2 hunks)
✅ Files skipped from review due to trivial changes (4)
  • packages/lib/constants.ts
  • apps/web/lib/plain/PlainContactForm.tsx
  • packages/trpc/server/routers/viewer/bookings/get.handler.ts
  • apps/web/components/booking/BookingListItem.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
  • packages/lib/defaultEvents.ts
  • packages/platform/atoms/event-types/hooks/useEventTypeForm.ts
  • packages/features/eventtypes/lib/types.ts
  • packages/lib/server/repository/eventTypeRepository.ts
  • packages/features/bookings/lib/handleNewBooking/types.ts
  • packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts
  • packages/trpc/server/routers/viewer/slots/util.ts
  • apps/web/public/static/locales/en/common.json
  • packages/prisma/schema.prisma
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/bookings/lib/handleNewBooking.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/bookings/lib/handleNewBooking.ts
🧠 Learnings (2)
📓 Common learnings
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.
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx:514-523
Timestamp: 2025-07-22T10:45:26.651Z
Learning: In the Round Robin groups feature, group names are only used within the event type settings UI and are not rendered elsewhere in the application. The user CarinaWolli confirmed this limited scope when asked about potential XSS concerns with direct input handling in the group name field.
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: For large pull requests (>500 lines changed or >10 files touched), advise splitting into smaller, focused PRs by feature, layer, dependency chain, or file/module
packages/features/bookings/lib/handleNewBooking.ts (3)

Learnt from: CarinaWolli
PR: #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.

Learnt from: eunjae-lee
PR: #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.

Learnt from: hariombalhara
PR: #22547
File: packages/embeds/embed-core/src/lib/eventHandlers/scrollByDistanceEventHandler.ts:11-14
Timestamp: 2025-07-16T11:46:28.759Z
Learning: In Cal.com's embed system, internal events like "__scrollByDistance" are fired by Cal.com's own code, so runtime validation of event data structure is unnecessary since TypeScript type system guarantees type safety for internal events.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (3)
packages/features/bookings/lib/handleNewBooking.ts (3)

48-48: LGTM! Import for host grouping utility

The import of groupHostsByGroupId utility is correctly added to support the new Round Robin groups functionality.


285-285: LGTM! Updated filter logic for Round Robin groups

The change to include both fixed and non-fixed users in the filteredUsers array for Round Robin scheduling correctly supports the new group-aware selection logic that happens downstream.


917-934: LGTM! Proper validation for Round Robin groups

The validation logic correctly ensures that:

  • Only non-empty host groups are considered for booking requirements
  • Each non-empty group must have at least one available host selected
  • Bookings fail appropriately when required groups lack available hosts

This implementation aligns with the Round Robin groups feature requirements and maintains booking integrity.

@CarinaWolli CarinaWolli enabled auto-merge (squash) July 30, 2025 14:47
eunjae-lee
eunjae-lee previously approved these changes Jul 30, 2025
eunjae-lee and others added 2 commits July 30, 2025 16:59
* check for attendee emails

* fix RR with same host with fixed hosts and RR groups

* code clean up

* return  hosts instead of empty array

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
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

🧹 Nitpick comments (5)
packages/lib/bookings/filterHostsBySameRoundRobinHost.test.ts (5)

69-69: Rename the describe to avoid implying fixed-hosts or RR-group support

Per the documented limitation (CAL-6134), this helper isn’t group-aware and shouldn’t be framed as such. These tests validate organizer/attendee-based filtering only. Rename to prevent confusion and avoid overclaiming coverage.

-describe("Fixed hosts and round robin groups support", () => {
+describe("Organizer and attendee host filtering (rescheduleWithSameRoundRobinHost)", () => {

87-93: Assert prisma was called when the filter applies

Make the test intention explicit by asserting the call to prisma, including key parts of the query. Keeps the test robust if early-return conditions change.

   const result = await filterHostsBySameRoundRobinHost({
     hosts,
     rescheduleUid: "some-uid",
     rescheduleWithSameRoundRobinHost: true,
     routedTeamMemberIds: null,
   });
+
+  expect(prisma.booking.findFirst).toHaveBeenCalledTimes(1);
+  expect(prisma.booking.findFirst).toHaveBeenCalledWith({
+    where: expect.objectContaining({ uid: "some-uid" }),
+    select: expect.objectContaining({
+      userId: true,
+      attendees: expect.any(Object),
+    }),
+  });

95-101: Make assertion order-agnostic to reduce brittleness

filter preserves the original order today, but asserting order here is unnecessary. Use arrayContaining + length to assert membership without coupling to order.

-// Should return organizer host (id: 1) and attendee hosts (ids: 2, 3)
-expect(result).toHaveLength(3);
-expect(result).toEqual([
-  expect.objectContaining({ user: { id: 1, email: "host1@acme.com" } }), // organizer
-  expect.objectContaining({ user: { id: 2, email: "host2@acme.com" } }), // attendee
-  expect.objectContaining({ user: { id: 3, email: "host3@acme.com" } }), // attendee
-]);
+// Should return organizer host (id: 1) and attendee hosts (ids: 2, 3)
+expect(result).toEqual(
+  expect.arrayContaining([
+    expect.objectContaining({ user: { id: 1, email: "host1@acme.com" } }), // organizer
+    expect.objectContaining({ user: { id: 2, email: "host2@acme.com" } }), // attendee
+    expect.objectContaining({ user: { id: 3, email: "host3@acme.com" } }), // attendee
+  ])
+);
+expect(result).toHaveLength(3);

69-69: Clarify scope in test naming and add a TODO reference

Given CAL-6134, consider adding a TODO linking that issue to avoid confusion for future readers who might expect actual group-aware behavior to be validated here. Example:

-describe("Organizer and attendee host filtering (rescheduleWithSameRoundRobinHost)", () => {
+// TODO(CAL-6134): This helper is not group-aware; tests validate organizer/attendee filtering only.
+describe("Organizer and attendee host filtering (rescheduleWithSameRoundRobinHost)", () => {

124-127: Optional: Strengthen the “only organizer” case

You can assert the prisma call here too for symmetry, and optionally assert identity to ensure filtered hosts are the same instances, not clones.

 // Should return only organizer host
 expect(result).toHaveLength(1);
 expect(result[0]).toEqual(expect.objectContaining({ user: { id: 1, email: "host1@acme.com" } }));
+expect(result[0]).toBe(hosts[0]); // same reference
+expect(prisma.booking.findFirst).toHaveBeenCalledTimes(1);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe9faee and c7fa308.

📒 Files selected for processing (3)
  • packages/lib/bookings/filterHostsBySameRoundRobinHost.test.ts (1 hunks)
  • packages/lib/bookings/filterHostsBySameRoundRobinHost.ts (2 hunks)
  • packages/lib/bookings/findQualifiedHostsWithDelegationCredentials.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/lib/bookings/filterHostsBySameRoundRobinHost.ts
  • packages/lib/bookings/findQualifiedHostsWithDelegationCredentials.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/lib/bookings/filterHostsBySameRoundRobinHost.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/lib/bookings/filterHostsBySameRoundRobinHost.test.ts
🧠 Learnings (2)
📓 Common learnings
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.
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx:514-523
Timestamp: 2025-07-22T10:45:26.651Z
Learning: In the Round Robin groups feature, group names are only used within the event type settings UI and are not rendered elsewhere in the application. The user CarinaWolli confirmed this limited scope when asked about potential XSS concerns with direct input handling in the group name field.
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: For large pull requests (>500 lines changed or >10 files touched), advise splitting into smaller, focused PRs by feature, layer, dependency chain, or file/module
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.
📚 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/lib/bookings/filterHostsBySameRoundRobinHost.test.ts
🧬 Code Graph Analysis (1)
packages/lib/bookings/filterHostsBySameRoundRobinHost.test.ts (1)
packages/lib/bookings/filterHostsBySameRoundRobinHost.ts (1)
  • filterHostsBySameRoundRobinHost (6-57)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache

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

🧹 Nitpick comments (3)
packages/features/bookings/lib/handleNewBooking.ts (3)

868-872: Micro-optimisation: avoid repeated org-lookup inside loop

getOrgIdFromMemberOrTeamId is called for every host group but its inputs never change inside this loop. Fetch it once before the loop and reuse the value to save an unnecessary DB round-trip.


936-947: Redundant second call to groupHostsByGroupId

luckyUserPools already groups the non-fixed hosts. Calling groupHostsByGroupId again on essentially the same data wastes cycles and risks diverging behaviour if the util changes. Reuse luckyUserPools or keep a single grouped structure for both selection and validation.


846-850: Minor readability: shadowing users variable

Inside Object.entries(...).map(([groupId, users]) => …) the parameter users shadows the outer users array defined earlier in the scope, which makes the logged object harder to read. Renaming the inner variable (e.g. groupHosts) avoids cognitive overhead.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7fa308 and c360631.

📒 Files selected for processing (5)
  • apps/web/public/static/locales/en/common.json (4 hunks)
  • apps/web/test/lib/getSchedule.test.ts (2 hunks)
  • packages/features/bookings/lib/handleNewBooking.ts (6 hunks)
  • packages/features/eventtypes/lib/types.ts (2 hunks)
  • packages/lib/server/repository/eventTypeRepository.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/features/eventtypes/lib/types.ts
  • packages/lib/server/repository/eventTypeRepository.ts
  • apps/web/public/static/locales/en/common.json
  • apps/web/test/lib/getSchedule.test.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/bookings/lib/handleNewBooking.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/bookings/lib/handleNewBooking.ts
🧠 Learnings (5)
📓 Common learnings
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.
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx:514-523
Timestamp: 2025-07-22T10:45:26.651Z
Learning: In the Round Robin groups feature, group names are only used within the event type settings UI and are not rendered elsewhere in the application. The user CarinaWolli confirmed this limited scope when asked about potential XSS concerns with direct input handling in the group name field.
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: For large pull requests (>500 lines changed or >10 files touched), advise splitting into smaller, focused PRs by feature, layer, dependency chain, or file/module
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.
📚 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/bookings/lib/handleNewBooking.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/bookings/lib/handleNewBooking.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:

  • packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-07-16T11:46:28.759Z
Learnt from: hariombalhara
PR: calcom/cal.com#22547
File: packages/embeds/embed-core/src/lib/eventHandlers/scrollByDistanceEventHandler.ts:11-14
Timestamp: 2025-07-16T11:46:28.759Z
Learning: In Cal.com's embed system, internal events like "__scrollByDistance" are fired by Cal.com's own code, so runtime validation of event data structure is unnecessary since TypeScript type system guarantees type safety for internal events.

Applied to files:

  • packages/features/bookings/lib/handleNewBooking.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache

Comment on lines +871 to +882
const newLuckyUser = await getLuckyUser({
// find a lucky user that is not already in the luckyUsers array
availableUsers: freeUsers,
// only hosts from the same group
allRRHosts: (
await enrichHostsWithDelegationCredentials({
orgId: firstUserOrgId ?? null,
hosts: eventTypeWithUsers.hosts,
})
).filter((host) => !host.isFixed && userIdsSet.has(host.user.id) && host.groupId === groupId),
eventType,
routingFormResponse,
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.

⚠️ Potential issue

Bug – strict comparison between string and number drops all hosts in a group

groupId originates from Object.entries(luckyUserPools) and is therefore a string.
host.groupId comes from Prisma and is an int (number).
host.groupId === groupId will always be false, so the Round-Robin filter can end up with an empty array and getLuckyUser returns undefined, triggering RoundRobinHostsUnavailableForBooking even when suitable hosts exist.

-).filter((host) => !host.isFixed && userIdsSet.has(host.user.id) && host.groupId === groupId),
+).filter(
+  (host) =>
+    !host.isFixed &&
+    userIdsSet.has(host.user.id) &&
+    host.groupId !== null &&
+    host.groupId === Number(groupId),
+),

Consider typing groupId as number in groupHostsByGroupId and/or casting once at the top of the loop to avoid repeated Number() calls.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const newLuckyUser = await getLuckyUser({
// find a lucky user that is not already in the luckyUsers array
availableUsers: freeUsers,
// only hosts from the same group
allRRHosts: (
await enrichHostsWithDelegationCredentials({
orgId: firstUserOrgId ?? null,
hosts: eventTypeWithUsers.hosts,
})
).filter((host) => !host.isFixed && userIdsSet.has(host.user.id) && host.groupId === groupId),
eventType,
routingFormResponse,
const newLuckyUser = await getLuckyUser({
// find a lucky user that is not already in the luckyUsers array
availableUsers: freeUsers,
// only hosts from the same group
allRRHosts: (
await enrichHostsWithDelegationCredentials({
orgId: firstUserOrgId ?? null,
hosts: eventTypeWithUsers.hosts,
})
).filter(
(host) =>
!host.isFixed &&
userIdsSet.has(host.user.id) &&
host.groupId !== null &&
host.groupId === Number(groupId),
),
eventType,
routingFormResponse,
});
🤖 Prompt for AI Agents
In packages/features/bookings/lib/handleNewBooking.ts around lines 871 to 882,
the comparison between host.groupId (number) and groupId (string) uses strict
equality, causing the filter to always fail and drop all hosts. To fix this,
ensure groupId is typed as a number before the loop or cast groupId to a number
once at the top of the loop, so the comparison host.groupId === groupId
correctly matches numeric values without repeated Number() calls.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Aug 8, 2025

E2E results are ready!

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

bookings area: bookings, availability, timezones, double booking consumer core area: core, team members only ✨ feature New feature or request High priority Created by Linear-GitHub Sync ❗️ migrations contains migration files ready-for-e2e teams area: teams, round robin, collective, managed event-types ui area: UI, frontend, button, form, input

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Round Robin Groups

5 participants