Skip to content

Commit 8ad62d1

Browse files
authored
feat: booking references api type filter (calcom#21179)
* feat: add `type` filter for booking references API endpointa * Update openapi.json * feat: add enum validation for booking reference types in filter input * refactor: rename externalUid to eventUid and add destinationCalendarId in booking references * refactor: replace enum with const array for BookingReferenceType * fix: type safety for booking references where clause using Prisma types * refactor: rename BookingReferenceType to BookingReferences
1 parent f047799 commit 8ad62d1

9 files changed

Lines changed: 162 additions & 27 deletions

File tree

apps/api/v2/src/ee/bookings/2024-08-13/booking-references.repository.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
1+
import { BookingReferencesFilterInput_2024_08_13 } from "@/ee/bookings/2024-08-13/inputs/booking-references-filter.input";
12
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
23
import { Injectable } from "@nestjs/common";
4+
import type { Prisma } from "@prisma/client";
35

46
@Injectable()
57
export class BookingReferencesRepository_2024_08_13 {
68
constructor(private readonly dbRead: PrismaReadService) {}
79

8-
async getBookingReferences(bookingId: number) {
10+
async getBookingReferences(bookingId: number, filter?: BookingReferencesFilterInput_2024_08_13) {
11+
const whereClause: Prisma.BookingReferenceWhereInput = { bookingId };
12+
13+
if (filter?.type) {
14+
whereClause.type = filter.type;
15+
}
16+
917
return this.dbRead.prisma.bookingReference.findMany({
10-
where: {
11-
bookingId,
12-
},
18+
where: whereClause,
1319
select: {
1420
type: true,
1521
uid: true,
1622
id: true,
23+
externalCalendarId: true,
1724
},
1825
});
1926
}

apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { BookingUidGuard } from "@/ee/bookings/2024-08-13/guards/booking-uid.guard";
2+
import { BookingReferencesFilterInput_2024_08_13 } from "@/ee/bookings/2024-08-13/inputs/booking-references-filter.input";
23
import { BookingReferencesOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/booking-references.output";
34
import { CalendarLinksOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/calendar-links.output";
45
import { CancelBookingOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/cancel-booking.output";
@@ -403,9 +404,14 @@ export class BookingsController_2024_08_13 {
403404
@HttpCode(HttpStatus.OK)
404405
async getBookingReferences(
405406
@Param("bookingUid") bookingUid: string,
406-
@GetUser("id") userId: number
407+
@GetUser("id") userId: number,
408+
@Query() filter: BookingReferencesFilterInput_2024_08_13
407409
): Promise<BookingReferencesOutput_2024_08_13> {
408-
const bookingReferences = await this.bookingReferencesService.getBookingReferences(bookingUid, userId);
410+
const bookingReferences = await this.bookingReferencesService.getBookingReferences(
411+
bookingUid,
412+
userId,
413+
filter
414+
);
409415

410416
return {
411417
status: SUCCESS_STATUS,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ApiProperty } from "@nestjs/swagger";
2+
import { IsIn, IsOptional } from "class-validator";
3+
4+
export const BookingReferences = [
5+
"google_calendar",
6+
"office365_calendar",
7+
"daily_video",
8+
"google_video",
9+
"office365_video",
10+
"zoom_video",
11+
] as const;
12+
13+
export class BookingReferencesFilterInput_2024_08_13 {
14+
@ApiProperty({
15+
description: "Filter booking references by type",
16+
required: false,
17+
enum: BookingReferences,
18+
example: "google_calendar",
19+
})
20+
@IsOptional()
21+
@IsIn(BookingReferences)
22+
type?: (typeof BookingReferences)[number];
23+
}

apps/api/v2/src/ee/bookings/2024-08-13/outputs/booking-references.output.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ApiProperty } from "@nestjs/swagger";
1+
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
22
import { IsEnum, IsNumber, IsString } from "class-validator";
33

44
import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants";
@@ -12,9 +12,16 @@ export class BookingReference {
1212

1313
@IsString()
1414
@ApiProperty({
15-
description: "The external uid of the booking reference",
15+
description: "The event uid of the booking",
1616
})
17-
externalUid!: string;
17+
eventUid!: string;
18+
19+
@IsString()
20+
@ApiProperty({
21+
description: "The id of the calendar the event is created in",
22+
nullable: true,
23+
})
24+
destinationCalendarId!: string | null;
1825

1926
@IsNumber()
2027
@ApiProperty({

apps/api/v2/src/ee/bookings/2024-08-13/services/booking-references.service.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { BookingReferencesRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/booking-references.repository";
22
import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/bookings.repository";
3+
import { BookingReferencesFilterInput_2024_08_13 } from "@/ee/bookings/2024-08-13/inputs/booking-references-filter.input";
34
import { OutputBookingReferencesService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/output-booking-references.service";
45
import { Injectable, NotFoundException, BadRequestException } from "@nestjs/common";
56

@@ -11,7 +12,11 @@ export class BookingReferencesService_2024_08_13 {
1112
private readonly outputBookingReferencesService: OutputBookingReferencesService_2024_08_13
1213
) {}
1314

14-
async getBookingReferences(bookingUid: string, userId: number) {
15+
async getBookingReferences(
16+
bookingUid: string,
17+
userId: number,
18+
filter?: BookingReferencesFilterInput_2024_08_13
19+
) {
1520
const booking = await this.bookingsRepository.getByUidWithUser(bookingUid);
1621

1722
if (!booking) {
@@ -22,19 +27,19 @@ export class BookingReferencesService_2024_08_13 {
2227
throw new BadRequestException(`Booking with uid ${bookingUid} does not belong to user`);
2328
}
2429

25-
const bookingReferences = await this.bookingReferencesRepository.getBookingReferences(booking.id);
30+
const bookingReferences = await this.bookingReferencesRepository.getBookingReferences(booking.id, filter);
2631

2732
return this.outputBookingReferencesService.getOutputBookingReferences(bookingReferences);
2833
}
2934

30-
async getOrgBookingReferences(bookingUid: string) {
35+
async getOrgBookingReferences(bookingUid: string, filter?: BookingReferencesFilterInput_2024_08_13) {
3136
const booking = await this.bookingsRepository.getByUidWithUser(bookingUid);
3237

3338
if (!booking) {
3439
throw new NotFoundException(`Booking with uid ${bookingUid} not found`);
3540
}
3641

37-
const bookingReferences = await this.bookingReferencesRepository.getBookingReferences(booking.id);
42+
const bookingReferences = await this.bookingReferencesRepository.getBookingReferences(booking.id, filter);
3843

3944
return this.outputBookingReferencesService.getOutputBookingReferences(bookingReferences);
4045
}

apps/api/v2/src/ee/bookings/2024-08-13/services/output-booking-references.service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ interface IBookingReference {
44
type: string;
55
uid: string;
66
id: number;
7+
externalCalendarId: string | null;
78
}
89

910
@Injectable()
1011
export class OutputBookingReferencesService_2024_08_13 {
1112
getOutputBookingReferences(bookingReferences: IBookingReference[]) {
1213
return bookingReferences.map((bookingReference) => ({
1314
type: bookingReference.type,
14-
externalUid: bookingReference.uid,
15+
eventUid: bookingReference.uid,
1516
id: bookingReference.id,
17+
destinationCalendarId: bookingReference?.externalCalendarId,
1618
}));
1719
}
1820
}

apps/api/v2/src/modules/organizations/teams/bookings/organizations-teams-bookings.controller.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { BookingUidGuard } from "@/ee/bookings/2024-08-13/guards/booking-uid.guard";
2+
import { BookingReferencesFilterInput_2024_08_13 } from "@/ee/bookings/2024-08-13/inputs/booking-references-filter.input";
23
import { BookingReferencesOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/booking-references.output";
34
import { BookingReferencesService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/booking-references.service";
45
import { BookingsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/bookings.service";
@@ -82,9 +83,10 @@ export class OrganizationsTeamsBookingsController {
8283
})
8384
@HttpCode(HttpStatus.OK)
8485
async getBookingReferences(
85-
@Param("bookingUid") bookingUid: string
86+
@Param("bookingUid") bookingUid: string,
87+
@Query() filter: BookingReferencesFilterInput_2024_08_13
8688
): Promise<BookingReferencesOutput_2024_08_13> {
87-
const bookingReferences = await this.bookingReferencesService.getOrgBookingReferences(bookingUid);
89+
const bookingReferences = await this.bookingReferencesService.getOrgBookingReferences(bookingUid, filter);
8890

8991
return {
9092
status: SUCCESS_STATUS,

apps/api/v2/swagger/documentation.json

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3321,6 +3321,24 @@
33213321
"schema": {
33223322
"type": "string"
33233323
}
3324+
},
3325+
{
3326+
"name": "type",
3327+
"required": false,
3328+
"in": "query",
3329+
"description": "Filter booking references by type",
3330+
"example": "google_calendar",
3331+
"schema": {
3332+
"enum": [
3333+
"google_calendar",
3334+
"office365_calendar",
3335+
"daily_video",
3336+
"google_video",
3337+
"office365_video",
3338+
"zoom_video"
3339+
],
3340+
"type": "string"
3341+
}
33243342
}
33253343
],
33263344
"responses": {
@@ -7529,6 +7547,24 @@
75297547
"type": "string"
75307548
}
75317549
},
7550+
{
7551+
"name": "type",
7552+
"required": false,
7553+
"in": "query",
7554+
"description": "Filter booking references by type",
7555+
"example": "google_calendar",
7556+
"schema": {
7557+
"enum": [
7558+
"google_calendar",
7559+
"office365_calendar",
7560+
"daily_video",
7561+
"google_video",
7562+
"office365_video",
7563+
"zoom_video"
7564+
],
7565+
"type": "string"
7566+
}
7567+
},
75327568
{
75337569
"name": "Authorization",
75347570
"in": "header",
@@ -15063,7 +15099,7 @@
1506315099
"eightxeight-video",
1506415100
"discord-video",
1506515101
"demodesk-video",
15066-
"campfire-video",
15102+
"campfire-video"
1506715103
],
1506815104
"example": "cal-video"
1506915105
},
@@ -21743,7 +21779,7 @@
2174321779
"type": "object",
2174421780
"properties": {
2174521781
"id": {
21746-
"type": "string"
21782+
"type": "number"
2174721783
},
2174821784
"formId": {
2174921785
"type": "string"
@@ -22296,7 +22332,7 @@
2229622332
"eightxeight-video",
2229722333
"discord-video",
2229822334
"demodesk-video",
22299-
"campfire-video",
22335+
"campfire-video"
2230022336
]
2230122337
}
2230222338
},
@@ -24257,9 +24293,14 @@
2425724293
"type": "string",
2425824294
"description": "The type of the booking reference"
2425924295
},
24260-
"externalUid": {
24296+
"eventUid": {
2426124297
"type": "string",
24262-
"description": "The external uid of the booking reference"
24298+
"description": "The event uid of the booking"
24299+
},
24300+
"destinationCalendarId": {
24301+
"type": "string",
24302+
"nullable": true,
24303+
"description": "The id of the calendar the event is created in"
2426324304
},
2426424305
"id": {
2426524306
"type": "number",
@@ -24268,7 +24309,8 @@
2426824309
},
2426924310
"required": [
2427024311
"type",
24271-
"externalUid",
24312+
"eventUid",
24313+
"destinationCalendarId",
2427224314
"id"
2427324315
]
2427424316
},
@@ -25168,4 +25210,4 @@
2516825210
}
2516925211
}
2517025212
}
25171-
}
25213+
}

docs/api-reference/v2/openapi.json

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3184,6 +3184,24 @@
31843184
"schema": {
31853185
"type": "string"
31863186
}
3187+
},
3188+
{
3189+
"name": "type",
3190+
"required": false,
3191+
"in": "query",
3192+
"description": "Filter booking references by type",
3193+
"example": "google_calendar",
3194+
"schema": {
3195+
"enum": [
3196+
"google_calendar",
3197+
"office365_calendar",
3198+
"daily_video",
3199+
"google_video",
3200+
"office365_video",
3201+
"zoom_video"
3202+
],
3203+
"type": "string"
3204+
}
31873205
}
31883206
],
31893207
"responses": {
@@ -7197,6 +7215,24 @@
71977215
"type": "string"
71987216
}
71997217
},
7218+
{
7219+
"name": "type",
7220+
"required": false,
7221+
"in": "query",
7222+
"description": "Filter booking references by type",
7223+
"example": "google_calendar",
7224+
"schema": {
7225+
"enum": [
7226+
"google_calendar",
7227+
"office365_calendar",
7228+
"daily_video",
7229+
"google_video",
7230+
"office365_video",
7231+
"zoom_video"
7232+
],
7233+
"type": "string"
7234+
}
7235+
},
72007236
{
72017237
"name": "Authorization",
72027238
"in": "header",
@@ -19940,7 +19976,7 @@
1994019976
"type": "object",
1994119977
"properties": {
1994219978
"id": {
19943-
"type": "string"
19979+
"type": "number"
1994419980
},
1994519981
"formId": {
1994619982
"type": "string"
@@ -22237,16 +22273,21 @@
2223722273
"type": "string",
2223822274
"description": "The type of the booking reference"
2223922275
},
22240-
"externalUid": {
22276+
"eventUid": {
2224122277
"type": "string",
22242-
"description": "The external uid of the booking reference"
22278+
"description": "The event uid of the booking"
22279+
},
22280+
"destinationCalendarId": {
22281+
"type": "string",
22282+
"nullable": true,
22283+
"description": "The id of the calendar the event is created in"
2224322284
},
2224422285
"id": {
2224522286
"type": "number",
2224622287
"description": "The id of the booking reference"
2224722288
}
2224822289
},
22249-
"required": ["type", "externalUid", "id"]
22290+
"required": ["type", "eventUid", "destinationCalendarId", "id"]
2225022291
},
2225122292
"BookingReferencesOutput_2024_08_13": {
2225222293
"type": "object",

0 commit comments

Comments
 (0)