feat: v2 bookings createdAt filter (#20054)

* feat: add before and after updated filter to core handler

* feat: afterCreatedAt and beforeCreatedAt v2 bookings filters

* wip

* finish

* chore: bump libraries

* fix: tests

* refactor: implement feedback
This commit is contained in:
Lauris Skraucis authored and GitHub committed 2025-03-14 15:49:57 +02:00
1 parent 580b03f2b9
commit 13044cb5b0
8 files changed
+5908 -69

No files matched your search

+1 -1
View File
@@ -38,7 +38,7 @@
"@axiomhq/winston": "^1.2.0",
"@calcom/platform-constants": "*",
"@calcom/platform-enums": "*",
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.150",
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.151",
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2",
"@calcom/platform-types": "*",
"@calcom/platform-utils": "*",
@@ -981,6 +981,64 @@ describe("Bookings Endpoints 2024-08-13", () => {
});
});
describe("createdAt filter", () => {
it("should should get bookings after specified createdAt time", async () => {
return request(app.getHttpServer())
.get(`/v2/bookings?afterCreatedAt=${createdRecurringBooking[1].createdAt}`)
.set(CAL_API_VERSION_HEADER, VERSION_2024_08_13)
.expect(200)
.then(async (response) => {
const responseBody: GetBookingsOutput_2024_08_13 = response.body;
expect(responseBody.status).toEqual(SUCCESS_STATUS);
expect(responseBody.data).toBeDefined();
const data: (
| BookingOutput_2024_08_13
| RecurringBookingOutput_2024_08_13
| GetSeatedBookingOutput_2024_08_13
)[] = responseBody.data;
expect(data.length).toEqual(2);
});
});
it("should should get bookings before specified createdAt time", async () => {
return request(app.getHttpServer())
.get(`/v2/bookings?beforeCreatedAt=${createdRecurringBooking[0].createdAt}`)
.set(CAL_API_VERSION_HEADER, VERSION_2024_08_13)
.expect(200)
.then(async (response) => {
const responseBody: GetBookingsOutput_2024_08_13 = response.body;
expect(responseBody.status).toEqual(SUCCESS_STATUS);
expect(responseBody.data).toBeDefined();
const data: (
| BookingOutput_2024_08_13
| RecurringBookingOutput_2024_08_13
| GetSeatedBookingOutput_2024_08_13
)[] = responseBody.data;
expect(data.length).toEqual(3);
});
});
it("should should get bookings in createdAt range", async () => {
return request(app.getHttpServer())
.get(
`/v2/bookings?afterCreatedAt=${createdRecurringBooking[0].createdAt}&beforeCreatedAt=${createdRecurringBooking[1].createdAt}`
)
.set(CAL_API_VERSION_HEADER, VERSION_2024_08_13)
.expect(200)
.then(async (response) => {
const responseBody: GetBookingsOutput_2024_08_13 = response.body;
expect(responseBody.status).toEqual(SUCCESS_STATUS);
expect(responseBody.data).toBeDefined();
const data: (
| BookingOutput_2024_08_13
| RecurringBookingOutput_2024_08_13
| GetSeatedBookingOutput_2024_08_13
)[] = responseBody.data;
expect(data.length).toEqual(2);
});
});
});
it("should should sort bookings by start in descending order", async () => {
return request(app.getHttpServer())
.get(`/v2/bookings?eventTypeId=${eventTypeId}&sortStart=desc`)
@@ -229,8 +229,7 @@ export class BookingsService_2024_08_13 {
const fetchedBookings: { bookings: { id: number }[] } = await getAllUserBookings({
bookingListingByStatus: queryParams.status || [],
skip: queryParams.skip ?? 0,
// note(Lauris): we substract -1 because getAllUSerBookings child function adds +1 for some reason
take: queryParams.take ? queryParams.take - 1 : 100,
take: queryParams.take ?? 100,
filters: this.inputService.transformGetBookingsFilters(queryParams),
ctx: {
user,
@@ -564,7 +563,9 @@ export class BookingsService_2024_08_13 {
throw new BadRequestException(`Booking with uid ${bookingUid} has no event type`);
}
const eventType = await this.eventTypesRepository.getEventTypeByIdIncludeUsersAndTeam(booking.eventTypeId);
const eventType = await this.eventTypesRepository.getEventTypeByIdIncludeUsersAndTeam(
booking.eventTypeId
);
if (!eventType) {
throw new BadRequestException(`Booking with uid ${bookingUid} has no event type`);
}
@@ -632,6 +632,8 @@ export class InputBookingsService_2024_08_13 {
queryParams.eventTypeIds || (queryParams.eventTypeId ? [queryParams.eventTypeId] : undefined),
afterUpdatedDate: queryParams.afterUpdatedAt,
beforeUpdatedDate: queryParams.beforeUpdatedAt,
afterCreatedDate: queryParams.afterCreatedAt,
beforeCreatedDate: queryParams.beforeCreatedAt,
};
}
@@ -152,6 +152,26 @@ export class GetBookingsInput_2024_08_13 {
})
beforeEnd?: string;
@IsOptional()
@IsISO8601({ strict: true }, { message: "fromDate must be a valid ISO 8601 date." })
@ApiProperty({
type: String,
required: false,
description: "Filter bookings that have been created after this date string.",
example: "?afterCreatedAt=2025-03-07T10:00:00.000Z",
})
afterCreatedAt?: string;
@IsOptional()
@IsISO8601({ strict: true }, { message: "toDate must be a valid ISO 8601 date." })
@ApiProperty({
type: String,
required: false,
description: "Filter bookings that have been created before this date string.",
example: "?beforeCreatedAt=2025-03-14T11:00:00.000Z",
})
beforeCreatedAt?: string;
@IsOptional()
@IsISO8601({ strict: true }, { message: "fromDate must be a valid ISO 8601 date." })
@ApiProperty({
@@ -336,6 +336,24 @@ export async function getBookings({
},
]
: []),
...(filters?.afterCreatedDate
? [
{
createdAt: {
gte: dayjs.utc(filters.afterCreatedDate).toDate(),
},
},
]
: []),
...(filters?.beforeCreatedDate
? [
{
createdAt: {
lte: dayjs.utc(filters.beforeCreatedDate).toDate(),
},
},
]
: []),
],
};
@@ -14,6 +14,8 @@ export const ZGetInputSchema = z.object({
beforeEndDate: z.string().optional(),
afterUpdatedDate: z.string().optional(),
beforeUpdatedDate: z.string().optional(),
afterCreatedDate: z.string().optional(),
beforeCreatedDate: z.string().optional(),
}),
limit: z.number().min(1).max(100),
offset: z.number(),
+5803 -65
View File
File diff suppressed because it is too large. Load diff