fix(slots): widen booking prefetch window to account for event buffers#29540
fix(slots): widen booking prefetch window to account for event buffers#29540GAURAV07C wants to merge 5 commits into
Conversation
Previously, findAllExistingBookingsForEventTypeBetween fetched bookings only within the raw requested range. Bookings ending just before the range start were ignored, even if their after-event buffer overlapped the requested window. This caused the slots endpoint to offer times that booking validation would reject with no_available_users_found_error. Fix: Apply the same max-buffer widening (getDefinedBufferTimes) to the prefetch query that getBusyTimes already applies when fetching its own bookings.
|
Welcome to Cal.diy, @GAURAV07C! Thanks for opening this pull request. A few things to keep in mind:
A maintainer will review your PR soon. Thanks for contributing! |
📝 WalkthroughWalkthroughThe viewer slots util now imports getDefinedBufferTimes and uses it in calculateHostsAndAvailabilities to compute a maxBuffer and expand the date range passed to bookingRepo.findAllExistingBookingsForEventTypeBetween (subtracting from startDate and adding to endDate). A separate file, BookingRepository.ts, has a minor non-functional whitespace adjustment between two type declarations. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/repositories/BookingRepository.ts (1)
700-711:⚠️ Potential issue | 🟠 MajorFix double-application of maxBuffer in booking overlap queries (performance hit)
BookingRepository._findAllExistingBookingsForEventTypeBetweenexpandsstartDate/endDatebymaxBuffer(viagetDefinedBufferTimes()), butpackages/features/busyTimes/services/getBusyTimes.tsalready expands the same window withstartTimeAdjustedWithMaxBuffer/endTimeAdjustedWithMaxBufferbefore callingfindAllExistingBookingsForEventTypeBetween, causing the effective query window to be ~2×maxBuffer.Callers like
packages/trpc/server/routers/viewer/slots/util.tspass unbufferedstartTimeDate/endTimeDate, so they only get a single expansion.Adjust either:
- remove the caller-side maxBuffer adjustment in
getBusyTimes.ts, or- move buffer-expansion responsibility so it happens in exactly one place.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/features/bookings/repositories/BookingRepository.ts` around lines 700 - 711, The repository and the busy-times service are both expanding the query window by maxBuffer which doubles the buffer; centralize buffer expansion in BookingRepository._findAllExistingBookingsForEventTypeBetween and remove the caller-side expansion in packages/features/busyTimes/services/getBusyTimes.ts. Concretely, delete the startTimeAdjustedWithMaxBuffer / endTimeAdjustedWithMaxBuffer computation and any use of those variables in getBusyTimes.ts, and ensure getBusyTimes and its callers pass the raw startDate/endDate into BookingRepository._findAllExistingBookingsForEventTypeBetween so the repository’s existing maxBuffer logic (definedBufferTimes, maxBuffer, and sharedQuery) remains the single source of truth for buffer expansion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/features/bookings/repositories/BookingRepository.ts`:
- Around line 700-711: The repository and the busy-times service are both
expanding the query window by maxBuffer which doubles the buffer; centralize
buffer expansion in
BookingRepository._findAllExistingBookingsForEventTypeBetween and remove the
caller-side expansion in packages/features/busyTimes/services/getBusyTimes.ts.
Concretely, delete the startTimeAdjustedWithMaxBuffer /
endTimeAdjustedWithMaxBuffer computation and any use of those variables in
getBusyTimes.ts, and ensure getBusyTimes and its callers pass the raw
startDate/endDate into
BookingRepository._findAllExistingBookingsForEventTypeBetween so the
repository’s existing maxBuffer logic (definedBufferTimes, maxBuffer, and
sharedQuery) remains the single source of truth for buffer expansion.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b8747b50-33db-4746-ac71-594a1a2f7895
📒 Files selected for processing (1)
packages/features/bookings/repositories/BookingRepository.ts
|
@GAURAV07C please attach before/after demo of ur changes! |
Test setup:
Before fix: {"time":"2026-06-12T04:00:00.000Z"} 04:00 UTC = 09:30 IST
After fix: {"time":"2026-06-12T04:30:00.000Z"} 04:30 UTC = 10:00 IST
The 09:30 slot was previously returned even though the host was busy until 09:45 because of the after-event buffer. After widening the booking lookup range to include buffer-overlapping bookings, the invalid 09:30 slot is no longer returned and the first available slot is correctly shown as 10:00. 04:30 UTC = 10:00 IST So the invalid 09:30 slot is no longer exposed after widening the booking lookup range to include buffer-overlapping bookings. |
|
@bandhan-majumder please check. let me know what you think ?
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/trpc/server/routers/viewer/slots/util.ts (1)
733-739: ⚡ Quick winPrefer native
Datemath for buffer padding in this non-timezone path.At Line 738 and Line 739,
dayjsis only used for minute arithmetic onDateobjects. Switching to nativeDatekeeps this path lighter and aligns with the repo rule.♻️ Proposed refactor
- const definedBufferTimes = getDefinedBufferTimes(); - const maxBuffer = definedBufferTimes[definedBufferTimes.length - 1]; + const maxBuffer = Math.max(...getDefinedBufferTimes()); const [currentBookingsAllUsers, outOfOfficeDaysAllUsers] = await Promise.all([ bookingRepo.findAllExistingBookingsForEventTypeBetween({ - startDate: dayjs(startTimeDate).subtract(maxBuffer, "minute").toDate(), - endDate: dayjs(endTimeDate).add(maxBuffer, "minute").toDate(), + startDate: new Date(startTimeDate.getTime() - maxBuffer * 60_000), + endDate: new Date(endTimeDate.getTime() + maxBuffer * 60_000), eventTypeId: eventType.id, seatedEvent: Boolean(eventType.seatsPerTimeSlot), userIdAndEmailMap, }),As per coding guidelines,
Use date-fns or native Date instead of Day.js when timezone awareness isn't needed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/trpc/server/routers/viewer/slots/util.ts` around lines 733 - 739, The code uses dayjs just to add/subtract minutes for buffer padding; replace that with native Date arithmetic: compute start = new Date(startTimeDate.getTime() - maxBuffer * 60_000) and end = new Date(endTimeDate.getTime() + maxBuffer * 60_000) and pass those to bookingRepo.findAllExistingBookingsForEventTypeBetween (and any other call using the dayjs versions). Keep getDefinedBufferTimes and maxBuffer logic unchanged; remove the dayjs(startTimeDate).subtract(...) / dayjs(endTimeDate).add(...) usage and use the native Date results instead.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/trpc/server/routers/viewer/slots/util.ts`:
- Around line 733-739: The code uses dayjs just to add/subtract minutes for
buffer padding; replace that with native Date arithmetic: compute start = new
Date(startTimeDate.getTime() - maxBuffer * 60_000) and end = new
Date(endTimeDate.getTime() + maxBuffer * 60_000) and pass those to
bookingRepo.findAllExistingBookingsForEventTypeBetween (and any other call using
the dayjs versions). Keep getDefinedBufferTimes and maxBuffer logic unchanged;
remove the dayjs(startTimeDate).subtract(...) / dayjs(endTimeDate).add(...)
usage and use the native Date results instead.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 38d7d389-8c10-4631-b7e7-ca825c54922a
📒 Files selected for processing (2)
packages/features/bookings/repositories/BookingRepository.tspackages/trpc/server/routers/viewer/slots/util.ts
✅ Files skipped from review due to trivial changes (1)
- packages/features/bookings/repositories/BookingRepository.ts


Problem
The slots endpoint was offering times that booking validation would reject with
no_available_users_found_error.Root cause
findAllExistingBookingsForEventTypeBetweenfetched bookings only within the raw requested range. If a booking ended just before the range start, its after-event buffer was ignored — making the slot appear free when it wasn't.This caused a mismatch:
getBusyTimes): correctly detected themResult: Users were shown slots (e.g. 9:30) that later failed during booking.
Fix
#29532
Applied buffer-aware widening to the booking prefetch query using
getDefinedBufferTimes()max buffer, aligning it withgetBusyTimesbehavior.Now the slot generation includes bookings whose buffers overlap the requested time window.
Steps to Reproduce
no_available_users_found_errorChanges
packages/features/bookings/repositories/BookingRepository.tsImpact