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:
1 parent
580b03f2b9
commit
13044cb5b0
8 files changed
+5908
-69
No files matched your search
@@ -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(),
|
||||
|
||||
Reference in new issue
Block a user