feat: update attendees / availabilites / users endpoints and document parameters

This commit is contained in:
Agusti Fernandez Pardo
2022-04-01 22:05:10 +02:00
parent 2b4a745f12
commit 55f93cded6
14 changed files with 419 additions and 194 deletions
+38 -16
View File
@@ -2,27 +2,49 @@ 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/attendees/{id}/delete:
* delete:
* summary: Remove an existing attendee
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the attendee to delete
* tags:
* - attendees
* responses:
* 201:
* description: OK, attendee removed successfuly
* model: Attendee
* 400:
* description: Bad request. Attendee id is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function deleteAttendee(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query", safe.error);
export async function attendee(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "DELETE" && safe.success && safe.data) {
const attendee = await prisma.attendee.delete({ where: { id: safe.data.id } });
// We only remove the attendee type from the database if there's an existing resource.
if (attendee) res.status(200).json({ message: `attendee with id: ${safe.data.id} deleted successfully` });
// This catches the error thrown by prisma.attendee.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.attendee.delete({ where: { id: safe.data.id } });
if (data) res.status(200).json({ message: `Attendee with id: ${safe.data.id} deleted successfully` });
else
(error: Error) =>
res.status(400).json({
message: `Attendee with id: ${safe.data.id} was not able to be processed`,
error,
});
}
export default withValidQueryIdTransformParseInt(attendee);
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteAttendee));
+44 -27
View File
@@ -1,41 +1,58 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Attendee } from "@calcom/prisma/client";
import { schemaAttendee, withValidAttendee } from "@lib/validations/attendee";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { AttendeeResponse } from "@lib/types";
import { schemaAttendeeBodyParams, schemaAttendeePublic, withValidAttendee } from "@lib/validations/attendee";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Attendee;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/attendees/{id}/edit:
* patch:
* summary: Edit an existing attendee
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the attendee to edit
* tags:
* - attendees
* responses:
* 201:
* description: OK, attendee edited successfuly
* model: Attendee
* 400:
* description: Bad request. Attendee body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function editAttendee(req: NextApiRequest, res: NextApiResponse<AttendeeResponse>) {
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
const safeBody = await schemaAttendeeBodyParams.safeParse(req.body);
export async function editAttendee(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, body, method } = req;
const safeQuery = await schemaQueryIdParseInt.safeParse(query);
const safeBody = await schemaAttendee.safeParse(body);
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
const attendee = await prisma.attendee.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
const data = schemaAttendeePublic.parse(attendee);
if (method === "PATCH" && safeQuery.success && safeBody.success) {
await prisma.attendee
.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
})
.then((attendee) => {
res.status(200).json({ data: attendee });
})
.catch((error) => {
res
.status(404)
.json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error });
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,
});
// Reject any other HTTP method than POST
} else res.status(405).json({ message: "Only PATCH Method allowed for updating attendees" });
}
export default withValidQueryIdTransformParseInt(withValidAttendee(editAttendee));
export default withMiddleware("HTTP_PATCH")(
withValidQueryIdTransformParseInt(withValidAttendee(editAttendee))
);
+38 -17
View File
@@ -1,30 +1,51 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Attendee } from "@calcom/prisma/client";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { AttendeeResponse } from "@lib/types";
import { schemaAttendeePublic } from "@lib/validations/attendee";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Attendee;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/attendees/{id}:
* get:
* summary: Get a attendee by ID
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the attendee to get
* tags:
* - attendees
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: Attendee was not found
*/
export async function attendeeById(req: NextApiRequest, res: NextApiResponse<AttendeeResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query");
export async function attendee(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
const attendee = await prisma.attendee.findUnique({ where: { id: safe.data.id } });
const data = schemaAttendeePublic.parse(attendee);
if (method === "GET" && safe.success) {
const attendee = await prisma.attendee.findUnique({ where: { id: safe.data.id } });
if (attendee) res.status(200).json({ data: attendee });
if (!attendee) 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 (attendee) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "Attendee was not found",
error,
});
}
export default withValidQueryIdTransformParseInt(attendee);
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(attendeeById));
+31 -13
View File
@@ -1,19 +1,37 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Attendee } from "@calcom/prisma/client";
type ResponseData = {
data?: Attendee[];
error?: unknown;
};
import { withMiddleware } from "@lib/helpers/withMiddleware";
import { AttendeesResponse } from "@lib/types";
import { schemaAttendeePublic } from "@lib/validations/attendee";
export default async function attendee(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
try {
const data = await prisma.attendee.findMany();
res.status(200).json({ data });
} catch (error) {
// FIXME: Add zod for validation/error handling
res.status(400).json({ error: error });
}
/**
* @swagger
* /api/attendees:
* get:
* summary: Get all attendees
* tags:
* - attendees
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: No attendees were found
*/
async function allAttendees(_: NextApiRequest, res: NextApiResponse<AttendeesResponse>) {
const attendees = await prisma.attendee.findMany();
const data = attendees.map((attendee) => schemaAttendeePublic.parse(attendee));
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "No Attendees were found",
error,
});
}
export default withMiddleware("HTTP_GET")(allAttendees);
+39 -18
View File
@@ -1,27 +1,48 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Attendee } from "@calcom/prisma/client";
import { schemaAttendee, withValidAttendee } from "@lib/validations/attendee";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { AttendeeResponse } from "@lib/types";
import { schemaAttendeeBodyParams, schemaAttendeePublic, withValidAttendee } from "@lib/validations/attendee";
type ResponseData = {
data?: Attendee;
message?: string;
error?: string;
};
/**
* @swagger
* /api/attendees/new:
* post:
* summary: Creates a new attendee
* requestBody:
* description: Optional description in *Markdown*
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Attendee'
* tags:
* - attendees
* responses:
* 201:
* description: OK, attendee created
* model: Attendee
* 400:
* description: Bad request. Attendee body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
async function createAttendee(req: NextApiRequest, res: NextApiResponse<AttendeeResponse>) {
const safe = schemaAttendeeBodyParams.safeParse(req.body);
if (!safe.success) throw new Error("Invalid request body", safe.error);
async function createAttendee(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { body, method } = req;
const safe = schemaAttendee.safeParse(body);
const attendee = await prisma.attendee.create({ data: safe.data });
const data = schemaAttendeePublic.parse(attendee);
if (method === "POST" && safe.success) {
await prisma.attendee
.create({ data: safe.data })
.then((attendee) => res.status(201).json({ data: attendee }))
.catch((error) => res.status(400).json({ message: "Could not create attendee type", error: error }));
// Reject any other HTTP method than POST
} else res.status(405).json({ error: "Only POST Method allowed" });
if (data) res.status(201).json({ data, message: "Attendee created successfully" });
else
(error: Error) =>
res.status(400).json({
message: "Could not create new attendee",
error,
});
}
export default withValidAttendee(createAttendee);
export default withMiddleware("HTTP_POST")(withValidAttendee(createAttendee));
+38 -17
View File
@@ -2,28 +2,49 @@ 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/availabilites/{id}/delete:
* delete:
* summary: Remove an existing availability
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the availability to delete
* tags:
* - availabilites
* responses:
* 201:
* description: OK, availability removed successfuly
* model: Availability
* 400:
* description: Bad request. Availability id is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function deleteAvailability(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query", safe.error);
export async function availability(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
if (method === "DELETE" && safe.success && safe.data) {
const availability = await prisma.availability.delete({ where: { id: safe.data.id } });
// We only remove the availability type from the database if there's an existing resource.
if (availability)
res.status(200).json({ message: `availability with id: ${safe.data.id} deleted successfully` });
// This catches the error thrown by prisma.availability.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.availability.delete({ where: { id: safe.data.id } });
if (data) res.status(200).json({ message: `Availability with id: ${safe.data.id} deleted successfully` });
else
(error: Error) =>
res.status(400).json({
message: `Availability with id: ${safe.data.id} was not able to be processed`,
error,
});
}
export default withValidQueryIdTransformParseInt(availability);
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteAvailability));
+48 -27
View File
@@ -1,41 +1,62 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Availability } from "@calcom/prisma/client";
import { schemaAvailability, withValidAvailability } from "@lib/validations/availability";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { AvailabilityResponse } from "@lib/types";
import {
schemaAvailabilityBodyParams,
schemaAvailabilityPublic,
withValidAvailability,
} from "@lib/validations/availability";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Availability;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/availabilites/{id}/edit:
* patch:
* summary: Edit an existing availability
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the availability to edit
* tags:
* - availabilites
* responses:
* 201:
* description: OK, availability edited successfuly
* model: Availability
* 400:
* description: Bad request. Availability body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
export async function editAvailability(req: NextApiRequest, res: NextApiResponse<AvailabilityResponse>) {
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
const safeBody = await schemaAvailabilityBodyParams.safeParse(req.body);
export async function editAvailability(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, body, method } = req;
const safeQuery = await schemaQueryIdParseInt.safeParse(query);
const safeBody = await schemaAvailability.safeParse(body);
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
const availability = await prisma.availability.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
});
const data = schemaAvailabilityPublic.parse(availability);
if (method === "PATCH" && safeQuery.success && safeBody.success) {
await prisma.availability
.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
})
.then((availability) => {
res.status(200).json({ data: availability });
})
.catch((error) => {
res
.status(404)
.json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error });
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,
});
// Reject any other HTTP method than PATCH
} else res.status(405).json({ message: "Only PATCH Method allowed for updating availabilities" });
}
export default withValidQueryIdTransformParseInt(withValidAvailability(editAvailability));
export default withMiddleware("HTTP_PATCH")(
withValidQueryIdTransformParseInt(withValidAvailability(editAvailability))
);
+38 -17
View File
@@ -1,30 +1,51 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Availability } from "@calcom/prisma/client";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { AvailabilityResponse } from "@lib/types";
import { schemaAvailabilityPublic } from "@lib/validations/availability";
import {
schemaQueryIdParseInt,
withValidQueryIdTransformParseInt,
} from "@lib/validations/shared/queryIdTransformParseInt";
type ResponseData = {
data?: Availability;
message?: string;
error?: unknown;
};
/**
* @swagger
* /api/availabilites/{id}:
* get:
* summary: Get a availability by ID
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the availability to get
* tags:
* - availabilites
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: Availability was not found
*/
export async function availabilityById(req: NextApiRequest, res: NextApiResponse<AvailabilityResponse>) {
const safe = await schemaQueryIdParseInt.safeParse(req.query);
if (!safe.success) throw new Error("Invalid request query");
export async function availability(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { query, method } = req;
const safe = await schemaQueryIdParseInt.safeParse(query);
const availability = await prisma.availability.findUnique({ where: { id: safe.data.id } });
const data = schemaAvailabilityPublic.parse(availability);
if (method === "GET" && safe.success) {
const availability = await prisma.availability.findUnique({ where: { id: safe.data.id } });
if (availability) res.status(200).json({ data: availability });
if (!availability) 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 (availability) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "Availability was not found",
error,
});
}
export default withValidQueryIdTransformParseInt(availability);
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(availabilityById));
+31 -13
View File
@@ -1,19 +1,37 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Availability } from "@calcom/prisma/client";
type ResponseData = {
data?: Availability[];
error?: unknown;
};
import { withMiddleware } from "@lib/helpers/withMiddleware";
import { AvailabilitysResponse } from "@lib/types";
import { schemaAvailabilityPublic } from "@lib/validations/availability";
export default async function availability(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
try {
const data = await prisma.availability.findMany();
res.status(200).json({ data });
} catch (error) {
// FIXME: Add zod for validation/error handling
res.status(400).json({ error: error });
}
/**
* @swagger
* /api/availabilites:
* get:
* summary: Get all availabilites
* tags:
* - availabilites
* responses:
* 200:
* description: OK
* 401:
* description: Authorization information is missing or invalid.
* 404:
* description: No availabilites were found
*/
async function allAvailabilitys(_: NextApiRequest, res: NextApiResponse<AvailabilitysResponse>) {
const availabilites = await prisma.availability.findMany();
const data = availabilites.map((availability) => schemaAvailabilityPublic.parse(availability));
if (data) res.status(200).json({ data });
else
(error: Error) =>
res.status(404).json({
message: "No Availabilitys were found",
error,
});
}
export default withMiddleware("HTTP_GET")(allAvailabilitys);
+44 -24
View File
@@ -1,32 +1,52 @@
import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "@calcom/prisma";
import { Availability } from "@calcom/prisma/client";
import { schemaAvailability, withValidAvailability } from "@lib/validations/availability";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { AvailabilityResponse } from "@lib/types";
import {
schemaAvailabilityBodyParams,
schemaAvailabilityPublic,
withValidAvailability,
} from "@lib/validations/availability";
type ResponseData = {
data?: Availability;
message?: string;
error?: string;
};
/**
* @swagger
* /api/availabilites/new:
* post:
* summary: Creates a new availability
* requestBody:
* description: Optional description in *Markdown*
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Availability'
* tags:
* - availabilites
* responses:
* 201:
* description: OK, availability created
* model: Availability
* 400:
* description: Bad request. Availability body is invalid.
* 401:
* description: Authorization information is missing or invalid.
*/
async function createAvailability(req: NextApiRequest, res: NextApiResponse<AvailabilityResponse>) {
const safe = schemaAvailabilityBodyParams.safeParse(req.body);
if (!safe.success) throw new Error("Invalid request body", safe.error);
async function createAvailability(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
const { body, method } = req;
if (method === "POST") {
const safe = schemaAvailability.safeParse(body);
if (safe.success && safe.data) {
await prisma.availability
.create({ data: safe.data })
.then((availability) => res.status(201).json({ data: availability }))
.catch((error) =>
res.status(400).json({ message: "Could not create availability type", error: error })
);
}
} else {
// Reject any other HTTP method than POST
res.status(405).json({ error: "Only POST Method allowed" });
}
const availability = await prisma.availability.create({ data: safe.data });
const data = schemaAvailabilityPublic.parse(availability);
if (data) res.status(201).json({ data, message: "Availability created successfully" });
else
(error: Error) =>
res.status(400).json({
message: "Could not create new availability",
error,
});
}
export default withValidAvailability(createAvailability);
export default withMiddleware("HTTP_POST")(withValidAvailability(createAvailability));
+10 -1
View File
@@ -11,9 +11,18 @@ import {
/**
* @swagger
* /api/eventTypes/:id/delete:
* /api/eventTypes/{id}/delete:
* delete:
* summary: Remove an existing eventType
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the eventType to delete
* tags:
* - eventTypes
* responses:
* 201:
* description: OK, eventType removed successfuly
+10 -1
View File
@@ -16,9 +16,18 @@ import {
/**
* @swagger
* /api/eventTypes/:id/edit:
* /api/eventTypes/{id}/edit:
* patch:
* summary: Edits an existing eventType
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the eventType to delete
* tags:
* - eventTypes
* responses:
* 201:
* description: OK, eventType edited successfuly
+1 -1
View File
@@ -21,7 +21,7 @@ import {
* schema:
* type: integer
* required: true
* description: Numeric ID of the event type to get
* description: Numeric ID of the eventType to get
* responses:
* 200:
* description: OK
+9 -2
View File
@@ -12,9 +12,16 @@ import { schemaUserBodyParams, schemaUserPublic, withValidUser } from "@lib/vali
/**
* @swagger
* /api/users/:id/edit:
* /api/users/{id}/edit:
* patch:
* summary: Edits an existing user
* summary: Edit an existing user
* parameters:
* - in: path
* name: id
* schema:
* type: integer
* required: true
* description: Numeric ID of the user to edit
* tags:
* - users
* responses: