From 701c4cdb768e007e9f5f0b938c31d4b9f08b8d83 Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Wed, 7 Jan 2026 05:41:09 -0300 Subject: [PATCH] perf: batch booking queries in output service (#25900) Replace N sequential queries with single batch queries in: - getOutputRecurringBookings - getOutputRecurringSeatedBookings Uses existing batch repository methods. Reduces database roundtrips from O(n) to O(1) for recurring booking lookups Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com> --- .../2024-08-13/services/output.service.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts index 96f2b4f629..d3033eeb1d 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts @@ -203,17 +203,17 @@ export class OutputBookingsService_2024_08_13 { } async getOutputRecurringBookings(bookingsIds: number[]) { - const transformed = []; - - for (const bookingId of bookingsIds) { - const databaseBooking = await this.bookingsRepository.getByIdWithAttendeesAndUserAndEvent(bookingId); + const databaseBookings = await this.bookingsRepository.getByIdsWithAttendeesAndUserAndEvent(bookingsIds); + + const bookingsMap = new Map(databaseBookings.map(booking => [booking.id, booking])); + + const transformed = bookingsIds.map(bookingId => { + const databaseBooking = bookingsMap.get(bookingId); if (!databaseBooking) { throw new Error(`Booking with id=${bookingId} was not found in the database`); } - - transformed.push(this.getOutputRecurringBooking(databaseBooking)); - } - + return this.getOutputRecurringBooking(databaseBooking); + }); return transformed.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()); } @@ -362,17 +362,17 @@ export class OutputBookingsService_2024_08_13 { } async getOutputRecurringSeatedBookings(bookingsIds: number[], showAttendees: boolean) { - const transformed = []; - - for (const bookingId of bookingsIds) { - const databaseBooking = - await this.bookingsRepository.getByIdWithAttendeesWithBookingSeatAndUserAndEvent(bookingId); + const databaseBookings = await this.bookingsRepository.getByIdsWithAttendeesWithBookingSeatAndUserAndEvent(bookingsIds); + + const bookingsMap = new Map(databaseBookings.map(booking => [booking.id, booking])); + + const transformed = bookingsIds.map(bookingId => { + const databaseBooking = bookingsMap.get(bookingId); if (!databaseBooking) { throw new Error(`Booking with id=${bookingId} was not found in the database`); } - - transformed.push(this.getOutputRecurringSeatedBooking(databaseBooking, showAttendees)); - } + return this.getOutputRecurringSeatedBooking(databaseBooking, showAttendees); + }); return transformed.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()); }