cal.com
cal.com copied to clipboard
feat: add multi-host assignment for round robin bookings
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
maxRoundRobinHostsconfig (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
Booking result - Multiple hosts assigned
How should this be tested?
Test Scenario 1 - Multi-host assignment:
- Create Round Robin event type with 3+ hosts
- Set
maxRoundRobinHosts = 3 - Create a booking when all hosts are available
- Expected: Booking created with 3 hosts assigned
Test Scenario 2 - Partial availability:
- Round Robin with
maxRoundRobinHosts = 4 - Only 2 hosts available at selected time
- Expected: Booking created with 2 hosts (assigns all available up to max)
Test Scenario 3 - Default behavior (regression):
- Create Round Robin event type
- Leave
maxRoundRobinHostsempty (null/default) - Create booking
- Expected: Only 1 host assigned (existing behavior preserved)
Performance improvements
- Replace N calls to
getLuckyUser()with singlegetOrderedListOfLuckyUsers()call (reduces DB queries from O(n) to O(1) per group) - Parallelize recurring slot availability checks with
Promise.all - Pre-compute
enrichedHosts,userIdsSet, andfirstUserOrgIdoutside 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.
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Review | Updated (UTC) |
|---|---|---|---|
| cal-companion | Preview, Comment | Dec 16, 2025 2:48pm |