feat: v2 GET bookings updated at filters and sort (#19133)
* fix: make Booking.updatedAt update automatically * feat: return updatedAt by bookings endpoints * feat: GET bookings beforeUpdatedAt, afterUpdatedAt, sortUpdated params * docs: api * chore: bump platform-libraries * refactor: sortUpdated -> sortUpdatedAt query param * chore: delete wrong migration
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
"@axiomhq/winston": "^1.2.0",
|
||||
"@calcom/platform-constants": "*",
|
||||
"@calcom/platform-enums": "*",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.94",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.95",
|
||||
"@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2",
|
||||
"@calcom/platform-types": "*",
|
||||
"@calcom/platform-utils": "*",
|
||||
|
||||
@@ -396,6 +396,12 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
expect(createdAtDate.getTime()).toBeGreaterThanOrEqual(beforeCreate.getTime());
|
||||
expect(createdAtDate.getTime()).toBeLessThanOrEqual(afterCreate.getTime());
|
||||
|
||||
// Check updatedAt date is between the time of the request and after the request
|
||||
expect(data.updatedAt).toBeDefined();
|
||||
const updatedAtDate = data.updatedAt ? new Date(data.updatedAt) : null;
|
||||
expect(updatedAtDate?.getTime()).toBeGreaterThanOrEqual(beforeCreate.getTime());
|
||||
expect(updatedAtDate?.getTime()).toBeLessThanOrEqual(afterCreate.getTime());
|
||||
|
||||
expect(data.metadata).toEqual(body.metadata);
|
||||
createdBooking = data;
|
||||
} else {
|
||||
@@ -869,7 +875,63 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
|
||||
it("should should get bookings by before specified end time", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/bookings?afterStart=${createdRecurringBooking[0].start}`)
|
||||
.get(`/v2/bookings?beforeEnd=${createdRecurringBooking[0].end}`)
|
||||
.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 after specified update time", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/bookings?afterUpdatedAt=${createdRecurringBooking[1].updatedAt}`)
|
||||
.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 update time", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/bookings?beforeUpdatedAt=${createdRecurringBooking[0].updatedAt}`)
|
||||
.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 update range", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(
|
||||
`/v2/bookings?afterUpdatedAt=${createdRecurringBooking[0].updatedAt}&beforeUpdatedAt=${createdRecurringBooking[2].updatedAt}`
|
||||
)
|
||||
.set(CAL_API_VERSION_HEADER, VERSION_2024_08_13)
|
||||
.expect(200)
|
||||
.then(async (response) => {
|
||||
@@ -1004,6 +1066,46 @@ describe("Bookings Endpoints 2024-08-13", () => {
|
||||
expect(data[1].start).toEqual(createdBooking.start);
|
||||
});
|
||||
});
|
||||
|
||||
it("should should sort bookings by updated in descending order", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/bookings?eventTypeId=${eventTypeId}&sortUpdatedAt=desc`)
|
||||
.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);
|
||||
expect(data[0].updatedAt).toEqual(createdBooking.updatedAt);
|
||||
expect(data[1].updatedAt).toEqual(bookingInThePast.updatedAt?.toISOString());
|
||||
});
|
||||
});
|
||||
|
||||
it("should should sort bookings by updated in ascending order", async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get(`/v2/bookings?eventTypeId=${eventTypeId}&sortUpdatedAt=asc`)
|
||||
.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);
|
||||
expect(data[0].updatedAt).toEqual(bookingInThePast.updatedAt?.toISOString());
|
||||
expect(data[1].updatedAt).toEqual(createdBooking.updatedAt);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("reschedule bookings", () => {
|
||||
|
||||
@@ -463,11 +463,18 @@ export class InputBookingsService_2024_08_13 {
|
||||
teamIds: queryParams.teamsIds || (queryParams.teamId ? [queryParams.teamId] : undefined),
|
||||
eventTypeIds:
|
||||
queryParams.eventTypeIds || (queryParams.eventTypeId ? [queryParams.eventTypeId] : undefined),
|
||||
afterUpdatedDate: queryParams.afterUpdatedAt,
|
||||
beforeUpdatedDate: queryParams.beforeUpdatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
transformGetBookingsSort(queryParams: GetBookingsInput_2024_08_13) {
|
||||
if (!queryParams.sortStart && !queryParams.sortEnd && !queryParams.sortCreated) {
|
||||
if (
|
||||
!queryParams.sortStart &&
|
||||
!queryParams.sortEnd &&
|
||||
!queryParams.sortCreated &&
|
||||
!queryParams.sortUpdatedAt
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -475,6 +482,7 @@ export class InputBookingsService_2024_08_13 {
|
||||
sortStart: queryParams.sortStart,
|
||||
sortEnd: queryParams.sortEnd,
|
||||
sortCreated: queryParams.sortCreated,
|
||||
sortUpdated: queryParams.sortUpdatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ export class OutputBookingsService_2024_08_13 {
|
||||
meetingUrl: location,
|
||||
absentHost: !!databaseBooking.noShowHost,
|
||||
createdAt: databaseBooking.createdAt,
|
||||
updatedAt: databaseBooking.updatedAt,
|
||||
};
|
||||
|
||||
const bookingTransformed = plainToClass(BookingOutput_2024_08_13, booking, { strategy: "excludeAll" });
|
||||
@@ -225,6 +226,7 @@ export class OutputBookingsService_2024_08_13 {
|
||||
absentHost: !!databaseBooking.noShowHost,
|
||||
bookingFieldsResponses: databaseBooking.responses,
|
||||
createdAt: databaseBooking.createdAt,
|
||||
updatedAt: databaseBooking.updatedAt,
|
||||
};
|
||||
|
||||
const bookingTransformed = plainToClass(RecurringBookingOutput_2024_08_13, booking, {
|
||||
@@ -271,6 +273,7 @@ export class OutputBookingsService_2024_08_13 {
|
||||
meetingUrl: location,
|
||||
absentHost: !!databaseBooking.noShowHost,
|
||||
createdAt: databaseBooking.createdAt,
|
||||
updatedAt: databaseBooking.updatedAt,
|
||||
};
|
||||
|
||||
const parsed = plainToClass(GetSeatedBookingOutput_2024_08_13, booking, { strategy: "excludeAll" });
|
||||
@@ -376,6 +379,7 @@ export class OutputBookingsService_2024_08_13 {
|
||||
recurringBookingUid: databaseBooking.recurringEventId,
|
||||
absentHost: !!databaseBooking.noShowHost,
|
||||
createdAt: databaseBooking.createdAt,
|
||||
updatedAt: databaseBooking.updatedAt,
|
||||
};
|
||||
|
||||
const parsed = plainToClass(GetRecurringSeatedBookingOutput_2024_08_13, booking, {
|
||||
|
||||
@@ -3385,6 +3385,26 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "afterUpdatedAt",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Filter bookings that have been updated after this date string.",
|
||||
"example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "beforeUpdatedAt",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Filter bookings that have been updated before this date string.",
|
||||
"example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortStart",
|
||||
"required": false,
|
||||
@@ -3427,6 +3447,20 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortUpdatedAt",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.",
|
||||
"example": "?sortUpdated=asc OR ?sortUpdated=desc",
|
||||
"schema": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "take",
|
||||
"required": false,
|
||||
@@ -10488,10 +10522,7 @@
|
||||
"description": "A valid URL where the booker will redirect to, once the booking is completed successfully",
|
||||
"example": "https://masterchief.com/argentina/flan/video/9129412"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"lengthInMinutesOptions"
|
||||
]
|
||||
}
|
||||
},
|
||||
"UpdateEventTypeOutput_2024_06_14": {
|
||||
"type": "object",
|
||||
@@ -12923,10 +12954,7 @@
|
||||
"type": "boolean",
|
||||
"description": "If true, all current and future team members will be assigned to this event type"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"lengthInMinutesOptions"
|
||||
]
|
||||
}
|
||||
},
|
||||
"UpdateTeamEventTypeOutput": {
|
||||
"type": "object",
|
||||
@@ -15220,10 +15248,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -15267,6 +15303,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -15312,6 +15352,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees",
|
||||
"bookingFieldsResponses"
|
||||
]
|
||||
@@ -15355,10 +15396,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -15402,6 +15451,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -15451,6 +15504,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees",
|
||||
"bookingFieldsResponses",
|
||||
"recurringBookingUid"
|
||||
@@ -15593,10 +15647,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -15640,6 +15702,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -15672,6 +15738,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"seatUid",
|
||||
"attendees"
|
||||
]
|
||||
@@ -15715,10 +15782,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -15762,6 +15837,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -15798,6 +15877,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"seatUid",
|
||||
"attendees",
|
||||
"recurringBookingUid"
|
||||
@@ -15882,10 +15962,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -15929,6 +16017,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -15957,6 +16049,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees"
|
||||
]
|
||||
},
|
||||
@@ -15999,10 +16092,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -16046,6 +16147,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -16078,6 +16183,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees",
|
||||
"recurringBookingUid"
|
||||
]
|
||||
|
||||
@@ -3285,6 +3285,26 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "afterUpdatedAt",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Filter bookings that have been updated after this date string.",
|
||||
"example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "beforeUpdatedAt",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Filter bookings that have been updated before this date string.",
|
||||
"example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortStart",
|
||||
"required": false,
|
||||
@@ -3318,6 +3338,17 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sortUpdatedAt",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.",
|
||||
"example": "?sortUpdated=asc OR ?sortUpdated=desc",
|
||||
"schema": {
|
||||
"enum": ["asc", "desc"],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "take",
|
||||
"required": false,
|
||||
@@ -9736,8 +9767,7 @@
|
||||
"description": "A valid URL where the booker will redirect to, once the booking is completed successfully",
|
||||
"example": "https://masterchief.com/argentina/flan/video/9129412"
|
||||
}
|
||||
},
|
||||
"required": ["lengthInMinutesOptions"]
|
||||
}
|
||||
},
|
||||
"UpdateEventTypeOutput_2024_06_14": {
|
||||
"type": "object",
|
||||
@@ -11872,8 +11902,7 @@
|
||||
"type": "boolean",
|
||||
"description": "If true, all current and future team members will be assigned to this event type"
|
||||
}
|
||||
},
|
||||
"required": ["lengthInMinutesOptions"]
|
||||
}
|
||||
},
|
||||
"UpdateTeamEventTypeOutput": {
|
||||
"type": "object",
|
||||
@@ -13824,10 +13853,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -13871,6 +13908,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -13913,6 +13954,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees",
|
||||
"bookingFieldsResponses"
|
||||
]
|
||||
@@ -13951,10 +13993,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -13998,6 +14048,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -14044,6 +14098,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees",
|
||||
"bookingFieldsResponses",
|
||||
"recurringBookingUid"
|
||||
@@ -14174,10 +14229,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -14221,6 +14284,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -14253,6 +14320,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"seatUid",
|
||||
"attendees"
|
||||
]
|
||||
@@ -14291,10 +14359,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -14338,6 +14414,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -14374,6 +14454,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"seatUid",
|
||||
"attendees",
|
||||
"recurringBookingUid"
|
||||
@@ -14447,10 +14528,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -14494,6 +14583,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -14522,6 +14615,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees"
|
||||
]
|
||||
},
|
||||
@@ -14559,10 +14653,18 @@
|
||||
"type": "string",
|
||||
"example": "User requested cancellation"
|
||||
},
|
||||
"cancelledByEmail": {
|
||||
"type": "string",
|
||||
"example": "canceller@example.com"
|
||||
},
|
||||
"reschedulingReason": {
|
||||
"type": "string",
|
||||
"example": "User rescheduled the event"
|
||||
},
|
||||
"rescheduledByEmail": {
|
||||
"type": "string",
|
||||
"example": "rescheduler@example.com"
|
||||
},
|
||||
"rescheduledFromUid": {
|
||||
"type": "string",
|
||||
"example": "previous_uid_123"
|
||||
@@ -14606,6 +14708,10 @@
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"example": "2024-08-13T15:30:00Z"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"example": {
|
||||
@@ -14638,6 +14744,7 @@
|
||||
"location",
|
||||
"absentHost",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"attendees",
|
||||
"recurringBookingUid"
|
||||
]
|
||||
|
||||
@@ -8,6 +8,7 @@ type SortOptions = {
|
||||
sortStart?: "asc" | "desc";
|
||||
sortEnd?: "asc" | "desc";
|
||||
sortCreated?: "asc" | "desc";
|
||||
sortUpdated?: "asc" | "desc";
|
||||
};
|
||||
type GetOptions = {
|
||||
ctx: {
|
||||
@@ -127,6 +128,9 @@ function getOrderBy(
|
||||
if (sort?.sortCreated) {
|
||||
return { createdAt: sort.sortCreated };
|
||||
}
|
||||
if (sort?.sortUpdated) {
|
||||
return { updatedAt: sort.sortUpdated };
|
||||
}
|
||||
|
||||
return { startTime: "asc" };
|
||||
}
|
||||
|
||||
@@ -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 updated after this date string.",
|
||||
example: "?afterUpdatedAt=2025-03-07T10:00:00.000Z",
|
||||
})
|
||||
afterUpdatedAt?: 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 updated before this date string.",
|
||||
example: "?beforeUpdatedAt=2025-03-14T11:00:00.000Z",
|
||||
})
|
||||
beforeUpdatedAt?: string;
|
||||
|
||||
// note(Lauris): sort
|
||||
@IsOptional()
|
||||
@IsEnum(SortOrder, {
|
||||
@@ -190,6 +210,19 @@ export class GetBookingsInput_2024_08_13 {
|
||||
})
|
||||
sortCreated?: SortOrderType;
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(SortOrder, {
|
||||
message: 'SortCreated must be either "asc" or "desc".',
|
||||
})
|
||||
@ApiProperty({
|
||||
required: false,
|
||||
description:
|
||||
"Sort results by their updated time (for example when booking status changes) in ascending or descending order.",
|
||||
example: "?sortUpdated=asc OR ?sortUpdated=desc",
|
||||
enum: SortOrder,
|
||||
})
|
||||
sortUpdatedAt?: SortOrderType;
|
||||
|
||||
// note(Lauris): pagination
|
||||
@ApiProperty({ required: false, description: "The number of items to return", example: 10 })
|
||||
@Transform(({ value }: { value: string }) => value && parseInt(value))
|
||||
|
||||
@@ -236,6 +236,11 @@ class BaseBookingOutput_2024_08_13 {
|
||||
@Expose()
|
||||
createdAt!: string;
|
||||
|
||||
@ApiProperty({ type: String, example: "2024-08-13T15:30:00Z" })
|
||||
@IsDateString()
|
||||
@Expose()
|
||||
updatedAt!: string | null;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
type: Object,
|
||||
example: { key: "value" },
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ export class UpdateEventTypeInput_2024_06_14 {
|
||||
@ArrayUnique()
|
||||
@IsInt({ each: true })
|
||||
@Min(1, { each: true })
|
||||
@DocsProperty({
|
||||
@DocsPropertyOptional({
|
||||
example: [15, 30, 60],
|
||||
description:
|
||||
"If you want that user can choose between different lengths of the event you can specify them here. Must include the provided `lengthInMinutes`.",
|
||||
|
||||
@@ -643,7 +643,7 @@ model Booking {
|
||||
attendees Attendee[]
|
||||
location String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime?
|
||||
updatedAt DateTime? @updatedAt
|
||||
status BookingStatus @default(ACCEPTED)
|
||||
paid Boolean @default(false)
|
||||
payment Payment[]
|
||||
|
||||
@@ -201,6 +201,22 @@ export async function getBookings({
|
||||
};
|
||||
}
|
||||
|
||||
if (filters?.afterUpdatedDate) {
|
||||
bookingWhereInputFilters.afterUpdatedDate = {
|
||||
updatedAt: {
|
||||
gte: dayjs.utc(filters.afterUpdatedDate).toDate(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (filters?.beforeUpdatedDate) {
|
||||
bookingWhereInputFilters.beforeUpdatedDate = {
|
||||
updatedAt: {
|
||||
lte: dayjs.utc(filters.beforeUpdatedDate).toDate(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const filtersCombined: Prisma.BookingWhereInput[] = !filters
|
||||
? []
|
||||
: Object.keys(filters)
|
||||
|
||||
@@ -10,6 +10,8 @@ export const ZGetInputSchema = z.object({
|
||||
attendeeName: z.string().optional(),
|
||||
afterStartDate: z.string().optional(),
|
||||
beforeEndDate: z.string().optional(),
|
||||
afterUpdatedDate: z.string().optional(),
|
||||
beforeUpdatedDate: z.string().optional(),
|
||||
}),
|
||||
limit: z.number().min(1).max(100).nullish(),
|
||||
cursor: z.number().nullish(), // <-- "cursor" needs to exist when using useInfiniteQuery, but can be any type
|
||||
|
||||
Reference in New Issue
Block a user