perf: Improve loading existing bookings via API (#16410)

This commit is contained in:
Keith Williams
2024-08-30 11:10:44 +01:00
committed by GitHub
parent 57e9ef7320
commit f3462776e8
2 changed files with 76 additions and 66 deletions
+71 -55
View File
@@ -1,4 +1,5 @@
import type { Booking, EventType } from "@prisma/client";
import { Prisma } from "@prisma/client";
import { getBusyCalendarTimes } from "@calcom/core/CalendarManager";
import dayjs from "@calcom/dayjs";
@@ -8,7 +9,7 @@ import logger from "@calcom/lib/logger";
import { getPiiFreeBooking } from "@calcom/lib/piiFreeData";
import { performance } from "@calcom/lib/server/perfObserver";
import prisma from "@calcom/prisma";
import type { Prisma, SelectedCalendar } from "@calcom/prisma/client";
import type { SelectedCalendar } from "@calcom/prisma/client";
import { BookingStatus } from "@calcom/prisma/enums";
import { stringToDayjs } from "@calcom/prisma/zod-utils";
import type { EventBusyDetails, IntervalLimit } from "@calcom/types/Calendar";
@@ -106,63 +107,78 @@ export async function getBusyTimes(params: {
// Will keep support for retrieving a user's bookings if the caller does not already supply them.
// This function is called from multiple places but we aren't refactoring all of them at this moment
// to avoid potential side effects.
const bookings = params.currentBookings
? params.currentBookings
: await prisma.booking.findMany({
where: {
OR: [
// User is primary host (individual events, or primary organizer)
{
...sharedQuery,
userId,
},
// The current user has a different booking at this time he/she attends
{
...sharedQuery,
attendees: {
some: {
email: userEmail,
},
},
},
{
startTime: { lte: endTimeDate },
endTime: { gte: startTimeDate },
eventType: {
id: eventTypeId,
requiresConfirmation: true,
requiresConfirmationWillBlockSlot: true,
},
status: {
in: [BookingStatus.PENDING],
},
},
],
},
let bookings = params.currentBookings;
if (!bookings) {
const bookingsSelect = Prisma.validator<Prisma.BookingSelect>()({
id: true,
uid: true,
userId: true,
startTime: true,
endTime: true,
title: true,
eventType: {
select: {
id: true,
uid: true,
userId: true,
startTime: true,
endTime: true,
title: true,
eventType: {
select: {
id: true,
afterEventBuffer: true,
beforeEventBuffer: true,
seatsPerTimeSlot: true,
},
},
...(seatedEvent && {
_count: {
select: {
seatsReferences: true,
},
},
}),
afterEventBuffer: true,
beforeEventBuffer: true,
seatsPerTimeSlot: true,
},
});
},
...(seatedEvent && {
_count: {
select: {
seatsReferences: true,
},
},
}),
});
const currentBookingsAllUsersQueryOne = prisma.booking.findMany({
where: {
// User is primary host (individual events, or primary organizer)
...sharedQuery,
userId,
},
select: bookingsSelect,
});
const currentBookingsAllUsersQueryTwo = prisma.booking.findMany({
where: {
...sharedQuery,
attendees: {
some: {
email: userEmail,
},
},
},
select: bookingsSelect,
});
const currentBookingsAllUsersQueryThree = prisma.booking.findMany({
where: {
startTime: { lte: endTimeDate },
endTime: { gte: startTimeDate },
eventType: {
id: eventTypeId,
requiresConfirmation: true,
requiresConfirmationWillBlockSlot: true,
},
status: {
in: [BookingStatus.PENDING],
},
},
select: bookingsSelect,
});
const [resultOne, resultTwo, resultThree] = await Promise.all([
currentBookingsAllUsersQueryOne,
currentBookingsAllUsersQueryTwo,
currentBookingsAllUsersQueryThree,
]);
bookings = [...resultOne, ...resultTwo, ...resultThree];
}
const bookingSeatCountMap: { [x: string]: number } = {};
const busyTimes = bookings.reduce(
@@ -442,7 +442,7 @@ export async function getAvailableSlots({ input, ctx }: GetScheduleOptions): Pro
};
const allUserIds = usersWithCredentials.map((user) => user.id);
const bookingsSelect = {
const bookingsSelect = Prisma.validator<Prisma.BookingSelect>()({
id: true,
uid: true,
userId: true,
@@ -468,7 +468,7 @@ export async function getAvailableSlots({ input, ctx }: GetScheduleOptions): Pro
},
},
}),
};
});
const currentBookingsAllUsersQueryOne = prisma.booking.findMany({
where: {
@@ -477,9 +477,7 @@ export async function getAvailableSlots({ input, ctx }: GetScheduleOptions): Pro
in: allUserIds,
},
},
select: {
...bookingsSelect,
},
select: bookingsSelect,
});
const currentBookingsAllUsersQueryTwo = prisma.booking.findMany({
@@ -493,9 +491,7 @@ export async function getAvailableSlots({ input, ctx }: GetScheduleOptions): Pro
},
},
},
select: {
...bookingsSelect,
},
select: bookingsSelect,
});
const currentBookingsAllUsersQueryThree = prisma.booking.findMany({
@@ -511,9 +507,7 @@ export async function getAvailableSlots({ input, ctx }: GetScheduleOptions): Pro
in: [BookingStatus.PENDING],
},
},
select: {
...bookingsSelect,
},
select: bookingsSelect,
});
const [resultOne, resultTwo, resultThree] = await Promise.all([