diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts index 8edf53263f..163b436675 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts @@ -96,6 +96,7 @@ describe("Bookings Endpoints 2024-08-13", () => { user = await userRepositoryFixture.create({ email: userEmail, + username: `bob-${Math.floor(Math.random() * 1000)}@gmail.com`, platformOAuthClients: { connect: { id: oAuthClient.id, @@ -351,6 +352,7 @@ describe("Bookings Endpoints 2024-08-13", () => { expect(data.id).toBeDefined(); expect(data.uid).toBeDefined(); expect(data.hosts[0].id).toEqual(user.id); + expect(data.hosts[0].username).toEqual(user.username); expect(data.status).toEqual("accepted"); expect(data.start).toEqual(body.start); expect(data.end).toEqual(new Date(Date.UTC(2030, 0, 8, 14, 0, 0)).toISOString()); @@ -508,6 +510,7 @@ describe("Bookings Endpoints 2024-08-13", () => { expect(data.id).toEqual(createdBooking.id); expect(data.uid).toEqual(createdBooking.uid); expect(data.hosts[0].id).toEqual(user.id); + expect(data.hosts[0].username).toEqual(user.username); expect(data.status).toEqual(createdBooking.status); expect(data.start).toEqual(createdBooking.start); expect(data.end).toEqual(createdBooking.end); diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts index 769440e786..a3e5b6a7b6 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts @@ -49,6 +49,8 @@ export const seatedBookingResponsesSchema = z }) .passthrough(); +type DatabaseUser = { id: number; name: string | null; email: string; username: string | null }; + type DatabaseBooking = Booking & { eventType: { id: number; @@ -62,11 +64,11 @@ type DatabaseBooking = Booking & { noShow: boolean | null; bookingSeat?: BookingSeat | null; }[]; - user: { id: number; name: string | null; email: string } | null; + user: DatabaseUser | null; createdAt: Date; }; -type BookingWithUser = Booking & { user: { id: number; name: string | null; email: string } | null }; +type BookingWithUser = Booking & { user: DatabaseUser | null }; type DatabaseMetadata = z.infer; @@ -89,7 +91,7 @@ export class OutputBookingsService_2024_08_13 { uid: databaseBooking.uid, title: databaseBooking.title, description: databaseBooking.description, - hosts: [databaseBooking.user], + hosts: [this.getHost(databaseBooking.user)], status: databaseBooking.status.toLowerCase(), cancellationReason: databaseBooking.cancellationReason || undefined, reschedulingReason: bookingResponses?.rescheduledReason, @@ -130,6 +132,22 @@ export class OutputBookingsService_2024_08_13 { return userDefinedMetadata; } + getHost(user: DatabaseUser | null) { + if (!user) { + return { + id: "unknown", + name: "unknown", + email: "unknown", + username: "unknown", + }; + } + + return { + ...user, + username: user.username || "unknown", + }; + } + async getOutputRecurringBookings(bookingsIds: number[]) { const transformed = []; @@ -158,7 +176,7 @@ export class OutputBookingsService_2024_08_13 { uid: databaseBooking.uid, title: databaseBooking.title, description: databaseBooking.description, - hosts: [databaseBooking.user], + hosts: [this.getHost(databaseBooking.user)], status: databaseBooking.status.toLowerCase(), cancellationReason: databaseBooking.cancellationReason || undefined, reschedulingReason: bookingResponses?.rescheduledReason, @@ -215,7 +233,7 @@ export class OutputBookingsService_2024_08_13 { uid: databaseBooking.uid, title: databaseBooking.title, description: databaseBooking.description, - hosts: [databaseBooking.user], + hosts: [this.getHost(databaseBooking.user)], status: databaseBooking.status.toLowerCase(), rescheduledFromUid: databaseBooking.fromReschedule || undefined, start: databaseBooking.startTime, @@ -310,7 +328,7 @@ export class OutputBookingsService_2024_08_13 { uid: databaseBooking.uid, title: databaseBooking.title, description: databaseBooking.description, - hosts: [databaseBooking.user], + hosts: [this.getHost(databaseBooking.user)], status: databaseBooking.status.toLowerCase(), cancellationReason: databaseBooking.cancellationReason || undefined, rescheduledFromUid: databaseBooking.fromReschedule || undefined, diff --git a/apps/api/v2/swagger/documentation.json b/apps/api/v2/swagger/documentation.json index a755682d94..d43e9d260d 100644 --- a/apps/api/v2/swagger/documentation.json +++ b/apps/api/v2/swagger/documentation.json @@ -13023,6 +13023,33 @@ "attendee" ] }, + "BookingHost": { + "type": "object", + "properties": { + "id": { + "type": "number", + "example": 1 + }, + "name": { + "type": "string", + "example": "Jane Doe" + }, + "username": { + "type": "string", + "example": "jane100" + }, + "timeZone": { + "type": "string", + "example": "America/Los_Angeles" + } + }, + "required": [ + "id", + "name", + "username", + "timeZone" + ] + }, "EventType": { "type": "object", "properties": { @@ -13062,7 +13089,7 @@ "hosts": { "type": "array", "items": { - "$ref": "#/components/schemas/Host" + "$ref": "#/components/schemas/BookingHost" } }, "status": { @@ -13195,7 +13222,7 @@ "hosts": { "type": "array", "items": { - "$ref": "#/components/schemas/Host" + "$ref": "#/components/schemas/BookingHost" } }, "status": { diff --git a/docs/api-reference/v2/openapi.json b/docs/api-reference/v2/openapi.json index e170e3dcf4..6e70a7e37e 100644 --- a/docs/api-reference/v2/openapi.json +++ b/docs/api-reference/v2/openapi.json @@ -11701,6 +11701,28 @@ }, "required": ["start", "lengthInMinutes", "eventTypeId", "attendee"] }, + "BookingHost": { + "type": "object", + "properties": { + "id": { + "type": "number", + "example": 1 + }, + "name": { + "type": "string", + "example": "Jane Doe" + }, + "username": { + "type": "string", + "example": "jane100" + }, + "timeZone": { + "type": "string", + "example": "America/Los_Angeles" + } + }, + "required": ["id", "name", "username", "timeZone"] + }, "EventType": { "type": "object", "properties": { @@ -11737,7 +11759,7 @@ "hosts": { "type": "array", "items": { - "$ref": "#/components/schemas/Host" + "$ref": "#/components/schemas/BookingHost" } }, "status": { @@ -11792,6 +11814,10 @@ "type": "boolean", "example": true }, + "createdAt": { + "type": "string", + "example": "2024-08-13T15:30:00Z" + }, "metadata": { "type": "object", "example": { @@ -11832,6 +11858,7 @@ "eventTypeId", "eventType", "absentHost", + "createdAt", "attendees" ] }, @@ -11857,7 +11884,7 @@ "hosts": { "type": "array", "items": { - "$ref": "#/components/schemas/Host" + "$ref": "#/components/schemas/BookingHost" } }, "status": { @@ -11912,6 +11939,10 @@ "type": "boolean", "example": true }, + "createdAt": { + "type": "string", + "example": "2024-08-13T15:30:00Z" + }, "metadata": { "type": "object", "example": { @@ -11956,6 +11987,7 @@ "eventTypeId", "eventType", "absentHost", + "createdAt", "attendees", "recurringBookingUid" ] diff --git a/packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts b/packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts index a274a81b84..c323a1c080 100644 --- a/packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts +++ b/packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts @@ -69,7 +69,7 @@ export class SeatedAttendee extends Attendee { metadata?: Record; } -class Host { +class BookingHost { @ApiProperty({ type: Number, example: 1 }) @IsInt() @Expose() @@ -80,6 +80,11 @@ class Host { @Expose() name!: string; + @ApiProperty({ type: String, example: "jane100" }) + @IsString() + @Expose() + username!: string; + @ApiProperty({ type: String, example: "America/Los_Angeles" }) @IsTimeZone() @Expose() @@ -119,11 +124,11 @@ class BaseBookingOutput_2024_08_13 { @Expose() description!: string; - @ApiProperty({ type: [Host] }) + @ApiProperty({ type: [BookingHost] }) @ValidateNested({ each: true }) - @Type(() => Host) + @Type(() => BookingHost) @Expose() - hosts!: Host[]; + hosts!: BookingHost[]; @ApiProperty({ enum: ["cancelled", "accepted", "rejected", "pending"], example: "accepted" }) @IsEnum(["cancelled", "accepted", "rejected", "pending"])