diff --git a/lib/validations/team.ts b/lib/validations/team.ts new file mode 100644 index 0000000000..9ed08f90d5 --- /dev/null +++ b/lib/validations/team.ts @@ -0,0 +1,19 @@ +import { withValidation } from "next-validations"; +import { z } from "zod"; + +const schemaTeam = z + .object({ + slug: z.string().min(3), + name: z.string().min(3), + hideBranding: z.boolean().default(false), + bio: z.string().min(3).optional(), + logo: z.string().optional(), + }) + .strict(); // Adding strict so that we can disallow passing in extra fields +const withValidTeam = withValidation({ + schema: schemaTeam, + type: "Zod", + mode: "body", +}); + +export { schemaTeam, withValidTeam }; diff --git a/pages/api/team/[id]/delete.ts b/pages/api/team/[id]/delete.ts new file mode 100644 index 0000000000..aee327a197 --- /dev/null +++ b/pages/api/team/[id]/delete.ts @@ -0,0 +1,36 @@ +import prisma from "@calcom/prisma"; + +import type { NextApiRequest, NextApiResponse } from "next"; + +import { schemaQueryId, withValidQueryIdTransformParseInt } from "@lib/validations/queryIdTransformParseInt"; + + +type ResponseData = { + message?: string; + error?: unknown; +}; + +export async function team(req: NextApiRequest, res: NextApiResponse) { + const { query, method } = req; + const safe = await schemaQueryId.safeParse(query); + if (safe.success) { + if (method === "DELETE") { + // DELETE WILL DELETE THE EVENT TYPE + prisma.team + .delete({ where: { id: safe.data.id } }) + .then(() => { + // We only remove the team type from the database if there's an existing resource. + res.status(200).json({ message: `team-type with id: ${safe.data.id} deleted successfully` }); + }) + .catch((error) => { + // This catches the error thrown by prisma.team.delete() if the resource is not found. + res.status(400).json({ message: `Resource with id:${safe.data.id} was not found`, error: error }); + }); + } else { + // Reject any other HTTP method than POST + res.status(405).json({ message: "Only DELETE Method allowed in /team-types/[id]/delete endpoint" }); + } + } +} + +export default withValidQueryIdTransformParseInt(team); diff --git a/pages/api/team/[id]/edit.ts b/pages/api/team/[id]/edit.ts new file mode 100644 index 0000000000..ac0fdc1517 --- /dev/null +++ b/pages/api/team/[id]/edit.ts @@ -0,0 +1,37 @@ +import prisma from "@calcom/prisma"; + +import { Team } from "@calcom/prisma/client"; +import type { NextApiRequest, NextApiResponse } from "next"; + +import { schemaTeam, withValidTeam } from "@lib/validations/team"; +import { schemaQueryId, withValidQueryIdTransformParseInt } from "@lib/validations/queryIdTransformParseInt"; + +type ResponseData = { + data?: Team; + message?: string; + error?: unknown; +}; + +export async function editTeam(req: NextApiRequest, res: NextApiResponse) { + const { query, body, method } = req; + const safeQuery = await schemaQueryId.safeParse(query); + const safeBody = await schemaTeam.safeParse(body); + + if (method === "PATCH") { + if (safeQuery.success && safeBody.success) { + await prisma.team.update({ + where: { id: safeQuery.data.id }, + data: safeBody.data, + }).then(team => { + res.status(200).json({ data: team }); + }).catch(error => { + res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error }) + }); + } + } else { + // Reject any other HTTP method than POST + res.status(405).json({ message: "Only PATCH Method allowed for updating team-types" }); + } +} + +export default withValidQueryIdTransformParseInt(withValidTeam(editTeam)); diff --git a/pages/api/team/[id]/index.ts b/pages/api/team/[id]/index.ts new file mode 100644 index 0000000000..50a600ca58 --- /dev/null +++ b/pages/api/team/[id]/index.ts @@ -0,0 +1,31 @@ +import prisma from "@calcom/prisma"; + +import { Team } from "@calcom/prisma/client"; +import type { NextApiRequest, NextApiResponse } from "next"; + +import { schemaQueryId, withValidQueryIdTransformParseInt } from "@lib/validations/queryIdTransformParseInt"; + +type ResponseData = { + data?: Team; + message?: string; + error?: unknown; +}; + +export async function team(req: NextApiRequest, res: NextApiResponse) { + const { query, method } = req; + const safe = await schemaQueryId.safeParse(query); + if (safe.success) { + if (method === "GET") { + const team = await prisma.team.findUnique({ where: { id: safe.data.id } }); + + if (team) res.status(200).json({ data: team }); + if (!team) res.status(404).json({ message: "Event type not found" }); + } else { + // Reject any other HTTP method than POST + res.status(405).json({ message: "Only GET Method allowed" }); + } + } +} + + +export default withValidQueryIdTransformParseInt(team); diff --git a/pages/api/team/index.ts b/pages/api/team/index.ts new file mode 100644 index 0000000000..d00f092c99 --- /dev/null +++ b/pages/api/team/index.ts @@ -0,0 +1,19 @@ +import prisma from "@calcom/prisma"; + +import { Team } from "@calcom/prisma/client"; +import type { NextApiRequest, NextApiResponse } from "next"; + +type ResponseData = { + data?: Team[]; + error?: unknown; +}; + +export default async function team(req: NextApiRequest, res: NextApiResponse) { + try { + const teams = await prisma.team.findMany(); + res.status(200).json({ data: { ...teams } }); + } catch (error) { + // FIXME: Add zod for validation/error handling + res.status(400).json({ error: error }); + } +} diff --git a/pages/api/team/new.ts b/pages/api/team/new.ts new file mode 100644 index 0000000000..ebcb513777 --- /dev/null +++ b/pages/api/team/new.ts @@ -0,0 +1,30 @@ +import prisma from "@calcom/prisma"; + +import { Team } from "@calcom/prisma/client"; +import type { NextApiRequest, NextApiResponse } from "next"; + +import { schemaTeam, withValidTeam } from "@lib/validations/team"; + +type ResponseData = { + data?: Team; + message?: string; + error?: string; +}; + +async function createTeam(req: NextApiRequest, res: NextApiResponse) { + const { body, method } = req; + if (method === "POST") { + const safe = schemaTeam.safeParse(body); + if (safe.success && safe.data) { + await prisma.team + .create({ data: safe.data }) + .then((team) => res.status(201).json({ data: team })) + .catch((error) => res.status(400).json({ message: "Could not create team", error: error })); + } + } else { + // Reject any other HTTP method than POST + res.status(405).json({ error: "Only POST Method allowed" }); + } +} + +export default withValidTeam(createTeam);