diff --git a/lib/types.ts b/lib/types.ts index 100fde2b61..cec3f65c0b 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -21,10 +21,12 @@ export type BaseResponse = { message?: string; error?: Error; }; + // User export type UserResponse = BaseResponse & { data?: Partial; }; + export type UsersResponse = BaseResponse & { data?: Partial[]; }; diff --git a/pages/api/_middleware.ts b/pages/api/_middleware.ts index bd5d664589..35529757ba 100644 --- a/pages/api/_middleware.ts +++ b/pages/api/_middleware.ts @@ -9,7 +9,7 @@ export default async function requireApiKeyAsQueryParams({ nextUrl }: NextReques const apiKey = nextUrl.searchParams.get("apiKey"); if (apiKey) return response; - // if no apiKey is passed, we throw early a 401 unauthorized + // if no apiKey is passed, we throw early a 401 unauthorized asking for a valid apiKey else new NextResponse( JSON.stringify({ diff --git a/pages/api/docs.ts b/pages/api/docs.ts index e855eacfd8..8e489785bd 100644 --- a/pages/api/docs.ts +++ b/pages/api/docs.ts @@ -1,12 +1,14 @@ +import pjson from "@/package.json"; import { withSwagger } from "next-swagger-doc"; const swaggerHandler = withSwagger({ definition: { openapi: "3.0.0", info: { - title: "Cal.com Public API", - version: "1.0.0", + title: `${pjson.name}: ${pjson.description}`, + version: pjson.version, }, + tags: ["users", "teams"], }, apiFolder: "pages/api", }); diff --git a/pages/api/event-types/[id]/delete.ts b/pages/api/event-types/[id]/delete.ts index 8b9add8c87..4ac7f612dc 100644 --- a/pages/api/event-types/[id]/delete.ts +++ b/pages/api/event-types/[id]/delete.ts @@ -13,7 +13,7 @@ import { * @swagger * /api/eventTypes/:id/delete: * delete: - * description: Remove an existing eventType + * summary: Remove an existing eventType * responses: * 201: * description: OK, eventType removed successfuly diff --git a/pages/api/event-types/[id]/edit.ts b/pages/api/event-types/[id]/edit.ts index ecf8a42f76..08458274e3 100644 --- a/pages/api/event-types/[id]/edit.ts +++ b/pages/api/event-types/[id]/edit.ts @@ -18,7 +18,7 @@ import { * @swagger * /api/eventTypes/:id/edit: * patch: - * description: Edits an existing eventType + * summary: Edits an existing eventType * responses: * 201: * description: OK, eventType edited successfuly diff --git a/pages/api/event-types/[id]/index.ts b/pages/api/event-types/[id]/index.ts index cc9838dbb7..9a7236577b 100644 --- a/pages/api/event-types/[id]/index.ts +++ b/pages/api/event-types/[id]/index.ts @@ -12,9 +12,16 @@ import { /** * @swagger - * /api/eventTypes/:id: + * /api/eventTypes/{id}: * get: - * description: find eventType by ID + * summary: find eventType by ID + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the event type to get * responses: * 200: * description: OK diff --git a/pages/api/event-types/index.ts b/pages/api/event-types/index.ts index a6ef52c501..a9bd50bce7 100644 --- a/pages/api/event-types/index.ts +++ b/pages/api/event-types/index.ts @@ -10,7 +10,7 @@ import { schemaEventTypePublic } from "@lib/validations/eventType"; * @swagger * /api/eventTypes: * get: - * description: Returns all eventTypes + * summary: Returns all eventTypes * responses: * 200: * description: OK diff --git a/pages/api/event-types/new.ts b/pages/api/event-types/new.ts index 17d2e06190..e0a6bf4707 100644 --- a/pages/api/event-types/new.ts +++ b/pages/api/event-types/new.ts @@ -14,7 +14,7 @@ import { * @swagger * /api/eventTypes/new: * post: - * description: Creates a new eventType + * summary: Creates a new eventType * responses: * 201: * description: OK, eventType created diff --git a/pages/api/memberships/[id]/delete.ts b/pages/api/memberships/[id]/delete.ts index 5cbd96fca4..b33148e6d6 100644 --- a/pages/api/memberships/[id]/delete.ts +++ b/pages/api/memberships/[id]/delete.ts @@ -2,28 +2,53 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { - schemaQueryIdParseInt, - withValidQueryIdTransformParseInt, -} from "@lib/validations/shared/queryIdTransformParseInt"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { BaseResponse } from "@lib/types"; +import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; -type ResponseData = { - message?: string; - error?: unknown; -}; +/** + * @swagger + * /api/memberships/{userId}_{teamId}/delete: + * delete: + * summary: Remove an existing membership + * parameters: + * - in: path + * - name: userId + * schema: + * type: integer + * required: true + * description: Numeric ID of the user to get the membership of + * * - name: teamId + * schema: + * type: integer + * required: true + * description: Numeric ID of the team to get the membership of + * tags: + * - memberships + * responses: + * 201: + * description: OK, membership removed successfuly + * model: Membership + * 400: + * description: Bad request. Membership id is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +export async function deleteMembership(req: NextApiRequest, res: NextApiResponse) { + const safe = await schemaQueryIdAsString.safeParse(req.query); + if (!safe.success) throw new Error("Invalid request query", safe.error); + const [userId, teamId] = safe.data.id.split("_"); + const data = await prisma.membership.delete({ + where: { userId_teamId: { userId: parseInt(userId), teamId: parseInt(teamId) } }, + }); -export async function deleteMembership(req: NextApiRequest, res: NextApiResponse) { - const { query, method } = req; - const safe = await schemaQueryIdParseInt.safeParse(query); - if (method === "DELETE" && safe.success && safe.data) { - const membership = await prisma.membership.delete({ where: { id: safe.data.id } }); - // We only remove the membership type from the database if there's an existing resource. - if (membership) - res.status(200).json({ message: `membership with id: ${safe.data.id} deleted successfully` }); - // This catches the error thrown by prisma.membership.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was not found` }); - // Reject any other HTTP method than POST - } else res.status(405).json({ message: "Only DELETE Method allowed" }); + if (data) res.status(200).json({ message: `Membership with id: ${safe.data.id} deleted successfully` }); + else + (error: Error) => + res.status(400).json({ + message: `Membership with id: ${safe.data.id} was not able to be processed`, + error, + }); } -export default withValidQueryIdTransformParseInt(deleteMembership); +export default withMiddleware("HTTP_DELETE")(withValidQueryIdString(deleteMembership)); diff --git a/pages/api/memberships/[id]/edit.ts b/pages/api/memberships/[id]/edit.ts index 990c63914e..66c6ccec24 100644 --- a/pages/api/memberships/[id]/edit.ts +++ b/pages/api/memberships/[id]/edit.ts @@ -1,38 +1,51 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Membership } from "@calcom/prisma/client"; -import { schemaMembership, withValidMembership } from "@lib/validations/membership"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { MembershipResponse } from "@lib/types"; import { - schemaQueryIdParseInt, - withValidQueryIdTransformParseInt, -} from "@lib/validations/shared/queryIdTransformParseInt"; + schemaMembershipBodyParams, + schemaMembershipPublic, + withValidMembership, +} from "@lib/validations/membership"; +import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; -type ResponseData = { - data?: Membership; - message?: string; - error?: unknown; -}; +/** + * @swagger + * /api/memberships/{id}/edit: + * patch: + * summary: Edits an existing membership + * tags: + * - memberships + * responses: + * 201: + * description: OK, membership edited successfuly + * model: Membership + * 400: + * description: Bad request. Membership body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +export async function editMembership(req: NextApiRequest, res: NextApiResponse) { + const safeQuery = await schemaQueryIdAsString.safeParse(req.query); + const safeBody = await schemaMembershipBodyParams.safeParse(req.body); + if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request"); + const [userId, teamId] = safeQuery.data.id.split("_"); -export async function editMembership(req: NextApiRequest, res: NextApiResponse) { - const { query, body, method } = req; - const safeQuery = await schemaQueryIdParseInt.safeParse(query); - const safeBody = await schemaMembership.safeParse(body); + const membership = await prisma.membership.update({ + where: { userId_teamId: { userId: parseInt(userId), teamId: parseInt(teamId) } }, + data: safeBody.data, + }); + const data = schemaMembershipPublic.parse(membership); - if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.membership.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }); - if (data) res.status(200).json({ data }); - else - res - .status(404) - .json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }); - - // Reject any other HTTP method than POST - } else res.status(405).json({ message: "Only PATCH Method allowed for updating memberships" }); + if (data) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, + error, + }); } -export default withValidQueryIdTransformParseInt(withValidMembership(editMembership)); +export default withMiddleware("HTTP_PATCH")(withValidQueryIdString(withValidMembership(editMembership))); diff --git a/pages/api/memberships/[id]/index.ts b/pages/api/memberships/[id]/index.ts index 6aef005fa9..5bc5f79496 100644 --- a/pages/api/memberships/[id]/index.ts +++ b/pages/api/memberships/[id]/index.ts @@ -1,29 +1,57 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Membership } from "@calcom/prisma/client"; -import { - schemaQueryIdParseInt, - withValidQueryIdTransformParseInt, -} from "@lib/validations/shared/queryIdTransformParseInt"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { MembershipResponse } from "@lib/types"; +import { schemaMembershipPublic } from "@lib/validations/membership"; +import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; -type ResponseData = { - data?: Membership; - message?: string; - error?: unknown; -}; +/** + * @swagger + * /api/memberships/{userId}_{teamId}: + * get: + * summary: find membership by userID and teamID + * parameters: + * - in: path + * name: userId + * schema: + * type: integer + * required: true + * description: Numeric userId of the membership to get + * - in: path + * name: teamId + * schema: + * type: integer + * required: true + * description: Numeric teamId of the membership to get + * tags: + * - memberships + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: Membership was not found + */ +export async function membershipById(req: NextApiRequest, res: NextApiResponse) { + const safe = await schemaQueryIdAsString.safeParse(req.query); + if (!safe.success) throw new Error("Invalid request query"); + const [userId, teamId] = safe.data.id.split("_"); -export async function membership(req: NextApiRequest, res: NextApiResponse) { - const { query, method } = req; - const safe = await schemaQueryIdParseInt.safeParse(query); - if (method === "GET" && safe.success) { - const data = await prisma.membership.findUnique({ where: { id: safe.data.id } }); + const membership = await prisma.membership.findUnique({ + where: { userId_teamId: { userId: parseInt(userId), teamId: parseInt(teamId) } }, + }); + const data = schemaMembershipPublic.parse(membership); - if (data) res.status(200).json({ data }); - else res.status(404).json({ message: "Event type not found" }); - // Reject any other HTTP method than POST - } else res.status(405).json({ message: "Only GET Method allowed" }); + if (membership) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: "Membership was not found", + error, + }); } -export default withValidQueryIdTransformParseInt(membership); +export default withMiddleware("HTTP_GET")(withValidQueryIdString(membershipById)); diff --git a/pages/api/memberships/index.ts b/pages/api/memberships/index.ts index 59e5c21b5c..d53670ce92 100644 --- a/pages/api/memberships/index.ts +++ b/pages/api/memberships/index.ts @@ -1,15 +1,37 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Membership } from "@calcom/prisma/client"; -type ResponseData = { - data?: Membership[]; - error?: unknown; -}; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { MembershipsResponse } from "@lib/types"; +import { schemaMembershipPublic } from "@lib/validations/membership"; + +/** + * @swagger + * /api/memberships: + * get: + * summary: Returns all memberships + * tags: + * - memberships + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: No memberships were found + */ +async function allMemberships(_: NextApiRequest, res: NextApiResponse) { + const memberships = await prisma.membership.findMany(); + const data = memberships.map((membership) => schemaMembershipPublic.parse(membership)); -export default async function membership(req: NextApiRequest, res: NextApiResponse) { - const data = await prisma.membership.findMany(); if (data) res.status(200).json({ data }); - else res.status(400).json({ error: "No data found" }); + else + (error: Error) => + res.status(404).json({ + message: "No Memberships were found", + error, + }); } + +export default withMiddleware("HTTP_GET")(allMemberships); diff --git a/pages/api/memberships/new.ts b/pages/api/memberships/new.ts index 8df61fc964..e3b9dbe02f 100644 --- a/pages/api/memberships/new.ts +++ b/pages/api/memberships/new.ts @@ -1,26 +1,45 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Membership } from "@calcom/prisma/client"; -import { schemaMembership, withValidMembership } from "@lib/validations/membership"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { MembershipResponse } from "@lib/types"; +import { + schemaMembershipBodyParams, + schemaMembershipPublic, + withValidMembership, +} from "@lib/validations/membership"; -type ResponseData = { - data?: Membership; - message?: string; - error?: string; -}; +/** + * @swagger + * /api/memberships/new: + * post: + * summary: Creates a new membership + * tags: + * - memberships + * responses: + * 201: + * description: OK, membership created + * model: Membership + * 400: + * description: Bad request. Membership body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +async function createMembership(req: NextApiRequest, res: NextApiResponse) { + const safe = schemaMembershipBodyParams.safeParse(req.body); + if (!safe.success) throw new Error("Invalid request body", safe.error); -async function createMembership(req: NextApiRequest, res: NextApiResponse) { - const { body, method } = req; - const safe = schemaMembership.safeParse(body); - if (method === "POST" && safe.success) { - await prisma.membership - .create({ data: safe.data }) - .then((data) => res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create membership type", error: error })); - // Reject any other HTTP method than POST - } else res.status(405).json({ error: "Only POST Method allowed" }); + const membership = await prisma.membership.create({ data: safe.data }); + const data = schemaMembershipPublic.parse(membership); + + if (data) res.status(201).json({ data, message: "Membership created successfully" }); + else + (error: Error) => + res.status(400).json({ + message: "Could not create new membership", + error, + }); } -export default withValidMembership(createMembership); +export default withMiddleware("HTTP_POST")(withValidMembership(createMembership)); diff --git a/pages/api/schedules/[id]/delete.ts b/pages/api/schedules/[id]/delete.ts index 17aba616cf..4b037be9d2 100644 --- a/pages/api/schedules/[id]/delete.ts +++ b/pages/api/schedules/[id]/delete.ts @@ -2,27 +2,42 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { BaseResponse } from "@lib/types"; import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt, } from "@lib/validations/shared/queryIdTransformParseInt"; -type ResponseData = { - message?: string; - error?: unknown; -}; +/** + * @swagger + * /api/schedules/:id/delete: + * delete: + * summary: Remove an existing schedule + * tags: + * - schedules + * responses: + * 201: + * description: OK, schedule removed successfuly + * model: Schedule + * 400: + * description: Bad request. Schedule id is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +export async function deleteSchedule(req: NextApiRequest, res: NextApiResponse) { + const safe = await schemaQueryIdParseInt.safeParse(req.query); + if (!safe.success) throw new Error("Invalid request query", safe.error); -export async function deleteSchedule(req: NextApiRequest, res: NextApiResponse) { - const { query, method } = req; - const safe = await schemaQueryIdParseInt.safeParse(query); - if (method === "DELETE" && safe.success && safe.data) { - const schedule = await prisma.schedule.delete({ where: { id: safe.data.id } }); - // We only remove the schedule type from the database if there's an existing resource. - if (schedule) res.status(200).json({ message: `schedule with id: ${safe.data.id} deleted successfully` }); - // This catches the error thrown by prisma.schedule.delete() if the resource is not found. - else res.status(400).json({ message: `Resource with id:${safe.data.id} was not found` }); - // Reject any other HTTP method than POST - } else res.status(405).json({ message: "Only DELETE Method allowed" }); + const data = await prisma.schedule.delete({ where: { id: safe.data.id } }); + + if (data) res.status(200).json({ message: `Schedule with id: ${safe.data.id} deleted successfully` }); + else + (error: Error) => + res.status(400).json({ + message: `Schedule with id: ${safe.data.id} was not able to be processed`, + error, + }); } -export default withValidQueryIdTransformParseInt(deleteSchedule); +export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteSchedule)); diff --git a/pages/api/schedules/[id]/edit.ts b/pages/api/schedules/[id]/edit.ts index b40923504e..2f750536f8 100644 --- a/pages/api/schedules/[id]/edit.ts +++ b/pages/api/schedules/[id]/edit.ts @@ -1,38 +1,51 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Schedule } from "@calcom/prisma/client"; -import { schemaSchedule, withValidSchedule } from "@lib/validations/schedule"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { ScheduleResponse } from "@lib/types"; +import { schemaScheduleBodyParams, schemaSchedulePublic, withValidSchedule } from "@lib/validations/schedule"; import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt, } from "@lib/validations/shared/queryIdTransformParseInt"; -type ResponseData = { - data?: Schedule; - message?: string; - error?: unknown; -}; +/** + * @swagger + * /api/schedules/:id/edit: + * patch: + * summary: Edits an existing schedule + * tags: + * - schedules + * responses: + * 201: + * description: OK, schedule edited successfuly + * model: Schedule + * 400: + * description: Bad request. Schedule body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +export async function editSchedule(req: NextApiRequest, res: NextApiResponse) { + const safeQuery = await schemaQueryIdParseInt.safeParse(req.query); + const safeBody = await schemaScheduleBodyParams.safeParse(req.body); -export async function editSchedule(req: NextApiRequest, res: NextApiResponse) { - const { query, body, method } = req; - const safeQuery = await schemaQueryIdParseInt.safeParse(query); - const safeBody = await schemaSchedule.safeParse(body); + if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request"); + const schedule = await prisma.schedule.update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }); + const data = schemaSchedulePublic.parse(schedule); - if (method === "PATCH" && safeQuery.success && safeBody.success) { - const data = await prisma.schedule.update({ - where: { id: safeQuery.data.id }, - data: safeBody.data, - }); - if (data) res.status(200).json({ data }); - else - res - .status(404) - .json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }); - - // Reject any other HTTP method than POST - } else res.status(405).json({ message: "Only PATCH Method allowed for updating schedules" }); + if (data) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, + error, + }); } -export default withValidQueryIdTransformParseInt(withValidSchedule(editSchedule)); +export default withMiddleware("HTTP_PATCH")( + withValidQueryIdTransformParseInt(withValidSchedule(editSchedule)) +); diff --git a/pages/api/schedules/[id]/index.ts b/pages/api/schedules/[id]/index.ts index 482267fcbe..1a8675d53f 100644 --- a/pages/api/schedules/[id]/index.ts +++ b/pages/api/schedules/[id]/index.ts @@ -1,29 +1,51 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Schedule } from "@calcom/prisma/client"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { ScheduleResponse } from "@lib/types"; +import { schemaSchedulePublic } from "@lib/validations/schedule"; import { schemaQueryIdParseInt, withValidQueryIdTransformParseInt, } from "@lib/validations/shared/queryIdTransformParseInt"; -type ResponseData = { - data?: Schedule; - message?: string; - error?: unknown; -}; +/** + * @swagger + * /api/schedules/{id}: + * get: + * summary: Get schedule by ID + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the schedule to delete + * tags: + * - schedules + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: Schedule was not found + */ +export async function scheduleById(req: NextApiRequest, res: NextApiResponse) { + const safe = await schemaQueryIdParseInt.safeParse(req.query); + if (!safe.success) throw new Error("Invalid request query"); -export async function schedule(req: NextApiRequest, res: NextApiResponse) { - const { query, method } = req; - const safe = await schemaQueryIdParseInt.safeParse(query); - if (method === "GET" && safe.success) { - const data = await prisma.schedule.findUnique({ where: { id: safe.data.id } }); + const schedule = await prisma.schedule.findUnique({ where: { id: safe.data.id } }); + const data = schemaSchedulePublic.parse(schedule); - if (data) res.status(200).json({ data }); - else res.status(404).json({ message: "Event type not found" }); - // Reject any other HTTP method than POST - } else res.status(405).json({ message: "Only GET Method allowed" }); + if (schedule) res.status(200).json({ data }); + else + (error: Error) => + res.status(404).json({ + message: "Schedule was not found", + error, + }); } -export default withValidQueryIdTransformParseInt(schedule); +export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(scheduleById)); diff --git a/pages/api/schedules/index.ts b/pages/api/schedules/index.ts index fc22c4e2e0..cd09534c99 100644 --- a/pages/api/schedules/index.ts +++ b/pages/api/schedules/index.ts @@ -1,15 +1,37 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Schedule } from "@calcom/prisma/client"; -type ResponseData = { - data?: Schedule[]; - error?: unknown; -}; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import { SchedulesResponse } from "@lib/types"; +import { schemaSchedulePublic } from "@lib/validations/schedule"; + +/** + * @swagger + * /api/schedules: + * get: + * summary: Returns all schedules + * tags: + * - schedules + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: No schedules were found + */ +async function allSchedules(_: NextApiRequest, res: NextApiResponse) { + const schedules = await prisma.schedule.findMany(); + const data = schedules.map((schedule) => schemaSchedulePublic.parse(schedule)); -export default async function schedule(req: NextApiRequest, res: NextApiResponse) { - const data = await prisma.schedule.findMany(); if (data) res.status(200).json({ data }); - else res.status(400).json({ error: "No data found" }); + else + (error: Error) => + res.status(404).json({ + message: "No Schedules were found", + error, + }); } + +export default withMiddleware("HTTP_GET")(allSchedules); diff --git a/pages/api/schedules/new.ts b/pages/api/schedules/new.ts index 081acc9a5c..d4a3ea4416 100644 --- a/pages/api/schedules/new.ts +++ b/pages/api/schedules/new.ts @@ -1,26 +1,41 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; -import { Schedule } from "@calcom/prisma/client"; -import { schemaSchedule, withValidSchedule } from "@lib/validations/schedule"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; +import type { ScheduleResponse } from "@lib/types"; +import { schemaScheduleBodyParams, schemaSchedulePublic, withValidSchedule } from "@lib/validations/schedule"; -type ResponseData = { - data?: Schedule; - message?: string; - error?: string; -}; +/** + * @swagger + * /api/schedules/new: + * post: + * summary: Creates a new schedule + * tags: + * - schedules + * responses: + * 201: + * description: OK, schedule created + * model: Schedule + * 400: + * description: Bad request. Schedule body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ +async function createSchedule(req: NextApiRequest, res: NextApiResponse) { + const safe = schemaScheduleBodyParams.safeParse(req.body); + if (!safe.success) throw new Error("Invalid request body", safe.error); -async function createSchedule(req: NextApiRequest, res: NextApiResponse) { - const { body, method } = req; - const safe = schemaSchedule.safeParse(body); - if (method === "POST" && safe.success) { - await prisma.schedule - .create({ data: safe.data }) - .then((data) => res.status(201).json({ data })) - .catch((error) => res.status(400).json({ message: "Could not create schedule type", error: error })); - // Reject any other HTTP method than POST - } else res.status(405).json({ error: "Only POST Method allowed" }); + const schedule = await prisma.schedule.create({ data: safe.data }); + const data = schemaSchedulePublic.parse(schedule); + + if (data) res.status(201).json({ data, message: "Schedule created successfully" }); + else + (error: Error) => + res.status(400).json({ + message: "Could not create new schedule", + error, + }); } -export default withValidSchedule(createSchedule); +export default withMiddleware("HTTP_POST")(withValidSchedule(createSchedule)); diff --git a/pages/api/selected-calendars/[id]/delete.ts b/pages/api/selected-calendars/[id]/delete.ts index 249912dce9..d4f0fac746 100644 --- a/pages/api/selected-calendars/[id]/delete.ts +++ b/pages/api/selected-calendars/[id]/delete.ts @@ -13,7 +13,7 @@ import { * @swagger * /api/selectedCalendars/:id/delete: * delete: - * description: Remove an existing selectedCalendar + * summary: Remove an existing selectedCalendar * responses: * 201: * description: OK, selectedCalendar removed successfuly diff --git a/pages/api/selected-calendars/[id]/edit.ts b/pages/api/selected-calendars/[id]/edit.ts index 96c9f08675..950c4c04eb 100644 --- a/pages/api/selected-calendars/[id]/edit.ts +++ b/pages/api/selected-calendars/[id]/edit.ts @@ -18,7 +18,7 @@ import { * @swagger * /api/selectedCalendars/:id/edit: * patch: - * description: Edits an existing selectedCalendar + * summary: Edits an existing selectedCalendar * responses: * 201: * description: OK, selectedCalendar edited successfuly diff --git a/pages/api/selected-calendars/[id]/index.ts b/pages/api/selected-calendars/[id]/index.ts index cf932ac5a2..3867c3834a 100644 --- a/pages/api/selected-calendars/[id]/index.ts +++ b/pages/api/selected-calendars/[id]/index.ts @@ -12,9 +12,18 @@ import { /** * @swagger - * /api/selectedCalendars/:id: + * /api/selectedCalendars/{id}: * get: - * description: find selectedCalendar by ID + * summary: find selectedCalendar by ID + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the user to delete + * tags: + * - selected-calendars * responses: * 200: * description: OK diff --git a/pages/api/selected-calendars/index.ts b/pages/api/selected-calendars/index.ts index ab80b3aa0f..cb13635eec 100644 --- a/pages/api/selected-calendars/index.ts +++ b/pages/api/selected-calendars/index.ts @@ -10,7 +10,7 @@ import { schemaSelectedCalendarPublic } from "@lib/validations/selected-calendar * @swagger * /api/selectedCalendars: * get: - * description: Returns all selected calendars + * summary: Returns all selected calendars * responses: * 200: * description: OK diff --git a/pages/api/selected-calendars/new.ts b/pages/api/selected-calendars/new.ts index 22ae2a8657..dbca6d85a0 100644 --- a/pages/api/selected-calendars/new.ts +++ b/pages/api/selected-calendars/new.ts @@ -14,7 +14,7 @@ import { * @swagger * /api/selectedCalendars/new: * post: - * description: Creates a new selected calendar + * summary: Creates a new selected calendar * responses: * 201: * description: OK, selected calendar created diff --git a/pages/api/teams/[id]/delete.ts b/pages/api/teams/[id]/delete.ts index cf3825fd96..657e9628ce 100644 --- a/pages/api/teams/[id]/delete.ts +++ b/pages/api/teams/[id]/delete.ts @@ -13,7 +13,9 @@ import { * @swagger * /api/teams/:id/delete: * delete: - * description: Remove an existing team + * summary: Remove an existing team + * tags: + * - teams * responses: * 201: * description: OK, team removed successfuly diff --git a/pages/api/teams/[id]/edit.ts b/pages/api/teams/[id]/edit.ts index 4b1696d207..2b0411cdf8 100644 --- a/pages/api/teams/[id]/edit.ts +++ b/pages/api/teams/[id]/edit.ts @@ -14,7 +14,9 @@ import { schemaTeamBodyParams, schemaTeamPublic, withValidTeam } from "@lib/vali * @swagger * /api/teams/:id/edit: * patch: - * description: Edits an existing team + * summary: Edits an existing team + * tags: + * - teams * responses: * 201: * description: OK, team edited successfuly diff --git a/pages/api/teams/[id]/index.ts b/pages/api/teams/[id]/index.ts index 1047a479ef..0dedf16159 100644 --- a/pages/api/teams/[id]/index.ts +++ b/pages/api/teams/[id]/index.ts @@ -14,7 +14,9 @@ import { schemaTeamPublic } from "@lib/validations/team"; * @swagger * /api/teams/:id: * get: - * description: find team by ID + * summary: find team by ID + * tags: + * - teams * responses: * 200: * description: OK diff --git a/pages/api/teams/index.ts b/pages/api/teams/index.ts index 7497539eeb..a4ed336c38 100644 --- a/pages/api/teams/index.ts +++ b/pages/api/teams/index.ts @@ -10,7 +10,9 @@ import { schemaTeamPublic } from "@lib/validations/team"; * @swagger * /api/teams: * get: - * description: Returns all teams + * summary: Returns all teams + * tags: + * - teams * responses: * 200: * description: OK diff --git a/pages/api/teams/new.ts b/pages/api/teams/new.ts index b78759d249..6100b5c42d 100644 --- a/pages/api/teams/new.ts +++ b/pages/api/teams/new.ts @@ -10,7 +10,9 @@ import { schemaTeamBodyParams, schemaTeamPublic, withValidTeam } from "@lib/vali * @swagger * /api/teams/new: * post: - * description: Creates a new team + * summary: Creates a new team + * tags: + * - teams * responses: * 201: * description: OK, team created diff --git a/pages/api/users/[id]/delete.ts b/pages/api/users/[id]/delete.ts index 51b6e36cf6..b8b5a7a59f 100644 --- a/pages/api/users/[id]/delete.ts +++ b/pages/api/users/[id]/delete.ts @@ -11,9 +11,18 @@ import { /** * @swagger - * /api/users/:id/delete: + * /api/users/{id}/delete: * delete: - * description: Remove an existing user + * summary: Remove an existing user + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the user to delete + * tags: + * - users * responses: * 201: * description: OK, user removed successfuly diff --git a/pages/api/users/[id]/edit.ts b/pages/api/users/[id]/edit.ts index b78cb1f83c..3f37b36d77 100644 --- a/pages/api/users/[id]/edit.ts +++ b/pages/api/users/[id]/edit.ts @@ -14,7 +14,9 @@ import { schemaUserBodyParams, schemaUserPublic, withValidUser } from "@lib/vali * @swagger * /api/users/:id/edit: * patch: - * description: Edits an existing user + * summary: Edits an existing user + * tags: + * - users * responses: * 201: * description: OK, user edited successfuly diff --git a/pages/api/users/[id]/index.ts b/pages/api/users/[id]/index.ts index 04be633d5d..59987519b7 100644 --- a/pages/api/users/[id]/index.ts +++ b/pages/api/users/[id]/index.ts @@ -12,9 +12,18 @@ import { schemaUserPublic } from "@lib/validations/user"; /** * @swagger - * /api/users/:id: + * /api/users/{id}: * get: - * description: find user by ID + * summary: Get a user by ID + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: Numeric ID of the user to get + * tags: + * - users * responses: * 200: * description: OK diff --git a/pages/api/users/index.ts b/pages/api/users/index.ts index a748315a4a..6bb3763a88 100644 --- a/pages/api/users/index.ts +++ b/pages/api/users/index.ts @@ -10,7 +10,9 @@ import { schemaUserPublic } from "@lib/validations/user"; * @swagger * /api/users: * get: - * description: Returns all users + * summary: Get all users + * tags: + * - users * responses: * 200: * description: OK diff --git a/pages/api/users/new.ts b/pages/api/users/new.ts index fd717213e0..70e6497b9b 100644 --- a/pages/api/users/new.ts +++ b/pages/api/users/new.ts @@ -10,7 +10,16 @@ import { schemaUserBodyParams, schemaUserPublic, withValidUser } from "@lib/vali * @swagger * /api/users/new: * post: - * description: Creates a new user + * summary: Creates a new user + * requestBody: + description: Optional description in *Markdown* + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/User' + * tags: + * - users * responses: * 201: * description: OK, user created