Skip to content

Commit b620581

Browse files
ibex088devin-ai-integration[bot]ThyMinimalDev
authored
feat: Add endpoint to add attendees to existing bookings (calcom#24414)
* feat: add endpoint to add attendees to existing bookings - Created POST /v2/bookings/:bookingUid/attendees endpoint - Added AddAttendeesInput_2024_08_13 for input validation - Added AddAttendeesOutput_2024_08_13 for response format - Created BookingAttendeesService_2024_08_13 for business logic - Created BookingAttendeesController_2024_08_13 for API endpoint - Added validation to check for duplicate attendee emails - Integrated with existing booking and event type repositories - Added validateAndTransformAddAttendeesInput method to InputBookingsService - Fixed pre-existing ESLint no-prototype-builtins warnings - Left placeholder for custom booking field validation logic Co-Authored-By: somay@cal.com <somaychauhan98@gmail.com> * refactor: move booking attendee operations to dedicated repository * refactor: move repository files into dedicated repositories directory * feat: validate guests field availability before adding attendees to booking * feat: migrate addAttendees API to use existing addGuests handler * refactor: remove unused validateAndTransformAddAttendeesInput method from InputBookingsService * refactor: rename attendees to guests in booking API endpoints and types * refactor: rename booking-attendees to booking-guests for consistency * WIP: add e2e tests for add booking guests endpoint * faet: improve guest booking tests * refactor: extract getHtml method in email templates * feat: add email toggle support for guest invites based on OAuth client settings * refactor: addGuests handler * feat: add SMS notifications when adding guests to existing bookings * refactor: rename add-attendees to add-guests for consistent terminology * refactor: added repository pattern in addGuests.handler * test: add attendee scheduled email spy to booking guests tests * fix: use event type team ID instead of user org ID for booking permission check * Update BookingEmailSmsHandler.ts * Remove comments * refactor: rename booking guests to booking attendees * refactor: rename guest-related methods to use attendees terminology for consistency * update api docs * refactor: restructure addGuests handler to top * refactor: update guest email format to use object structure in booking tests * docs: clarify API version header requirement for booking attendees endpoint * docs: add email notification details to booking attendees API documentation * refactor: rename booking attendees to guests for consistency * refactor: rename attendees to guests in booking API endpoints * feat: add email validation for guest invites * feat: improve error handling for guest booking failures --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
1 parent c0530cc commit b620581

34 files changed

Lines changed: 1302 additions & 103 deletions

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { BookingReferencesRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/booking-references.repository";
2-
import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/bookings.repository";
1+
import { BookingGuestsController_2024_08_13 } from "@/ee/bookings/2024-08-13/controllers/booking-guests.controller";
32
import { BookingsController_2024_08_13 } from "@/ee/bookings/2024-08-13/controllers/bookings.controller";
3+
import { BookingReferencesRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/repositories/booking-references.repository";
4+
import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/repositories/bookings.repository";
5+
import { BookingGuestsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/booking-guests.service";
46
import { BookingReferencesService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/booking-references.service";
57
import { BookingsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/bookings.service";
68
import { CalVideoService } from "@/ee/bookings/2024-08-13/services/cal-video.service";
@@ -15,6 +17,7 @@ import { CalendarsService } from "@/ee/calendars/services/calendars.service";
1517
import { EventTypesModule_2024_04_15 } from "@/ee/event-types/event-types_2024_04_15/event-types.module";
1618
import { EventTypesModule_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.module";
1719
import { EventTypesRepository_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.repository";
20+
import { OutputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/services/output-event-types.service";
1821
import { SchedulesModule_2024_04_15 } from "@/ee/schedules/schedules_2024_04_15/schedules.module";
1922
import { InstantBookingModule } from "@/lib/modules/instant-booking.module";
2023
import { RecurringBookingModule } from "@/lib/modules/recurring-booking.module";
@@ -71,9 +74,11 @@ import { Module } from "@nestjs/common";
7174
OAuthClientRepository,
7275
OAuthClientUsersService,
7376
BookingsService_2024_08_13,
77+
BookingGuestsService_2024_08_13,
7478
InputBookingsService_2024_08_13,
7579
OutputBookingsService_2024_08_13,
7680
OutputBookingReferencesService_2024_08_13,
81+
OutputEventTypesService_2024_06_14,
7782
BookingsRepository_2024_08_13,
7883
EventTypesRepository_2024_06_14,
7984
BookingSeatRepository,
@@ -92,7 +97,7 @@ import { Module } from "@nestjs/common";
9297
BookingReferencesRepository_2024_08_13,
9398
CalVideoService,
9499
],
95-
controllers: [BookingsController_2024_08_13],
100+
controllers: [BookingsController_2024_08_13, BookingGuestsController_2024_08_13],
96101
exports: [InputBookingsService_2024_08_13, OutputBookingsService_2024_08_13, BookingsService_2024_08_13],
97102
})
98103
export class BookingsModule_2024_08_13 {}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { BookingUidGuard } from "@/ee/bookings/2024-08-13/guards/booking-uid.guard";
2+
import { AddGuestsOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/add-guests.output";
3+
import { BookingGuestsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/booking-guests.service";
4+
import { VERSION_2024_08_13_VALUE, VERSION_2024_08_13 } from "@/lib/api-versions";
5+
import { API_KEY_OR_ACCESS_TOKEN_HEADER } from "@/lib/docs/headers";
6+
import { GetUser } from "@/modules/auth/decorators/get-user/get-user.decorator";
7+
import { Permissions } from "@/modules/auth/decorators/permissions/permissions.decorator";
8+
import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard";
9+
import { PermissionsGuard } from "@/modules/auth/guards/permissions/permissions.guard";
10+
import { ApiAuthGuardUser } from "@/modules/auth/strategies/api-auth/api-auth.strategy";
11+
import { Controller, Post, Logger, Body, UseGuards, Param, HttpCode, HttpStatus } from "@nestjs/common";
12+
import { ApiOperation, ApiTags as DocsTags, ApiHeader } from "@nestjs/swagger";
13+
14+
import { BOOKING_WRITE, SUCCESS_STATUS } from "@calcom/platform-constants";
15+
import { AddGuestsInput_2024_08_13 } from "@calcom/platform-types";
16+
17+
@Controller({
18+
path: "/v2/bookings/:bookingUid/guests",
19+
version: VERSION_2024_08_13_VALUE,
20+
})
21+
@UseGuards(PermissionsGuard)
22+
@DocsTags("Bookings / Guests")
23+
@ApiHeader({
24+
name: "cal-api-version",
25+
description: `Must be set to ${VERSION_2024_08_13}. This header is required as this endpoint does not exist in older API versions.`,
26+
example: VERSION_2024_08_13,
27+
required: true,
28+
})
29+
export class BookingGuestsController_2024_08_13 {
30+
private readonly logger = new Logger("BookingGuestsController_2024_08_13");
31+
32+
constructor(private readonly bookingGuestsService: BookingGuestsService_2024_08_13) {}
33+
34+
@Post("/")
35+
@HttpCode(HttpStatus.OK)
36+
@Permissions([BOOKING_WRITE])
37+
@UseGuards(ApiAuthGuard, BookingUidGuard)
38+
@ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER)
39+
@ApiOperation({
40+
summary: "Add guests to an existing booking",
41+
description: `Add one or more guests to an existing booking.
42+
43+
**Email Notifications:**
44+
When guests are added, the following notifications are sent (unless disabled by event type settings):
45+
46+
- **Organizer & Team Members:** Receive an "Add Guests" notification email informing them that new guests have been added to the booking.
47+
48+
- **New Guests:** Receive a "Scheduled Event" email with full booking details and calendar invite. If they have a phone number, they also receive an SMS notification.
49+
50+
- **Existing Guests:** Receive an "Add Guests" notification email informing them that additional guests have been added to the booking.
51+
52+
<Note>The cal-api-version header is required for this endpoint. Without it, the request will fail with a 404 error.</Note>
53+
`,
54+
})
55+
async addGuests(
56+
@Param("bookingUid") bookingUid: string,
57+
@Body() body: AddGuestsInput_2024_08_13,
58+
@GetUser() user: ApiAuthGuardUser
59+
): Promise<AddGuestsOutput_2024_08_13> {
60+
const booking = await this.bookingGuestsService.addGuests(bookingUid, body, user);
61+
62+
return {
63+
status: SUCCESS_STATUS,
64+
data: booking,
65+
};
66+
}
67+
}

0 commit comments

Comments
 (0)