fix: increment iCalSequence when changing booking location (#22847)

* fix: increment iCalSequence when changing booking location

- Add iCalSequence parameter to buildCalEventFromBooking function
- Update editLocation handler to increment sequence by 1 in CalendarEvent
- Update database with incremented iCalSequence when location changes
- Update buildCalEventFromBooking test to include new fields
- Ensures ICS files properly update existing calendar events instead of creating duplicates

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* `BookingRepository.updateLocationById` to accept responses and iCalSequence

* `editLocation.handler` use `BookingRepository`

* Update iCalSequence

* Use iCalSequence from booking param

* Add iCalUID to evt object

* Clean up

* Fix test

* Fix test

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2025-07-31 20:58:48 +01:00
1 parent 1d1a242a72
commit f81bb92beb
4 files changed
+29 -8

No files matched your search

@@ -52,6 +52,8 @@ const createBooking = (overrides = {}) => ({
},
destinationCalendar: null,
user: null,
iCalSequence: 0,
iCalUID: "icaluid",
...overrides,
});
@@ -121,6 +123,10 @@ describe("buildCalEventFromBooking", () => {
destinationCalendar: [],
seatsPerTimeSlot: booking.eventType?.seatsPerTimeSlot,
seatsShowAttendees: true,
customReplyToEmail: undefined,
hideOrganizerEmail: undefined,
iCalSequence: 0,
iCalUID: booking.iCalUID,
});
expect(parseRecurringEvent).toHaveBeenCalledWith(booking.eventType?.recurringEvent);
@@ -135,6 +141,8 @@ describe("buildCalEventFromBooking", () => {
userPrimaryEmail: null,
attendees: [],
eventType: null,
iCalUID: "icaluid",
iCalSequence: 0,
});
const organizer = createOrganizer({ name: null, locale: null });
@@ -170,6 +178,10 @@ describe("buildCalEventFromBooking", () => {
destinationCalendar: [],
seatsPerTimeSlot: undefined,
seatsShowAttendees: undefined,
customReplyToEmail: undefined,
hideOrganizerEmail: undefined,
iCalSequence: 0,
iCalUID: "icaluid",
});
// @ts-expect-error - locale is set in mock
@@ -192,6 +204,8 @@ describe("buildCalEventFromBooking", () => {
credentialId: 1,
},
},
iCalUID: "icaluid",
iCalSequence: 0,
});
const organizer = createOrganizer();
+4
View File
@@ -55,6 +55,8 @@ type Booking = {
} | null;
attendees: Attendee[];
eventType: EventType | null;
iCalUID: string | null;
iCalSequence: number;
};
export const buildCalEventFromBooking = async ({
@@ -110,5 +112,7 @@ export const buildCalEventFromBooking = async ({
seatsPerTimeSlot: booking.eventType?.seatsPerTimeSlot,
seatsShowAttendees: booking.eventType?.seatsShowAttendees,
customReplyToEmail: booking.eventType?.customReplyToEmail,
iCalUID: booking.iCalUID ?? booking.uid,
iCalSequence: booking.iCalSequence ?? 0,
};
};
+5 -1
View File
@@ -522,13 +522,15 @@ export class BookingRepository {
async updateLocationById({
where: { id },
data: { location, metadata, referencesToCreate },
data: { location, metadata, referencesToCreate, responses, iCalSequence },
}: {
where: { id: number };
data: {
location: string;
metadata: Record<string, unknown>;
referencesToCreate: Prisma.BookingReferenceCreateInput[];
responses?: Record<string, unknown>;
iCalSequence?: number;
};
}) {
await this.prismaClient.booking.update({
@@ -538,6 +540,8 @@ export class BookingRepository {
data: {
location,
metadata,
...(responses && { responses }),
...(iCalSequence !== undefined && { iCalSequence }),
references: {
create: referencesToCreate,
},
@@ -10,6 +10,7 @@ import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getUsersCredentialsIncludeServiceAccountKey } from "@calcom/lib/server/getUsersCredentials";
import { getTranslation } from "@calcom/lib/server/i18n";
import { BookingRepository } from "@calcom/lib/server/repository/booking";
import { CredentialRepository } from "@calcom/lib/server/repository/credential";
import { UserRepository } from "@calcom/lib/server/repository/user";
import { prisma } from "@calcom/prisma";
@@ -97,19 +98,16 @@ async function updateBookingLocationInDb({
};
});
await prisma.booking.update({
where: {
id: booking.id,
},
const bookingRepository = new BookingRepository(prisma);
await bookingRepository.updateLocationById({
where: { id: booking.id },
data: {
location: evt.location,
metadata: {
...(typeof booking.metadata === "object" && booking.metadata),
...bookingMetadataUpdate,
},
references: {
create: referencesToCreate,
},
referencesToCreate,
responses: {
...(typeof booking.responses === "object" && booking.responses),
location: {
@@ -117,6 +115,7 @@ async function updateBookingLocationInDb({
optionValue: "",
},
},
iCalSequence: (evt.iCalSequence || 0) + 1,
},
});
}