From 4e92b6edebb58dece2b9815760387526d5203a17 Mon Sep 17 00:00:00 2001 From: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Date: Tue, 29 Jul 2025 12:10:21 -0400 Subject: [PATCH] chore: Log availability snapshot when booking is created (#22782) * Add userAvailability type * Add user availability to return value of getUsersAvailability * Log availabilitySnapshot when booking is created * Type fix --- packages/features/bookings/lib/handleNewBooking.ts | 8 +++++++- .../bookings/lib/handleNewBooking/ensureAvailableUsers.ts | 6 ++++-- packages/features/bookings/lib/handleNewBooking/types.ts | 2 ++ packages/lib/getUserAvailability.ts | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index 0a03184396..e14825844c 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -658,6 +658,7 @@ async function handler( let luckyUserResponse; let isFirstSeat = true; + let availableUsers: IsFixedAwareUser[] = []; if (eventType.seatsPerTimeSlot) { const booking = await prisma.booking.findFirst({ @@ -757,7 +758,6 @@ async function handler( } if (!input.bookingData.allRecurringDates || input.bookingData.isFirstRecurringSlot) { - let availableUsers: IsFixedAwareUser[] = []; try { availableUsers = await ensureAvailableUsers( { ...eventTypeWithUsers, users: [...qualifiedRRUsers, ...fixedUsers] as IsFixedAwareUser[] }, @@ -1391,6 +1391,12 @@ async function handler( if (booking?.userId) { const usersRepository = new UsersRepository(); await usersRepository.updateLastActiveAt(booking.userId); + const organizerUserAvailability = availableUsers.find((user) => user.id === booking?.userId); + + logger.info(`Booking created`, { + bookingUid: booking.uid, + availabilitySnapshot: organizerUserAvailability?.availabilityData, + }); } // If it's a round robin event, record the reason for the host assignment diff --git a/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts b/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts index 6c9a85b2d5..81e0ad84de 100644 --- a/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts +++ b/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts @@ -99,6 +99,7 @@ const _ensureAvailableUsers = async ( afterEventBuffer: eventType.afterEventBuffer, bypassBusyCalendarTimes: false, shouldServeCache, + withSource: true, }, initialData: { eventType, @@ -210,7 +211,8 @@ const _ensureAvailableUsers = async ( } } - usersAvailability.forEach(({ oooExcludedDateRanges: dateRanges, busy: bufferedBusyTimes }, index) => { + usersAvailability.forEach((userAvailability, index) => { + const { oooExcludedDateRanges: dateRanges, busy: bufferedBusyTimes } = userAvailability; const user = eventType.users[index]; loggerWithEventDetails.debug( @@ -239,7 +241,7 @@ const _ensureAvailableUsers = async ( eventLength: duration, }); if (!foundConflict) { - availableUsers.push(user); + availableUsers.push({ ...user, availabilityData: userAvailability }); } } catch (error) { loggerWithEventDetails.error("Unable set isAvailableToBeBooked. Using true. ", error); diff --git a/packages/features/bookings/lib/handleNewBooking/types.ts b/packages/features/bookings/lib/handleNewBooking/types.ts index 83f40475bc..5456ccfece 100644 --- a/packages/features/bookings/lib/handleNewBooking/types.ts +++ b/packages/features/bookings/lib/handleNewBooking/types.ts @@ -4,6 +4,7 @@ import type { TFunction } from "i18next"; import type { EventTypeAppsList } from "@calcom/app-store/utils"; import type { PaymentAppData } from "@calcom/lib/getPaymentAppData"; +import type { GetUserAvailabilityResult } from "@calcom/lib/getUserAvailability"; import type { userSelect } from "@calcom/prisma"; import type { SelectedCalendar } from "@calcom/prisma/client"; import type { CredentialForCalendarService } from "@calcom/types/Credential"; @@ -40,6 +41,7 @@ export type IsFixedAwareUser = User & { weight?: number; userLevelSelectedCalendars: SelectedCalendar[]; allSelectedCalendars: SelectedCalendar[]; + availabilityData?: GetUserAvailabilityResult; }; export type { PaymentAppData }; diff --git a/packages/lib/getUserAvailability.ts b/packages/lib/getUserAvailability.ts index 0bc3f97179..5654bc7685 100644 --- a/packages/lib/getUserAvailability.ts +++ b/packages/lib/getUserAvailability.ts @@ -266,7 +266,7 @@ export type CurrentSeats = Awaited>; export const getCurrentSeats = withReporting(_getCurrentSeats, "getCurrentSeats"); -type GetUserAvailabilityResult = ReturnType; +export type GetUserAvailabilityResult = Awaited>; /** This should be called getUsersWorkingHoursAndBusySlots (...and remaining seats, and final timezone) */ const _getUserAvailability = async function getUsersWorkingHoursLifeTheUniverseAndEverythingElse(