diff --git a/apps/api/v2/src/ee/event-types/controllers/event-types.controller.ts b/apps/api/v2/src/ee/event-types/controllers/event-types.controller.ts index 4529c296b6..22abc2ef18 100644 --- a/apps/api/v2/src/ee/event-types/controllers/event-types.controller.ts +++ b/apps/api/v2/src/ee/event-types/controllers/event-types.controller.ts @@ -1,8 +1,12 @@ import { CreateEventTypeInput } from "@/ee/event-types/inputs/create-event-type.input"; import { UpdateEventTypeInput } from "@/ee/event-types/inputs/update-event-type.input"; import { CreateEventTypeOutput } from "@/ee/event-types/outputs/create-event-type.output"; +import { DeleteEventTypeOutput } from "@/ee/event-types/outputs/delete-event-type.output"; +import { GetEventTypeOutput } from "@/ee/event-types/outputs/get-event-type.output"; +import { GetEventTypesPublicOutput } from "@/ee/event-types/outputs/get-event-types-public.output"; +import { GetEventTypesOutput } from "@/ee/event-types/outputs/get-event-types.output"; +import { UpdateEventTypeOutput } from "@/ee/event-types/outputs/update-event-type.output"; import { EventTypesService } from "@/ee/event-types/services/event-types.service"; -import { ForAtom } from "@/lib/atoms/decorators/for-atom.decorator"; import { GetUser } from "@/modules/auth/decorators/get-user/get-user.decorator"; import { Permissions } from "@/modules/auth/decorators/permissions/permissions.decorator"; import { AccessTokenGuard } from "@/modules/auth/guards/access-token/access-token.guard"; @@ -22,17 +26,9 @@ import { Delete, } from "@nestjs/common"; import { ApiTags as DocsTags } from "@nestjs/swagger"; -import { EventType } from "@prisma/client"; -import { EventTypesByViewer } from "@calcom/lib"; import { EVENT_TYPE_READ, EVENT_TYPE_WRITE, SUCCESS_STATUS } from "@calcom/platform-constants"; -import type { - EventType as AtomEventType, - EventTypesPublic, - UpdateEventTypeReturn, -} from "@calcom/platform-libraries"; import { getEventTypesByViewer } from "@calcom/platform-libraries"; -import { ApiResponse, ApiSuccessResponse } from "@calcom/platform-types"; @Controller({ path: "event-types", @@ -63,12 +59,9 @@ export class EventTypesController { @UseGuards(AccessTokenGuard) async getEventType( @Param("eventTypeId") eventTypeId: string, - @ForAtom() forAtom: boolean, @GetUser() user: UserWithProfile - ): Promise> { - const eventType = forAtom - ? await this.eventTypesService.getUserEventTypeForAtom(user, Number(eventTypeId)) - : await this.eventTypesService.getUserEventType(user.id, Number(eventTypeId)); + ): Promise { + const eventType = await this.eventTypesService.getUserEventTypeForAtom(user, Number(eventTypeId)); if (!eventType) { throw new NotFoundException(`Event type with id ${eventTypeId} not found`); @@ -83,7 +76,7 @@ export class EventTypesController { @Get("/") @Permissions([EVENT_TYPE_READ]) @UseGuards(AccessTokenGuard) - async getEventTypes(@GetUser() user: UserWithProfile): Promise> { + async getEventTypes(@GetUser() user: UserWithProfile): Promise { const eventTypes = await getEventTypesByViewer({ id: user.id, profile: { @@ -99,9 +92,7 @@ export class EventTypesController { @Get("/:username/public") @Permissions([EVENT_TYPE_READ]) - async getPublicEventTypes( - @Param("username") username: string - ): Promise> { + async getPublicEventTypes(@Param("username") username: string): Promise { const eventTypes = await this.eventTypesService.getEventTypesPublicByUsername(username); return { @@ -118,7 +109,7 @@ export class EventTypesController { @Param("eventTypeId") eventTypeId: number, @Body() body: UpdateEventTypeInput, @GetUser() user: UserWithProfile - ): Promise> { + ): Promise { const eventType = await this.eventTypesService.updateEventType(eventTypeId, body, user); return { @@ -133,12 +124,17 @@ export class EventTypesController { async deleteEventType( @Param("eventTypeId") eventTypeId: number, @GetUser("id") userId: number - ): Promise> { + ): Promise { const eventType = await this.eventTypesService.deleteEventType(eventTypeId, userId); return { status: SUCCESS_STATUS, - data: eventType, + data: { + id: eventType.id, + length: eventType.length, + slug: eventType.slug, + title: eventType.title, + }, }; } } diff --git a/apps/api/v2/src/ee/event-types/outputs/delete-event-type.output.ts b/apps/api/v2/src/ee/event-types/outputs/delete-event-type.output.ts new file mode 100644 index 0000000000..738ab32499 --- /dev/null +++ b/apps/api/v2/src/ee/event-types/outputs/delete-event-type.output.ts @@ -0,0 +1,38 @@ +import { + CREATE_EVENT_LENGTH_EXAMPLE, + CREATE_EVENT_SLUG_EXAMPLE, + CREATE_EVENT_TITLE_EXAMPLE, +} from "@/ee/event-types/inputs/create-event-type.input"; +import { ApiProperty } from "@nestjs/swagger"; +import { ApiProperty as DocsProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; +import { IsEnum, IsInt, IsString } from "class-validator"; + +import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants"; + +class DeleteData { + @IsInt() + @DocsProperty({ example: 1 }) + id!: number; + + @IsInt() + @DocsProperty({ example: CREATE_EVENT_LENGTH_EXAMPLE }) + length!: number; + + @IsString() + @DocsProperty({ example: CREATE_EVENT_SLUG_EXAMPLE }) + slug!: string; + + @IsString() + @DocsProperty({ example: CREATE_EVENT_TITLE_EXAMPLE }) + title!: string; +} + +export class DeleteEventTypeOutput { + @ApiProperty({ example: SUCCESS_STATUS, enum: [SUCCESS_STATUS, ERROR_STATUS] }) + @IsEnum([SUCCESS_STATUS, ERROR_STATUS]) + status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS; + + @Type(() => DeleteData) + data!: DeleteData; +} diff --git a/apps/api/v2/src/ee/event-types/outputs/get-event-type.output.ts b/apps/api/v2/src/ee/event-types/outputs/get-event-type.output.ts new file mode 100644 index 0000000000..605be799e9 --- /dev/null +++ b/apps/api/v2/src/ee/event-types/outputs/get-event-type.output.ts @@ -0,0 +1,28 @@ +import { EventTypeOutput } from "@/ee/event-types/outputs/event-type.output"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; +import { IsEnum, ValidateNested } from "class-validator"; + +import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants"; + +class Data { + @ApiProperty({ + type: EventTypeOutput, + }) + @ValidateNested() + @Type(() => EventTypeOutput) + eventType!: EventTypeOutput; +} + +export class GetEventTypeOutput { + @ApiProperty({ example: SUCCESS_STATUS, enum: [SUCCESS_STATUS, ERROR_STATUS] }) + @IsEnum([SUCCESS_STATUS, ERROR_STATUS]) + status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS; + + @ApiProperty({ + type: Data, + }) + @ValidateNested() + @Type(() => Data) + data!: Data; +} diff --git a/apps/api/v2/src/ee/event-types/outputs/get-event-types-public.output.ts b/apps/api/v2/src/ee/event-types/outputs/get-event-types-public.output.ts new file mode 100644 index 0000000000..c3789fce15 --- /dev/null +++ b/apps/api/v2/src/ee/event-types/outputs/get-event-types-public.output.ts @@ -0,0 +1,43 @@ +import { + CREATE_EVENT_LENGTH_EXAMPLE, + CREATE_EVENT_SLUG_EXAMPLE, + CREATE_EVENT_TITLE_EXAMPLE, +} from "@/ee/event-types/inputs/create-event-type.input"; +import { ApiProperty } from "@nestjs/swagger"; +import { ApiProperty as DocsProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; +import { IsArray, IsEnum, IsInt, IsString, ValidateNested } from "class-validator"; + +import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants"; + +class PublicEventType { + @IsInt() + @DocsProperty({ example: 1 }) + id!: number; + + @IsInt() + @DocsProperty({ example: CREATE_EVENT_LENGTH_EXAMPLE }) + length!: number; + + @IsString() + @DocsProperty({ example: CREATE_EVENT_SLUG_EXAMPLE }) + slug!: string; + + @IsString() + @DocsProperty({ example: CREATE_EVENT_TITLE_EXAMPLE }) + title!: string; + + @IsString() + description?: string | null; +} + +export class GetEventTypesPublicOutput { + @ApiProperty({ example: SUCCESS_STATUS, enum: [SUCCESS_STATUS, ERROR_STATUS] }) + @IsEnum([SUCCESS_STATUS, ERROR_STATUS]) + status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS; + + @ValidateNested({ each: true }) + @Type(() => PublicEventType) + @IsArray() + data!: PublicEventType[]; +} diff --git a/apps/api/v2/src/ee/event-types/outputs/get-event-types.output.ts b/apps/api/v2/src/ee/event-types/outputs/get-event-types.output.ts new file mode 100644 index 0000000000..735db07b93 --- /dev/null +++ b/apps/api/v2/src/ee/event-types/outputs/get-event-types.output.ts @@ -0,0 +1,31 @@ +import { EventTypeOutput } from "@/ee/event-types/outputs/event-type.output"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; +import { IsArray, IsEnum, ValidateNested } from "class-validator"; + +import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants"; + +class EventTypeGroup { + @ValidateNested({ each: true }) + @Type(() => EventTypeOutput) + @IsArray() + eventTypes!: EventTypeOutput[]; +} + +class GetEventTypesData { + @ValidateNested({ each: true }) + @Type(() => EventTypeGroup) + @IsArray() + eventTypeGroups!: EventTypeGroup[]; +} + +export class GetEventTypesOutput { + @ApiProperty({ example: SUCCESS_STATUS, enum: [SUCCESS_STATUS, ERROR_STATUS] }) + @IsEnum([SUCCESS_STATUS, ERROR_STATUS]) + status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS; + + @ValidateNested({ each: true }) + @Type(() => GetEventTypesData) + @IsArray() + data!: GetEventTypesData; +} diff --git a/apps/api/v2/src/ee/event-types/outputs/update-event-type.output.ts b/apps/api/v2/src/ee/event-types/outputs/update-event-type.output.ts new file mode 100644 index 0000000000..642be558a6 --- /dev/null +++ b/apps/api/v2/src/ee/event-types/outputs/update-event-type.output.ts @@ -0,0 +1,20 @@ +import { EventTypeOutput } from "@/ee/event-types/outputs/event-type.output"; +import { ApiProperty } from "@nestjs/swagger"; +import { Type } from "class-transformer"; +import { IsEnum, IsNotEmptyObject, ValidateNested } from "class-validator"; + +import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants"; + +export class UpdateEventTypeOutput { + @ApiProperty({ example: SUCCESS_STATUS, enum: [SUCCESS_STATUS, ERROR_STATUS] }) + @IsEnum([SUCCESS_STATUS, ERROR_STATUS]) + status!: typeof SUCCESS_STATUS | typeof ERROR_STATUS; + + @ApiProperty({ + type: EventTypeOutput, + }) + @IsNotEmptyObject() + @ValidateNested() + @Type(() => EventTypeOutput) + data!: EventTypeOutput; +} diff --git a/apps/api/v2/src/ee/event-types/services/event-types.service.ts b/apps/api/v2/src/ee/event-types/services/event-types.service.ts index 12ce0ad7fd..e55b0b1eba 100644 --- a/apps/api/v2/src/ee/event-types/services/event-types.service.ts +++ b/apps/api/v2/src/ee/event-types/services/event-types.service.ts @@ -116,7 +116,7 @@ export class EventTypesService { async updateEventType(eventTypeId: number, body: UpdateEventTypeInput, user: UserWithProfile) { this.checkCanUpdateEventType(user.id, eventTypeId); const eventTypeUser = await this.getUserToUpdateEvent(user); - const { eventType } = await updateEventType({ + await updateEventType({ input: { id: eventTypeId, ...body }, ctx: { user: eventTypeUser, @@ -126,6 +126,8 @@ export class EventTypesService { }, }); + const { eventType } = await this.getUserEventTypeForAtom(user, eventTypeId); + return eventType; } diff --git a/apps/api/v2/swagger/documentation.json b/apps/api/v2/swagger/documentation.json index d573e7ab53..0b2f11a9f2 100644 --- a/apps/api/v2/swagger/documentation.json +++ b/apps/api/v2/swagger/documentation.json @@ -577,7 +577,7 @@ "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/GetEventTypesOutput" } } } @@ -607,7 +607,7 @@ "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/GetEventTypeOutput" } } } @@ -645,7 +645,7 @@ "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/UpdateEventTypeOutput" } } } @@ -673,7 +673,7 @@ "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/DeleteEventTypeOutput" } } } @@ -703,7 +703,7 @@ "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/GetEventTypesPublicOutput" } } } @@ -1745,6 +1745,139 @@ "data" ] }, + "Data": { + "type": "object", + "properties": { + "eventType": { + "$ref": "#/components/schemas/EventTypeOutput" + } + }, + "required": [ + "eventType" + ] + }, + "GetEventTypeOutput": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "success", + "enum": [ + "success", + "error" + ] + }, + "data": { + "$ref": "#/components/schemas/Data" + } + }, + "required": [ + "status", + "data" + ] + }, + "EventTypeGroup": { + "type": "object", + "properties": { + "eventTypes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventTypeOutput" + } + } + }, + "required": [ + "eventTypes" + ] + }, + "GetEventTypesData": { + "type": "object", + "properties": { + "eventTypeGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventTypeGroup" + } + } + }, + "required": [ + "eventTypeGroups" + ] + }, + "GetEventTypesOutput": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "success", + "enum": [ + "success", + "error" + ] + }, + "data": { + "$ref": "#/components/schemas/GetEventTypesData" + } + }, + "required": [ + "status", + "data" + ] + }, + "PublicEventType": { + "type": "object", + "properties": { + "id": { + "type": "number", + "example": 1 + }, + "length": { + "type": "number", + "example": 60 + }, + "slug": { + "type": "string", + "example": "cooking-class" + }, + "title": { + "type": "string", + "example": "Learn the secrets of masterchief!" + }, + "description": { + "type": "string", + "nullable": true + } + }, + "required": [ + "id", + "length", + "slug", + "title" + ] + }, + "GetEventTypesPublicOutput": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "success", + "enum": [ + "success", + "error" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PublicEventType" + } + } + }, + "required": [ + "status", + "data" + ] + }, "UpdateEventTypeInput": { "type": "object", "properties": { @@ -1772,6 +1905,73 @@ } } }, + "UpdateEventTypeOutput": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "success", + "enum": [ + "success", + "error" + ] + }, + "data": { + "$ref": "#/components/schemas/EventTypeOutput" + } + }, + "required": [ + "status", + "data" + ] + }, + "DeleteData": { + "type": "object", + "properties": { + "id": { + "type": "number", + "example": 1 + }, + "length": { + "type": "number", + "example": 60 + }, + "slug": { + "type": "string", + "example": "cooking-class" + }, + "title": { + "type": "string", + "example": "Learn the secrets of masterchief!" + } + }, + "required": [ + "id", + "length", + "slug", + "title" + ] + }, + "DeleteEventTypeOutput": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "success", + "enum": [ + "success", + "error" + ] + }, + "data": { + "$ref": "#/components/schemas/DeleteData" + } + }, + "required": [ + "status", + "data" + ] + }, "CreateAvailabilityInput": { "type": "object", "properties": { diff --git a/packages/lib/server/eventTypeSelect.ts b/packages/lib/server/eventTypeSelect.ts index 3cac188661..75dc5f6a4a 100644 --- a/packages/lib/server/eventTypeSelect.ts +++ b/packages/lib/server/eventTypeSelect.ts @@ -43,4 +43,10 @@ export const eventTypeSelect = Prisma.validator()({ aiPhoneCallConfig: true, assignAllTeamMembers: true, recurringEvent: true, + locations: true, + bookingFields: true, + useEventTypeDestinationCalendarEmail: true, + secondaryEmailId: true, + bookingLimits: true, + durationLimits: true, });