cal.com icon indicating copy to clipboard operation
cal.com copied to clipboard

feat: add multi-host assignment for round robin bookings

Open pedroccastro opened this issue 3 weeks ago • 1 comments

What does this PR do?

This PR implements a new feature for Round Robin event types: optional multi-host assignment per booking.

Current behavior:

  • Round Robin always assigns exactly 1 host per booking
  • Collective requires all hosts to be available

New behavior:

  • New maxRoundRobinHosts config (1-20, default: 1)
  • Uses union availability (same as current RR logic)
  • At booking confirmation, assigns up to N available hosts
  • Minimum always 1 (preserves default RR behavior)

Example scenario:

  • Event type has 5 interviewers
  • Candidate selects a time where 4 are available
  • If maxRoundRobinHosts = 3 → 3 hosts automatically assigned

Fixes #25491 | Linear: CAL-6840

Key Changes:

Layer File(s) Change
Schema schema.prisma Add maxRoundRobinHosts Int? with Zod validation
API v2 DTOs (create, update, output) Add field with @Min(1) @Max(20) validation
Booking Logic RegularBookingService.ts Use getOrderedListOfLuckyUsers() for multi-host selection
tRPC eventTypeRepository.ts Add field to select statements
Form useEventTypeForm.ts Add to defaultValues
UI EventTeamAssignmentTab.tsx Add NumberInput for configuration
i18n common.json Add translation keys

Visual Demo

UI - New configuration field in Round Robin Hosts section

rr_max_hosts

Booking result - Multiple hosts assigned

max_hosts_response

How should this be tested?

Test Scenario 1 - Multi-host assignment:

  1. Create Round Robin event type with 3+ hosts
  2. Set maxRoundRobinHosts = 3
  3. Create a booking when all hosts are available
  4. Expected: Booking created with 3 hosts assigned

Test Scenario 2 - Partial availability:

  1. Round Robin with maxRoundRobinHosts = 4
  2. Only 2 hosts available at selected time
  3. Expected: Booking created with 2 hosts (assigns all available up to max)

Test Scenario 3 - Default behavior (regression):

  1. Create Round Robin event type
  2. Leave maxRoundRobinHosts empty (null/default)
  3. Create booking
  4. Expected: Only 1 host assigned (existing behavior preserved)

Performance improvements

  • Replace N calls to getLuckyUser() with single getOrderedListOfLuckyUsers() call (reduces DB queries from O(n) to O(1) per group)
  • Parallelize recurring slot availability checks with Promise.all
  • Pre-compute enrichedHosts, userIdsSet, and firstUserOrgId outside loops

Mandatory Tasks

  • [x] I have self-reviewed the code
  • [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change.
  • [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

pedroccastro avatar Dec 08 '25 18:12 pedroccastro

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

Project Deployment Review Updated (UTC)
cal-companion Ready Ready Preview, Comment Dec 16, 2025 2:48pm
2 Skipped Deployments
Project Deployment Review Updated (UTC)
cal Ignored Ignored Dec 16, 2025 2:48pm
cal-eu Ignored Ignored Dec 16, 2025 2:48pm

vercel[bot] avatar Dec 08 '25 21:12 vercel[bot]