docs: v2 event types swagger (#14296)

* docs: GET /event-types/:id response

* docs: GET /event-types response

* docs: UPDATE /event-types/:id response

* docs: DELETE /event-types/:id response

* docs: GET /event-types/:username/public response

* docs: prod docs show only event-types, bookings cancel and reschedule, managed users

* fix merge main

* Revert "docs: prod docs show only event-types, bookings cancel and reschedule, managed users"

This reverts commit 96cdc4b4840e3841c6ed27bd3a030d0574aad19e.

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
This commit is contained in:
Lauris Skraucis
2024-04-04 16:20:03 +00:00
committed by GitHub
co-authored by Morgan
parent c0523a31a7
commit 844076badb
9 changed files with 391 additions and 27 deletions
@@ -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<ApiSuccessResponse<EventType | AtomEventType>> {
const eventType = forAtom
? await this.eventTypesService.getUserEventTypeForAtom(user, Number(eventTypeId))
: await this.eventTypesService.getUserEventType(user.id, Number(eventTypeId));
): Promise<GetEventTypeOutput> {
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<ApiSuccessResponse<EventTypesByViewer>> {
async getEventTypes(@GetUser() user: UserWithProfile): Promise<GetEventTypesOutput> {
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<ApiSuccessResponse<EventTypesPublic>> {
async getPublicEventTypes(@Param("username") username: string): Promise<GetEventTypesPublicOutput> {
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<ApiResponse<UpdateEventTypeReturn["eventType"]>> {
): Promise<UpdateEventTypeOutput> {
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<ApiResponse<EventType>> {
): Promise<DeleteEventTypeOutput> {
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,
},
};
}
}
@@ -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;
}
@@ -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;
}
@@ -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[];
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
+205 -5
View File
@@ -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": {
+6
View File
@@ -43,4 +43,10 @@ export const eventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
aiPhoneCallConfig: true,
assignAllTeamMembers: true,
recurringEvent: true,
locations: true,
bookingFields: true,
useEventTypeDestinationCalendarEmail: true,
secondaryEmailId: true,
bookingLimits: true,
durationLimits: true,
});