/claim #16378

What does this PR do?

When a host reschedules a booking, the system now checks whether attendees are Cal.com users and fetches their busy times. Only mutually available slots are shown in the reschedule calendar.

Before: Host could freely pick any time when rescheduling, even if the guest was busy. After: Guest’s existing bookings are fetched and blocked automatically.

How it works

  1. BookingRepository.findByUidIncludeAttendeeEmails() — gets attendee emails from the original booking
  2. UserRepository.findByEmails() — resolves emails to Cal.com users (primary + verified secondary emails, case-insensitive, deduplicated via Promise.all)
  3. BookingRepository.findByUserIdsAndDateRange() — fetches guest bookings in the date range, with excludeUid filtering at the database level
  4. Guest busy times merged into host’s availability view

Scope

Per @CarinaWolli’s clarification: this applies only when the event type owner reschedules. If attendees reschedule, all slots are shown.

  • COLLECTIVE scheduling: skipped (already coordinated)
  • Non-Cal.com guests: ignored (no availability to check)
  • Multiple Cal.com guests: all busy times merged
  • ROUND_ROBIN: fully supported
  • Error handling: graceful degradation (returns [] on failure, never blocks rescheduling)

Demo

▶️ Watch Demo Video

Tests

30 tests passing (3 new test files, 631 lines added):

  • UserRepository.findByEmails — primary/secondary email lookup, dedup, normalization (6 tests)
  • BookingRepository.findByUserIdsAndDateRange — userId/email query, excludeUid, empty input (6 tests)
  • BookingRepository.findByUidIncludeAttendeeEmails — uid lookup, null handling (2 tests)
  • _getGuestBusyTimesForReschedule — early exits, busy time collection, multi-guest, error handling (13 tests)
  • Existing tests — unchanged and passing (6 tests)

Self-review notes

  • Uses select (not include) per cal.com conventions
  • Uses withReporting wrapper for observability
  • Queries run in Promise.all for zero added latency
  • excludeUid filtering at database level (not JS post-filter)

Claim

Total prize pool $200
Total paid $0
Status Pending
Submitted March 28, 2026
Last updated March 28, 2026

Contributors

BC

Bcornish

@bcornish1797

100%

Sponsors

CA

Cal.com, Inc.

@cal

$200