Merge pull request #63 from calcom/fix-openapi-spec
docs: improve open api spec, fixing all issues, removes json-schema / models
This commit is contained in:
42 files changed
+1386
-2603
No files matched your search
@@ -108,8 +108,6 @@ We have some shared validations which several resources require, like baseApiPar
|
||||
|
||||
- **[*]BodyParams** which merges both `[*]BaseBodyParams.merge([*]RequiredParams);`
|
||||
|
||||
- **withValid[*]** which is currently not being much used because is only useful in only post endpoints (we do post/get all in same file). This would validate the req.body of a POST call to API against our BaseBodyParams validation
|
||||
|
||||
### Next Validations
|
||||
|
||||
[Next-Validations Docs](https://next-validations.productsway.com/)
|
||||
@@ -127,9 +125,9 @@ We aim to provide a fully tested API for our peace of mind, this is accomplished
|
||||
| attendees | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| availabilities | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| booking-references | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| daily-event-references | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| event-references | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| destination-calendars | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| event-type-custom-inputs | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| custom-inputs | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| event-types | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| memberships | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| payments | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -8,6 +8,8 @@ import prisma from "@calcom/prisma";
|
||||
declare module "next" {
|
||||
export interface NextApiRequest extends IncomingMessage {
|
||||
userId: number;
|
||||
body: any;
|
||||
query: { [key: string]: string | string[] };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,21 +22,21 @@ export const dateNotInPast = function (date: Date) {
|
||||
};
|
||||
|
||||
// This verifies the apiKey and sets the user if it is valid.
|
||||
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
|
||||
if (!req.query.apiKey) return res.status(401).json({ message: "No apiKey provided" });
|
||||
export const verifyApiKey: NextMiddleware = async ({ query: { apiKey }, ...req }, res, next) => {
|
||||
if (!apiKey) return res.status(401).json({ message: "No apiKey provided" });
|
||||
// We remove the prefix from the user provided api_key. If no env set default to "cal_"
|
||||
const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", "");
|
||||
const strippedApiKey = `${apiKey}`.replace(process.env.API_KEY_PREFIX || " cal_", "");
|
||||
// Hash the key again before matching against the database records.
|
||||
const hashedKey = hashAPIKey(strippedApiKey);
|
||||
// Check if the hashed api key exists in database.
|
||||
const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
||||
const validApiKey = await prisma.apiKey.findUnique({ where: { hashedKey } });
|
||||
// If we cannot find any api key. Throw a 401 Unauthorized.
|
||||
if (!apiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
|
||||
if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) {
|
||||
if (!validApiKey) return res.status(401).json({ error: "Your apiKey is not valid" });
|
||||
if (validApiKey.expiresAt && dateNotInPast(validApiKey.expiresAt)) {
|
||||
return res.status(401).json({ error: "This apiKey is expired" });
|
||||
}
|
||||
if (!apiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" });
|
||||
if (!validApiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" });
|
||||
/* We save the user id in the request for later use */
|
||||
req.userId = apiKey.userId;
|
||||
req.userId = validApiKey.userId;
|
||||
await next();
|
||||
};
|
||||
+3
-7
@@ -1,5 +1,3 @@
|
||||
// https://www.npmjs.com/package/next-transpile-modules
|
||||
// This makes our @calcom/prisma package from the monorepo to be transpiled and usable by API
|
||||
const withTM = require("next-transpile-modules")([
|
||||
"@calcom/app-store",
|
||||
"@calcom/prisma",
|
||||
@@ -7,13 +5,11 @@ const withTM = require("next-transpile-modules")([
|
||||
"@calcom/ee",
|
||||
]);
|
||||
|
||||
// use something like withPlugins([withTM], {}) if more plugins added later.
|
||||
|
||||
module.exports = withTM({
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
// matching all API routes
|
||||
// @note: disabling CORS matching all API routes as this will be a our Public API
|
||||
source: "/api/:path*",
|
||||
headers: [
|
||||
{ key: "Access-Control-Allow-Credentials", value: "true" },
|
||||
@@ -30,12 +26,12 @@ module.exports = withTM({
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
// This redirects requests recieved at / the root to the /api/ folder.
|
||||
// @note: redirects requests from: "/:rest*" the root level to the "/api/:rest*" folder by default.
|
||||
{
|
||||
source: "/:rest*",
|
||||
destination: "/api/:rest*",
|
||||
},
|
||||
// This redirects requests to api/v*/ to /api/ passing version as a query parameter.
|
||||
// @note: redirects requests from api/v*/:rest to /api/:rest?version=* passing version as a query parameter.
|
||||
{
|
||||
source: "/api/v:version/:rest*",
|
||||
destination: "/api/:rest*?version=:version",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"dependencies": {
|
||||
"@calcom/prisma": "*",
|
||||
"@sentry/nextjs": "^6.19.3",
|
||||
"modify-response-middleware": "^1.1.0",
|
||||
"next": "^12.1.4",
|
||||
"next-api-middleware": "^1.0.1",
|
||||
"next-swagger-doc": "^0.2.1",
|
||||
|
||||
+110
-104
@@ -10,115 +10,56 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees/{id}:
|
||||
* get:
|
||||
* summary: Find an attendee by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the attendee to get
|
||||
* example: 3
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - attendees
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Attendee was not found
|
||||
* patch:
|
||||
* summary: Edit an existing attendee
|
||||
* consumes:
|
||||
* - application/json
|
||||
* requestBody:
|
||||
* description: Edit an existing attendee related to one of your bookings
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - bookingId
|
||||
* - name
|
||||
* - email
|
||||
* - timeZone
|
||||
* properties:
|
||||
* email:
|
||||
* type: string
|
||||
* example: email@example.com
|
||||
* name:
|
||||
* type: string
|
||||
* example: John Doe
|
||||
* timeZone:
|
||||
* type: string
|
||||
* example: Europe/London
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* example: 3
|
||||
* required: true
|
||||
* description: Numeric ID of the attendee to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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.
|
||||
* delete:
|
||||
* summary: Remove an existing attendee
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the attendee to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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 attendeeById(req: NextApiRequest, res: NextApiResponse<AttendeeResponse>) {
|
||||
const { method, query, body, userId } = req;
|
||||
export async function attendeeById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<AttendeeResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
if (!safeQuery.success) {
|
||||
res.status(400).json({ error: safeQuery.error });
|
||||
throw new Error("Invalid request query", safeQuery.error);
|
||||
}
|
||||
const userBookings = await prisma.booking.findMany({
|
||||
where: { userId },
|
||||
include: { attendees: true },
|
||||
});
|
||||
const attendees = userBookings.map((booking) => booking.attendees).flat();
|
||||
const attendeeIds = attendees.map((attendee) => attendee.id);
|
||||
// Here we make sure to only return attendee's of the user's own bookings.
|
||||
if (!attendeeIds.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
const userBookingsAttendeeIds = await prisma.booking
|
||||
// Find all user bookings, including attendees
|
||||
.findMany({
|
||||
where: { userId },
|
||||
include: { attendees: true },
|
||||
})
|
||||
.then(
|
||||
// Flatten and merge all the attendees in one array
|
||||
(bookings) =>
|
||||
bookings
|
||||
.map((bookings) => bookings.attendees)
|
||||
.flat()
|
||||
.map((attendee) => attendee.id)
|
||||
);
|
||||
// @note: Here we make sure to only return attendee's of the user's own bookings.
|
||||
if (!userBookingsAttendeeIds.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees/{id}:
|
||||
* get:
|
||||
* summary: Find an attendee
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the attendee to get
|
||||
* example: 3
|
||||
* tags:
|
||||
* - attendees
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Attendee was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.attendee
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -131,7 +72,51 @@ export async function attendeeById(req: NextApiRequest, res: NextApiResponse<Att
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing attendee
|
||||
* requestBody:
|
||||
* description: Edit an existing attendee related to one of your bookings
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - bookingId
|
||||
* - name
|
||||
* - email
|
||||
* - timeZone
|
||||
* properties:
|
||||
* email:
|
||||
* type: string
|
||||
* example: email@example.com
|
||||
* name:
|
||||
* type: string
|
||||
* example: John Doe
|
||||
* timeZone:
|
||||
* type: string
|
||||
* example: Europe/London
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* example: 3
|
||||
* required: true
|
||||
* description: Numeric ID of the attendee to edit
|
||||
* tags:
|
||||
* - attendees
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, attendee edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. Attendee body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
const safeBody = schemaAttendeeEditBodyParams.safeParse(body);
|
||||
if (!safeBody.success) {
|
||||
@@ -149,7 +134,28 @@ export async function attendeeById(req: NextApiRequest, res: NextApiResponse<Att
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees/{id}:
|
||||
* 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
|
||||
* 400:
|
||||
* description: Bad request. Attendee id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.attendee
|
||||
.delete({ where: { id: safeQuery.data.id } })
|
||||
|
||||
@@ -6,70 +6,10 @@ import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { AttendeeResponse, AttendeesResponse } from "@lib/types";
|
||||
import { schemaAttendeeCreateBodyParams, schemaAttendeeReadPublic } from "@lib/validations/attendee";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees:
|
||||
* get:
|
||||
* summary: Find all attendees
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - attendees
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No attendees were found
|
||||
* post:
|
||||
* summary: Creates a new attendee
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* consumes:
|
||||
* - application/json
|
||||
* requestBody:
|
||||
* description: Create a new attendee related to one of your bookings
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - bookingId
|
||||
* - name
|
||||
* - email
|
||||
* - timeZone
|
||||
* properties:
|
||||
* bookingId:
|
||||
* type: number
|
||||
* example: 1
|
||||
* email:
|
||||
* type: string
|
||||
* example: email@example.com
|
||||
* name:
|
||||
* type: string
|
||||
* example: John Doe
|
||||
* timeZone:
|
||||
* type: string
|
||||
* example: Europe/London
|
||||
* 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 createOrlistAllAttendees(
|
||||
req: NextApiRequest,
|
||||
{ method, userId, body }: NextApiRequest,
|
||||
res: NextApiResponse<AttendeesResponse | AttendeeResponse>
|
||||
) {
|
||||
const { method, userId } = req;
|
||||
// Here we make sure to only return attendee's of the user's own bookings.
|
||||
const userBookings = await prisma.booking.findMany({
|
||||
where: {
|
||||
userId,
|
||||
@@ -80,6 +20,21 @@ async function createOrlistAllAttendees(
|
||||
});
|
||||
const attendees = userBookings.map((booking) => booking.attendees).flat();
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees:
|
||||
* get:
|
||||
* summary: Find all attendees
|
||||
* tags:
|
||||
* - attendees
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No attendees were found
|
||||
*/
|
||||
if (attendees) res.status(200).json({ attendees });
|
||||
else
|
||||
(error: Error) =>
|
||||
@@ -88,13 +43,51 @@ async function createOrlistAllAttendees(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safePost = schemaAttendeeCreateBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /attendees:
|
||||
* post:
|
||||
* summary: Creates a new attendee
|
||||
* requestBody:
|
||||
* description: Create a new attendee related to one of your bookings
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - bookingId
|
||||
* - name
|
||||
* - email
|
||||
* - timeZone
|
||||
* properties:
|
||||
* bookingId:
|
||||
* type: number
|
||||
* example: 1
|
||||
* email:
|
||||
* type: string
|
||||
* example: email@example.com
|
||||
* name:
|
||||
* type: string
|
||||
* example: John Doe
|
||||
* timeZone:
|
||||
* type: string
|
||||
* example: Europe/London
|
||||
* tags:
|
||||
* - attendees
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, attendee created
|
||||
* 400:
|
||||
* description: Bad request. Attendee body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safePost = schemaAttendeeCreateBodyParams.safeParse(body);
|
||||
if (!safePost.success) {
|
||||
console.log(safePost.error);
|
||||
res.status(400).json({ error: safePost.error });
|
||||
throw new Error("Invalid request body", safePost.error);
|
||||
}
|
||||
const userId = req.userId;
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { bookings: true },
|
||||
@@ -102,7 +95,7 @@ async function createOrlistAllAttendees(
|
||||
if (!userWithBookings) {
|
||||
throw new Error("User not found");
|
||||
}
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: any) => booking.id).flat();
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat();
|
||||
// Here we make sure to only return attendee's of the user's own bookings.
|
||||
if (!userBookingIds.includes(safePost.data.bookingId)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
|
||||
@@ -13,97 +13,41 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities/{id}:
|
||||
* get:
|
||||
* summary: Find an availability by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the availability to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Availability was not found
|
||||
* patch:
|
||||
* summary: Edit an existing availability
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: availability
|
||||
* description: The availability to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/Availability'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the availability to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* 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.
|
||||
* delete:
|
||||
* summary: Remove an existing availability
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the availability to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* 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 availabilityById(req: NextApiRequest, res: NextApiResponse<AvailabilityResponse>) {
|
||||
const { method, query, body } = req;
|
||||
export async function availabilityById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<AvailabilityResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const data = await prisma.availability.findMany({ where: { userId } });
|
||||
const availabiltiesIds = data.map((availability) => availability.id);
|
||||
if (!availabiltiesIds.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities/{id}:
|
||||
* get:
|
||||
* summary: Find an availability
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the availability to get
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Availability was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.availability
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -113,7 +57,30 @@ export async function availabilityById(req: NextApiRequest, res: NextApiResponse
|
||||
res.status(404).json({ message: `Availability with id: ${safeQuery.data.id} not found`, error })
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities/{id}:
|
||||
* 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:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, availability edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. Availability body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
const safeBody = schemaAvailabilityEditBodyParams.safeParse(body);
|
||||
if (!safeBody.success) throw new Error("Invalid request body");
|
||||
@@ -132,14 +99,36 @@ export async function availabilityById(req: NextApiRequest, res: NextApiResponse
|
||||
.then((data) => schemaAvailabilityReadPublic.parse(data))
|
||||
.then((availability) => res.status(200).json({ availability }))
|
||||
.catch((error: Error) => {
|
||||
console.log(error);
|
||||
res.status(404).json({
|
||||
message: `Availability with id: ${safeQuery.data.id} not found`,
|
||||
error,
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities/{id}:
|
||||
* 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:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, availability removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. Availability id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.availability
|
||||
.delete({ where: { id: safeQuery.data.id } })
|
||||
|
||||
@@ -9,49 +9,28 @@ import {
|
||||
schemaAvailabilityReadPublic,
|
||||
} from "@lib/validations/availability";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities:
|
||||
* get:
|
||||
* summary: Find all availabilities
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No availabilities were found
|
||||
* post:
|
||||
* summary: Creates a new availability
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* 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 createOrlistAllAvailabilities(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<AvailabilitiesResponse | AvailabilityResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities:
|
||||
* get:
|
||||
* summary: Find all availabilities
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No availabilities were found
|
||||
*/
|
||||
const data = await prisma.availability.findMany({ where: { userId } });
|
||||
const availabilities = data.map((availability) => schemaAvailabilityReadPublic.parse(availability));
|
||||
if (availabilities) res.status(200).json({ availabilities });
|
||||
@@ -62,11 +41,27 @@ async function createOrlistAllAvailabilities(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaAvailabilityCreateBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /availabilities:
|
||||
* post:
|
||||
* summary: Creates a new availability
|
||||
* tags:
|
||||
* - availabilities
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/availability
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, availability created
|
||||
* 400:
|
||||
* description: Bad request. Availability body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaAvailabilityCreateBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const data = await prisma.availability.create({ data: { ...safe.data, userId } });
|
||||
console.log(data);
|
||||
const availability = schemaAvailabilityReadPublic.parse(data);
|
||||
|
||||
if (availability) res.status(201).json({ availability, message: "Availability created successfully" });
|
||||
|
||||
@@ -14,100 +14,46 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references/{id}:
|
||||
* get:
|
||||
* summary: Find a booking reference by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking reference to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: BookingReference was not found
|
||||
* patch:
|
||||
* summary: Edit an existing booking reference
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: bookingReference
|
||||
* description: The bookingReference to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/BookingReference'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking reference to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, bookingReference edited successfuly
|
||||
* model: BookingReference
|
||||
* 400:
|
||||
* description: Bad request. BookingReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing booking reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking reference to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, bookingReference removed successfuly
|
||||
* model: BookingReference
|
||||
* 400:
|
||||
* description: Bad request. BookingReference id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function bookingReferenceById(
|
||||
req: NextApiRequest,
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<BookingReferenceResponse>
|
||||
) {
|
||||
const { method, query, body } = req;
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { bookings: true },
|
||||
});
|
||||
if (!userWithBookings) throw new Error("User not found");
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: any) => booking.id).flat();
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat();
|
||||
const bookingReference = await prisma.bookingReference.findUnique({ where: { id: safeQuery.data.id } });
|
||||
if (!bookingReference) throw new Error("BookingReference not found");
|
||||
if (!bookingReference?.bookingId) throw new Error("BookingReference: bookingId not found");
|
||||
if (userBookingIds.includes(bookingReference.bookingId)) {
|
||||
switch (method) {
|
||||
case "GET":
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references/{id}:
|
||||
* get:
|
||||
* summary: Find a booking reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking reference to get
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: BookingReference was not found
|
||||
*/
|
||||
|
||||
await prisma.bookingReference
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
.then((data) => schemaBookingReferenceReadPublic.parse(data))
|
||||
@@ -118,11 +64,33 @@ export async function bookingReferenceById(
|
||||
error,
|
||||
})
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case "PATCH":
|
||||
const safeBody = schemaBookingEditBodyParams.safeParse(body);
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing booking reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking reference to edit
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, bookingReference edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. BookingReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
|
||||
const safeBody = schemaBookingEditBodyParams.safeParse(body);
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
}
|
||||
@@ -137,7 +105,28 @@ export async function bookingReferenceById(
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing booking reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking reference to delete
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, bookingReference removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. BookingReference id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.bookingReference
|
||||
.delete({
|
||||
|
||||
@@ -9,50 +9,32 @@ import {
|
||||
schemaBookingReferenceReadPublic,
|
||||
} from "@lib/validations/booking-reference";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references:
|
||||
* get:
|
||||
* summary: Find all booking references
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No booking references were found
|
||||
* post:
|
||||
* summary: Creates a new booking reference
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking reference created
|
||||
* model: BookingReference
|
||||
* 400:
|
||||
* description: Bad request. BookingReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllBookingReferences(
|
||||
req: NextApiRequest,
|
||||
{ method, userId, body }: NextApiRequest,
|
||||
res: NextApiResponse<BookingReferencesResponse | BookingReferenceResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { bookings: true },
|
||||
});
|
||||
if (!userWithBookings) throw new Error("User not found");
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: any) => booking.id).flat();
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat();
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references:
|
||||
* get:
|
||||
* summary: Find all booking references
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No booking references were found
|
||||
*/
|
||||
const data = await prisma.bookingReference.findMany({ where: { id: { in: userBookingIds } } });
|
||||
const booking_references = data.map((bookingReference) =>
|
||||
schemaBookingReferenceReadPublic.parse(bookingReference)
|
||||
@@ -65,13 +47,26 @@ async function createOrlistAllBookingReferences(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaBookingCreateBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /booking-references:
|
||||
* post:
|
||||
* summary: Creates a new booking reference
|
||||
* tags:
|
||||
* - booking-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking reference created
|
||||
* 400:
|
||||
* description: Bad request. BookingReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaBookingCreateBodyParams.safeParse(body);
|
||||
if (!safe.success) {
|
||||
throw new Error("Invalid request body");
|
||||
}
|
||||
|
||||
// const booking_reference = schemaBookingReferencePublic.parse(data);
|
||||
const userId = req.userId;
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { bookings: true },
|
||||
@@ -79,7 +74,8 @@ async function createOrlistAllBookingReferences(
|
||||
if (!userWithBookings) {
|
||||
throw new Error("User not found");
|
||||
}
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: any) => booking.id).flat();
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat();
|
||||
if (!safe.data.bookingId) throw new Error("BookingReference: bookingId not found");
|
||||
if (!userBookingIds.includes(safe.data.bookingId)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
const booking_reference = await prisma.bookingReference.create({
|
||||
|
||||
+71
-82
@@ -10,95 +10,43 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings/{id}:
|
||||
* get:
|
||||
* summary: Find a booking by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Booking was not found
|
||||
* patch:
|
||||
* summary: Edit an existing booking
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: booking
|
||||
* description: The booking to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/Booking'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking edited successfuly
|
||||
* model: Booking
|
||||
* 400:
|
||||
* description: Bad request. Booking body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing booking
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking removed successfuly
|
||||
* model: Booking
|
||||
* 400:
|
||||
* description: Bad request. Booking id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function bookingById(req: NextApiRequest, res: NextApiResponse<BookingResponse>) {
|
||||
const { method, query, body } = req;
|
||||
export async function bookingById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<BookingResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { bookings: true },
|
||||
});
|
||||
if (!userWithBookings) throw new Error("User not found");
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: any) => booking.id).flat();
|
||||
const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat();
|
||||
if (!userBookingIds.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings/{id}:
|
||||
* get:
|
||||
* summary: Find a booking
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking to get
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Booking was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.booking
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -111,10 +59,30 @@ export async function bookingById(req: NextApiRequest, res: NextApiResponse<Book
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing booking
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking to edit
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. Booking body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
const safeBody = schemaBookingEditBodyParams.safeParse(body);
|
||||
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
}
|
||||
@@ -132,7 +100,28 @@ export async function bookingById(req: NextApiRequest, res: NextApiResponse<Book
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing booking
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the booking to delete
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. Booking id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.booking
|
||||
.delete({ where: { id: safeQuery.data.id } })
|
||||
|
||||
+32
-36
@@ -6,45 +6,26 @@ import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { BookingResponse, BookingsResponse } from "@lib/types";
|
||||
import { schemaBookingCreateBodyParams, schemaBookingReadPublic } from "@lib/validations/booking";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings:
|
||||
* get:
|
||||
* summary: Find all bookings
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No bookings were found
|
||||
* post:
|
||||
* summary: Creates a new booking
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking created
|
||||
* model: Booking
|
||||
* 400:
|
||||
* description: Bad request. Booking body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllBookings(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<BookingsResponse | BookingResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings:
|
||||
* get:
|
||||
* summary: Find all bookings
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No bookings were found
|
||||
*/
|
||||
const data = await prisma.booking.findMany({ where: { userId } });
|
||||
const bookings = data.map((booking) => schemaBookingReadPublic.parse(booking));
|
||||
if (bookings) res.status(200).json({ bookings });
|
||||
@@ -55,7 +36,22 @@ async function createOrlistAllBookings(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaBookingCreateBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /bookings:
|
||||
* post:
|
||||
* summary: Creates a new booking
|
||||
* tags:
|
||||
* - bookings
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, booking created
|
||||
* 400:
|
||||
* description: Bad request. Booking body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaBookingCreateBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const data = await prisma.booking.create({ data: { ...safe.data, userId } });
|
||||
|
||||
@@ -15,9 +15,9 @@ import {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-type-custom-inputs/{id}:
|
||||
* /custom-inputs/{id}:
|
||||
* get:
|
||||
* summary: Find a eventTypeCustomInput by ID
|
||||
* summary: Find a eventTypeCustomInput
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
@@ -25,45 +25,31 @@ import {
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventTypeCustomInput to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-type-custom-inputs
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* deCustomInputscription: EventType was not found
|
||||
* description: EventType was not found
|
||||
* patch:
|
||||
* summary: Edit an existing eventTypeCustomInput
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: eventTypeCustomInput
|
||||
* description: The eventTypeCustomInput to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/EventTypeCustomInput'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventTypeCustomInput to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-type-custom-inputs
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput edited successfuly
|
||||
* model: EventTypeCustomInput
|
||||
* 400:
|
||||
* desCustomInputcription: Bad request. EventType body is invalid.
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
@@ -75,25 +61,23 @@ import {
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventTypeCustomInput to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-type-custom-inputs
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput removed successfuly
|
||||
* model: EventTypeCustomInput
|
||||
* 400:
|
||||
* desCustomInputcription: Bad request. EventType id is invalid.
|
||||
* description: Bad request. EventType id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function eventTypeById(req: NextApiRequest, res: NextApiResponse<EventTypeCustomInputResponse>) {
|
||||
const { method, query, body } = req;
|
||||
async function eventTypeById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<EventTypeCustomInputResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaEventTypeCustomInputBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const data = await prisma.eventType.findMany({ where: { userId } });
|
||||
const userEventTypes = data.map((eventType) => eventType.id);
|
||||
const userEventTypeCustomInputs = await prisma.eventTypeCustomInput.findMany({
|
||||
@@ -9,47 +9,28 @@ import {
|
||||
schemaEventTypeCustomInputPublic,
|
||||
} from "@lib/validations/event-type-custom-input";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-type-custom-inputs:
|
||||
* get:
|
||||
* summary: Find all eventTypeCustomInputs
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-type-custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No eventTypeCustomInputs were found
|
||||
* post:
|
||||
* summary: Creates a new eventTypeCustomInput
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-type-custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput created
|
||||
* model: EventTypeCustomInput
|
||||
* 400:
|
||||
* description: Bad request. EventTypeCustomInput body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllEventTypeCustomInputs(
|
||||
req: NextApiRequest,
|
||||
{ userId, method, body }: NextApiRequest,
|
||||
res: NextApiResponse<EventTypeCustomInputsResponse | EventTypeCustomInputResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
const data = await prisma.eventType.findMany({ where: { userId } });
|
||||
const userEventTypes = data.map((eventType) => eventType.id);
|
||||
|
||||
const userEventTypes: number[] = data.map((eventType) => eventType.id);
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs:
|
||||
* get:
|
||||
* summary: Find all eventTypeCustomInputs
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No eventTypeCustomInputs were found
|
||||
*/
|
||||
const data = await prisma.eventTypeCustomInput.findMany({ where: { eventType: userEventTypes } });
|
||||
const event_type_custom_inputs = data.map((eventTypeCustomInput) =>
|
||||
schemaEventTypeCustomInputPublic.parse(eventTypeCustomInput)
|
||||
@@ -62,7 +43,22 @@ async function createOrlistAllEventTypeCustomInputs(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaEventTypeCustomInputBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /custom-inputs:
|
||||
* post:
|
||||
* summary: Creates a new eventTypeCustomInput
|
||||
* tags:
|
||||
* - custom-inputs
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventTypeCustomInput created
|
||||
* 400:
|
||||
* description: Bad request. EventTypeCustomInput body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaEventTypeCustomInputBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
// Since we're supporting a create or connect relation on eventType, we need to treat them differently
|
||||
// When using connect on event type, check if userId is the owner of the event
|
||||
@@ -13,90 +13,13 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars/{id}:
|
||||
* get:
|
||||
* summary: Find a destination calendar by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: DestinationCalendar was not found
|
||||
* patch:
|
||||
* summary: Edit an existing destination calendar
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: destinationCalendar
|
||||
* description: The destinationCalendar to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/DestinationCalendar'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destinationCalendar edited successfuly
|
||||
* model: DestinationCalendar
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing destination calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destinationCalendar removed successfuly
|
||||
* model: DestinationCalendar
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function destionationCalendarById(
|
||||
req: NextApiRequest,
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<DestinationCalendarResponse>
|
||||
) {
|
||||
const { method, query, body } = req;
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaDestinationCalendarEditBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const data = await prisma.destinationCalendar.findMany({ where: { userId } });
|
||||
const userDestinationCalendars = data.map((destinationCalendar) => destinationCalendar.id);
|
||||
// FIXME: Should we also check ownership of bokingId and eventTypeId to avoid users cross-pollinating other users calendars.
|
||||
@@ -104,6 +27,64 @@ export async function destionationCalendarById(
|
||||
if (userDestinationCalendars.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars/{id}:
|
||||
* get:
|
||||
* summary: Find a destination calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to get
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: DestinationCalendar was not found
|
||||
* patch:
|
||||
* summary: Edit an existing destination calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to edit
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destinationCalendar edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing destination calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to delete
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destinationCalendar removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.destinationCalendar
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -116,7 +97,28 @@ export async function destionationCalendarById(
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing destination calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to edit
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destinationCalendar edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
@@ -132,7 +134,28 @@ export async function destionationCalendarById(
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing destination calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the destination calendar to delete
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destinationCalendar removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.destinationCalendar
|
||||
.delete({
|
||||
|
||||
@@ -9,45 +9,26 @@ import {
|
||||
schemaDestinationCalendarReadPublic,
|
||||
} from "@lib/validations/destination-calendar";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars:
|
||||
* get:
|
||||
* summary: Find all destination calendars
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No destination calendars were found
|
||||
* post:
|
||||
* summary: Creates a new destination calendar
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destination calendar created
|
||||
* model: DestinationCalendar
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllDestinationCalendars(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<DestinationCalendarsResponse | DestinationCalendarResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars:
|
||||
* get:
|
||||
* summary: Find all destination calendars
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No destination calendars were found
|
||||
*/
|
||||
const data = await prisma.destinationCalendar.findMany({ where: { userId } });
|
||||
const destination_calendars = data.map((destinationCalendar) =>
|
||||
schemaDestinationCalendarReadPublic.parse(destinationCalendar)
|
||||
@@ -60,7 +41,22 @@ async function createOrlistAllDestinationCalendars(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaDestinationCalendarCreateBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /destination-calendars:
|
||||
* post:
|
||||
* summary: Creates a new destination calendar
|
||||
* tags:
|
||||
* - destination-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, destination calendar created
|
||||
* 400:
|
||||
* description: Bad request. DestinationCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaDestinationCalendarCreateBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const data = await prisma.destinationCalendar.create({ data: { ...safe.data, userId } });
|
||||
|
||||
+14
-20
@@ -1,6 +1,8 @@
|
||||
import jsonSchema from "@/json-schema/json-schema.json";
|
||||
import pjson from "@/package.json";
|
||||
import modifyRes from "modify-response-middleware";
|
||||
import { use } from "next-api-middleware";
|
||||
import { withSwagger } from "next-swagger-doc";
|
||||
import { NextApiRequest, NextApiResponse } from "next/types";
|
||||
|
||||
const swaggerHandler = withSwagger({
|
||||
definition: {
|
||||
@@ -20,26 +22,18 @@ const swaggerHandler = withSwagger({
|
||||
},
|
||||
components: {
|
||||
securitySchemes: { ApiKeyAuth: { type: "apiKey", in: "query", name: "apiKey" } },
|
||||
security: { ApiKeyAuth: [] },
|
||||
schemas: { ...jsonSchema.definitions },
|
||||
},
|
||||
security: [{ ApiKeyAuth: [] }],
|
||||
},
|
||||
apiFolder: "pages/api",
|
||||
tags: [
|
||||
"users",
|
||||
"teams",
|
||||
"memeberships",
|
||||
"selected-calendars",
|
||||
"schedules",
|
||||
"payments",
|
||||
"event-types",
|
||||
"event-type-custom-inputs",
|
||||
"destination-calendars",
|
||||
"daily-event-references",
|
||||
"booking-references",
|
||||
"availabilities",
|
||||
"attendees",
|
||||
],
|
||||
sort: true,
|
||||
});
|
||||
export default swaggerHandler();
|
||||
|
||||
export default use(
|
||||
modifyRes((content: string, _req: NextApiRequest, _res: NextApiResponse) => {
|
||||
if (content) {
|
||||
const parsed = JSON.parse(content);
|
||||
delete parsed.channels;
|
||||
return Buffer.from(JSON.stringify(parsed));
|
||||
}
|
||||
})
|
||||
)(swaggerHandler());
|
||||
@@ -13,92 +13,15 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /daily-event-references/{id}:
|
||||
* get:
|
||||
* summary: Find a daily event reference by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the daily event reference to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - daily-event-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: DailyEventReference was not found
|
||||
* patch:
|
||||
* summary: Edit an existing daily event reference
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: dailyEventReference
|
||||
* description: The dailyEventReference to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/DailyEventReference'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the daily event reference to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - daily-event-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, dailyEventReference edited successfuly
|
||||
* model: DailyEventReference
|
||||
* 400:
|
||||
* description: Bad request. DailyEventReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing daily event reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the daily event reference to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - daily-event-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, dailyEventReference removed successfuly
|
||||
* model: DailyEventReference
|
||||
* 400:
|
||||
* description: Bad request. DailyEventReference id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function dailyEventReferenceById(
|
||||
req: NextApiRequest,
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<DailyEventReferenceResponse>
|
||||
) {
|
||||
const { method, query, body } = req;
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaDailyEventReferenceEditBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const userBookings = await prisma.booking.findMany({ where: { userId } });
|
||||
const userBookingIds = userBookings.map((booking) => booking.id);
|
||||
const userBookingIds: number[] = userBookings.map((booking) => booking.id);
|
||||
const userBookingDailyEventReferences = await prisma.dailyEventReference.findMany({
|
||||
where: { bookingId: { in: userBookingIds } },
|
||||
});
|
||||
@@ -109,6 +32,28 @@ export async function dailyEventReferenceById(
|
||||
res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /event-references/{id}:
|
||||
* get:
|
||||
* summary: Find a event reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the event reference to get
|
||||
* tags:
|
||||
* - event-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: EventReference was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.dailyEventReference
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -122,6 +67,28 @@ export async function dailyEventReferenceById(
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-references/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing event reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the event reference to edit
|
||||
* tags:
|
||||
* - event-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, EventReference edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. EventReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
@@ -138,6 +105,28 @@ export async function dailyEventReferenceById(
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-references/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing event reference
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the event reference to delete
|
||||
* tags:
|
||||
* - event-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, EventReference removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. EventReference id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.dailyEventReference
|
||||
.delete({
|
||||
@@ -9,47 +9,29 @@ import {
|
||||
schemaDailyEventReferenceReadPublic,
|
||||
} from "@lib/validations/daily-event-reference";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /daily-event-references:
|
||||
* get:
|
||||
* summary: Find all daily event reference
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - daily-event-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No daily event references were found
|
||||
* post:
|
||||
* summary: Creates a new daily event reference
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - daily-event-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, daily event reference created
|
||||
* model: DailyEventReference
|
||||
* 400:
|
||||
* description: Bad request. DailyEventReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllDailyEventReferences(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<DailyEventReferencesResponse | DailyEventReferenceResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
const userBookings = await prisma.booking.findMany({ where: { userId } });
|
||||
const userBookingIds = userBookings.map((booking) => booking.id);
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /event-references:
|
||||
* get:
|
||||
* summary: Find all daily event reference
|
||||
* tags:
|
||||
* - event-references
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No daily event references were found
|
||||
*/
|
||||
const data = await prisma.dailyEventReference.findMany({
|
||||
where: { bookingId: { in: userBookingIds } },
|
||||
});
|
||||
@@ -64,7 +46,22 @@ async function createOrlistAllDailyEventReferences(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaDailyEventReferenceCreateBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /event-references:
|
||||
* post:
|
||||
* summary: Creates a new daily event reference
|
||||
* tags:
|
||||
* - event-references
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, daily event reference created
|
||||
* 400:
|
||||
* description: Bad request. DailyEventReference body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaDailyEventReferenceCreateBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const data = await prisma.dailyEventReference.create({ data: safe.data });
|
||||
@@ -10,98 +10,43 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types/{id}:
|
||||
* get:
|
||||
* summary: Find a eventType by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventType to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: EventType was not found
|
||||
* patch:
|
||||
* summary: Edit an existing eventType
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: eventType
|
||||
* description: The eventType to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/EventType'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventType to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventType edited successfuly
|
||||
* model: EventType
|
||||
* 400:
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing eventType
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventType to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventType removed successfuly
|
||||
* model: EventType
|
||||
* 400:
|
||||
* description: Bad request. EventType id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function eventTypeById(req: NextApiRequest, res: NextApiResponse<EventTypeResponse>) {
|
||||
const { method, query, body } = req;
|
||||
export async function eventTypeById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<EventTypeResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaEventTypeBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const data = await prisma.eventType.findMany({ where: { userId } });
|
||||
const userEventTypes = data.map((eventType) => eventType.id);
|
||||
if (!userEventTypes.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types/{id}:
|
||||
* get:
|
||||
* summary: Find a eventType
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventType to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: EventType was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.eventType
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -114,8 +59,34 @@ export async function eventTypeById(req: NextApiRequest, res: NextApiResponse<Ev
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing eventType
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventType to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventType edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
const safeBody = schemaEventTypeBodyParams.safeParse(body);
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
}
|
||||
@@ -130,7 +101,32 @@ export async function eventTypeById(req: NextApiRequest, res: NextApiResponse<Ev
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing eventType
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the eventType to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, eventType removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. EventType id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.eventType
|
||||
.delete({ where: { id: safeQuery.data.id } })
|
||||
|
||||
@@ -6,49 +6,28 @@ import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { EventTypeResponse, EventTypesResponse } from "@lib/types";
|
||||
import { schemaEventTypeBodyParams, schemaEventTypePublic } from "@lib/validations/event-type";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types:
|
||||
* get:
|
||||
* summary: Find all event types
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No event types were found
|
||||
* post:
|
||||
* summary: Creates a new event type
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, event type created
|
||||
* model: EventType
|
||||
* 400:
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllEventTypes(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<EventTypesResponse | EventTypeResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types:
|
||||
* get:
|
||||
* summary: Find all event types
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No event types were found
|
||||
*/
|
||||
const data = await prisma.eventType.findMany({ where: { userId } });
|
||||
const event_types = data.map((eventType) => schemaEventTypePublic.parse(eventType));
|
||||
if (event_types) res.status(200).json({ event_types });
|
||||
@@ -59,7 +38,24 @@ async function createOrlistAllEventTypes(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaEventTypeBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /event-types:
|
||||
* post:
|
||||
* summary: Creates a new event type
|
||||
* tags:
|
||||
* - event-types
|
||||
* externalDocs:
|
||||
* url: https://docs.cal.com/event-types
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, event type created
|
||||
* 400:
|
||||
* description: Bad request. EventType body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaEventTypeBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const data = await prisma.eventType.create({ data: { ...safe.data, userId } });
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
*/
|
||||
export default async function CalcomApi(_: NextApiRequest, res: NextApiResponse) {
|
||||
res.status(201).json({ message: "Welcome to Cal.com API - docs are at https://docs.cal.com/api" });
|
||||
}
|
||||
@@ -7,110 +7,45 @@ import type { MembershipResponse } from "@lib/types";
|
||||
import { schemaMembershipBodyParams, schemaMembershipPublic } from "@lib/validations/membership";
|
||||
import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships/{userId}_{teamId}:
|
||||
* get:
|
||||
* summary: Find a 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
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - memberships
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Membership was not found
|
||||
* patch:
|
||||
* summary: Edit an existing membership
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: membership
|
||||
* description: The membership to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/Membership'
|
||||
* required: true
|
||||
* - 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
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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.
|
||||
* delete:
|
||||
* summary: Remove an existing membership
|
||||
* 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
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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 membershipById(req: NextApiRequest, res: NextApiResponse<MembershipResponse>) {
|
||||
const { method, query, body } = req;
|
||||
export async function membershipById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<MembershipResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdAsString.safeParse(query);
|
||||
const safeBody = schemaMembershipBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
// This is how we set the userId and teamId in the query for managing compoundId.
|
||||
const [paramUserId, teamId] = safeQuery.data.id.split("_");
|
||||
const userId = req.userId;
|
||||
if (parseInt(paramUserId) !== userId) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships/{userId}_{teamId}:
|
||||
* get:
|
||||
* summary: Find a 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
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.membership
|
||||
.findUnique({
|
||||
@@ -131,7 +66,36 @@ export async function membershipById(req: NextApiRequest, res: NextApiResponse<M
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships/{userId}_{teamId}:
|
||||
* patch:
|
||||
* summary: Edit an existing membership
|
||||
* 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:
|
||||
* 201:
|
||||
* description: OK, membership edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. Membership body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
const safeBody = schemaMembershipBodyParams.safeParse(body);
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
}
|
||||
@@ -155,6 +119,34 @@ export async function membershipById(req: NextApiRequest, res: NextApiResponse<M
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships/{userId}_{teamId}:
|
||||
* delete:
|
||||
* summary: Remove an existing membership
|
||||
* 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:
|
||||
* 201:
|
||||
* description: OK, membership removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. Membership id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.membership
|
||||
.delete({
|
||||
|
||||
@@ -6,44 +6,26 @@ import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { MembershipResponse, MembershipsResponse } from "@lib/types";
|
||||
import { schemaMembershipBodyParams, schemaMembershipPublic } from "@lib/validations/membership";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships:
|
||||
* get:
|
||||
* summary: Find all memberships
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - memberships
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No memberships were found
|
||||
* post:
|
||||
* summary: Creates a new membership
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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 createOrlistAllMemberships(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<MembershipsResponse | MembershipResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships:
|
||||
* get:
|
||||
* summary: Find all memberships
|
||||
* tags:
|
||||
* - memberships
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No memberships were found
|
||||
*/
|
||||
const data = await prisma.membership.findMany({ where: { userId } });
|
||||
const memberships = data.map((membership) => schemaMembershipPublic.parse(membership));
|
||||
if (memberships) res.status(200).json({ memberships });
|
||||
@@ -54,7 +36,22 @@ async function createOrlistAllMemberships(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaMembershipBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /memberships:
|
||||
* post:
|
||||
* summary: Creates a new membership
|
||||
* tags:
|
||||
* - memberships
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, membership created
|
||||
* 400:
|
||||
* description: Bad request. Membership body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaMembershipBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const data = await prisma.membership.create({ data: { ...safe.data, userId } });
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
* @swagger
|
||||
* /payments/{id}:
|
||||
* get:
|
||||
* summary: Find one of your own payments by ID
|
||||
* summary: Find a payment
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
@@ -22,8 +22,6 @@ import {
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the payment to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
@@ -34,11 +32,11 @@ import {
|
||||
* 404:
|
||||
* description: Payment was not found
|
||||
*/
|
||||
export async function paymentById(req: NextApiRequest, res: NextApiResponse<PaymentResponse>) {
|
||||
const { method, query } = req;
|
||||
export async function paymentById(
|
||||
{ method, query, userId }: NextApiRequest,
|
||||
res: NextApiResponse<PaymentResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const userId = req.userId;
|
||||
|
||||
if (safeQuery.success && method === "GET") {
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
|
||||
@@ -11,8 +11,6 @@ import { schemaPaymentPublic } from "@lib/validations/payment";
|
||||
* /payments:
|
||||
* get:
|
||||
* summary: Find all payments
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
@@ -23,9 +21,7 @@ import { schemaPaymentPublic } from "@lib/validations/payment";
|
||||
* 404:
|
||||
* description: No payments were found
|
||||
*/
|
||||
async function allPayments(req: NextApiRequest, res: NextApiResponse<PaymentsResponse>) {
|
||||
const userId = req.userId;
|
||||
|
||||
async function allPayments({ userId }: NextApiRequest, res: NextApiResponse<PaymentsResponse>) {
|
||||
const userWithBookings = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { bookings: true },
|
||||
|
||||
+70
-78
@@ -10,92 +10,40 @@ import {
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules/{id}:
|
||||
* get:
|
||||
* summary: Find a schedule by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the schedule to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Schedule was not found
|
||||
* patch:
|
||||
* summary: Edit an existing schedule
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: schedule
|
||||
* description: The schedule to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/Schedule'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the schedule to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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.
|
||||
* delete:
|
||||
* summary: Remove an existing schedule
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the schedule to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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 scheduleById(req: NextApiRequest, res: NextApiResponse<ScheduleResponse>) {
|
||||
const { method, query, body } = req;
|
||||
export async function scheduleById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<ScheduleResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaScheduleBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const userSchedules = await prisma.schedule.findMany({ where: { userId } });
|
||||
const userScheduleIds = userSchedules.map((schedule) => schedule.id);
|
||||
if (!userScheduleIds.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules/{id}:
|
||||
* get:
|
||||
* summary: Find a schedule
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the schedule to get
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Schedule was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.schedule
|
||||
.findUnique({ where: { id: safeQuery.data.id } })
|
||||
@@ -109,6 +57,28 @@ export async function scheduleById(req: NextApiRequest, res: NextApiResponse<Sch
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules/{id}:
|
||||
* patch:
|
||||
* summary: Edit an existing schedule
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the schedule to edit
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, schedule edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. Schedule body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
@@ -125,6 +95,28 @@ export async function scheduleById(req: NextApiRequest, res: NextApiResponse<Sch
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules/{id}:
|
||||
* delete:
|
||||
* summary: Remove an existing schedule
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the schedule to delete
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, schedule removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. Schedule id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
// Look for user to check if schedule is user's default
|
||||
const user = await prisma.user.findUnique({ where: { id: userId } });
|
||||
|
||||
@@ -6,45 +6,26 @@ import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { ScheduleResponse, SchedulesResponse } from "@lib/types";
|
||||
import { schemaScheduleBodyParams, schemaSchedulePublic } from "@lib/validations/schedule";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules:
|
||||
* get:
|
||||
* summary: Find all schedules
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No schedules were found
|
||||
* post:
|
||||
* summary: Creates a new schedule
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* 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 createOrlistAllSchedules(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<SchedulesResponse | ScheduleResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules:
|
||||
* get:
|
||||
* summary: Find all schedules
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No schedules were found
|
||||
*/
|
||||
const data = await prisma.schedule.findMany({ where: { userId } });
|
||||
const schedules = data.map((schedule) => schemaSchedulePublic.parse(schedule));
|
||||
if (schedules) res.status(200).json({ schedules });
|
||||
@@ -55,7 +36,22 @@ async function createOrlistAllSchedules(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaScheduleBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /schedules:
|
||||
* post:
|
||||
* summary: Creates a new schedule
|
||||
* tags:
|
||||
* - schedules
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, schedule created
|
||||
* 400:
|
||||
* description: Bad request. Schedule body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaScheduleBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
const data = await prisma.schedule.create({ data: { ...safe.data, userId } });
|
||||
const schedule = schemaSchedulePublic.parse(data);
|
||||
|
||||
@@ -10,131 +10,52 @@ import {
|
||||
} from "@lib/validations/selected-calendar";
|
||||
import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars/{userId}_{integration}_{externalId}:
|
||||
* get:
|
||||
* summary: Find a selected-calendar by userID and teamID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: userId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: userId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: externalId
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: externalId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: integration
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: integration of the selected calendar to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: SelectedCalendar was not found
|
||||
* patch:
|
||||
* summary: Edit an existing selected calendar
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: selected-calendar
|
||||
* description: The selected-calendar to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/SelectedCalendar'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: userId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: userId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: externalId
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: externalId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: integration
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: integration of the selected calendar to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, selected-calendar edited successfuly
|
||||
* model: SelectedCalendar
|
||||
* 400:
|
||||
* description: Bad request. SelectedCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing selected-calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: userId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: userId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: externalId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: externalId of the selected-calendar to get
|
||||
* - in: path
|
||||
* name: integration
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: integration of the selected calendar to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, selected-calendar removed successfuly
|
||||
* model: SelectedCalendar
|
||||
* 400:
|
||||
* description: Bad request. SelectedCalendar id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function selectedCalendarById(
|
||||
req: NextApiRequest,
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<SelectedCalendarResponse>
|
||||
) {
|
||||
const { method, query, body } = req;
|
||||
const safeQuery = schemaQueryIdAsString.safeParse(query);
|
||||
const safeBody = schemaSelectedCalendarBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
// This is how we set the userId and externalId in the query for managing compoundId.
|
||||
const [paramUserId, integration, externalId] = safeQuery.data.id.split("_");
|
||||
const userId = req.userId;
|
||||
if (userId !== parseInt(paramUserId)) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
switch (method) {
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars/{userId}_{integration}_{externalId}:
|
||||
* get:
|
||||
* summary: Find a selected calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: userId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: userId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: externalId
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: externalId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: integration
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: integration of the selected calendar to get
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: SelectedCalendar was not found
|
||||
*/
|
||||
case "GET":
|
||||
await prisma.selectedCalendar
|
||||
.findUnique({
|
||||
@@ -156,6 +77,40 @@ export async function selectedCalendarById(
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars/{userId}_{integration}_{externalId}:
|
||||
* patch:
|
||||
* summary: Edit a selected calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: userId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: userId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: externalId
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: externalId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: integration
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: integration of the selected calendar to get
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, selected-calendar edited successfuly
|
||||
* 400:
|
||||
* description: Bad request. SelectedCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "PATCH":
|
||||
if (!safeBody.success) {
|
||||
throw new Error("Invalid request body");
|
||||
@@ -180,7 +135,40 @@ export async function selectedCalendarById(
|
||||
})
|
||||
);
|
||||
break;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars/{userId}_{integration}_{externalId}:
|
||||
* delete:
|
||||
* summary: Remove a selected calendar
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: userId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: userId of the selected calendar to get
|
||||
* - in: path
|
||||
* name: externalId
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: externalId of the selected-calendar to get
|
||||
* - in: path
|
||||
* name: integration
|
||||
* schema:
|
||||
* type: string
|
||||
* required: true
|
||||
* description: integration of the selected calendar to get
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, selected-calendar removed successfuly
|
||||
* 400:
|
||||
* description: Bad request. SelectedCalendar id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
case "DELETE":
|
||||
await prisma.selectedCalendar
|
||||
.delete({
|
||||
|
||||
@@ -9,45 +9,26 @@ import {
|
||||
schemaSelectedCalendarPublic,
|
||||
} from "@lib/validations/selected-calendar";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars:
|
||||
* get:
|
||||
* summary: Find all selected calendars
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No selected calendars were found
|
||||
* post:
|
||||
* summary: Creates a new selected calendar
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, selected calendar created
|
||||
* model: SelectedCalendar
|
||||
* 400:
|
||||
* description: Bad request. SelectedCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllSelectedCalendars(
|
||||
req: NextApiRequest,
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<SelectedCalendarsResponse | SelectedCalendarResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars:
|
||||
* get:
|
||||
* summary: Find all selected calendars
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No selected calendars were found
|
||||
*/
|
||||
const data = await prisma.selectedCalendar.findMany({ where: { userId } });
|
||||
const selected_calendars = data.map((selected_calendar) =>
|
||||
schemaSelectedCalendarPublic.parse(selected_calendar)
|
||||
@@ -60,7 +41,33 @@ async function createOrlistAllSelectedCalendars(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaSelectedCalendarBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /selected-calendars:
|
||||
* get:
|
||||
* summary: Find all selected calendars
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No selected calendars were found
|
||||
* post:
|
||||
* summary: Creates a new selected calendar
|
||||
* tags:
|
||||
* - selected-calendars
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, selected calendar created
|
||||
* 400:
|
||||
* description: Bad request. SelectedCalendar body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaSelectedCalendarBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
// Create new selectedCalendar connecting it to current userId
|
||||
const data = await prisma.selectedCalendar.create({
|
||||
|
||||
+5
-21
@@ -14,7 +14,7 @@ import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team";
|
||||
* @swagger
|
||||
* /teams/{id}:
|
||||
* get:
|
||||
* summary: Find a team by ID
|
||||
* summary: Find a team
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
@@ -22,8 +22,6 @@ import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team";
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the team to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
@@ -35,30 +33,18 @@ import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team";
|
||||
* description: Team was not found
|
||||
* patch:
|
||||
* summary: Edit an existing team
|
||||
* consumes:
|
||||
* - application/json
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: team
|
||||
* description: The team to edit
|
||||
* schema:
|
||||
* type: object
|
||||
* $ref: '#/components/schemas/Team'
|
||||
* required: true
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the team to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, team edited successfuly
|
||||
* model: Team
|
||||
* 400:
|
||||
* description: Bad request. Team body is invalid.
|
||||
* 401:
|
||||
@@ -72,25 +58,23 @@ import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team";
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the team to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, team removed successfuly
|
||||
* model: Team
|
||||
* 400:
|
||||
* description: Bad request. Team id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function teamById(req: NextApiRequest, res: NextApiResponse<TeamResponse>) {
|
||||
const { method, query, body } = req;
|
||||
export async function teamById(
|
||||
{ method, query, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<TeamResponse>
|
||||
) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaTeamBodyParams.safeParse(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
const userId = req.userId;
|
||||
const userWithMemberships = await prisma.membership.findMany({
|
||||
where: { userId: userId },
|
||||
});
|
||||
|
||||
+35
-35
@@ -7,41 +7,26 @@ import { TeamResponse, TeamsResponse } from "@lib/types";
|
||||
import { schemaMembershipPublic } from "@lib/validations/membership";
|
||||
import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /teams:
|
||||
* get:
|
||||
* summary: Find all teams
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No teams were found
|
||||
* post:
|
||||
* summary: Creates a new team
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, team created
|
||||
* model: Team
|
||||
* 400:
|
||||
* description: Bad request. Team body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllTeams(req: NextApiRequest, res: NextApiResponse<TeamsResponse | TeamResponse>) {
|
||||
const { method } = req;
|
||||
const userId = req.userId;
|
||||
async function createOrlistAllTeams(
|
||||
{ method, body, userId }: NextApiRequest,
|
||||
res: NextApiResponse<TeamsResponse | TeamResponse>
|
||||
) {
|
||||
if (method === "GET") {
|
||||
/**
|
||||
* @swagger
|
||||
* /teams:
|
||||
* get:
|
||||
* summary: Find all teams
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No teams were found
|
||||
*/
|
||||
const userWithMemberships = await prisma.membership.findMany({
|
||||
where: { userId: userId },
|
||||
});
|
||||
@@ -55,7 +40,22 @@ async function createOrlistAllTeams(req: NextApiRequest, res: NextApiResponse<Te
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaTeamBodyParams.safeParse(req.body);
|
||||
/**
|
||||
* @swagger
|
||||
* /teams:
|
||||
* post:
|
||||
* summary: Creates a new team
|
||||
* tags:
|
||||
* - teams
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, team created
|
||||
* 400:
|
||||
* description: Bad request. Team body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaTeamBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
const team = await prisma.team.create({ data: safe.data });
|
||||
// We're also creating the relation membership of team ownership in this call.
|
||||
|
||||
+5
-18
@@ -14,7 +14,8 @@ import { schemaUserEditBodyParams, schemaUserReadPublic } from "@lib/validations
|
||||
* @swagger
|
||||
* /users/{id}:
|
||||
* get:
|
||||
* summary: Find a user by ID, returns your user if regular user.
|
||||
* summary: Find a user, returns your user if regular user.
|
||||
* operationId: getUserById
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
@@ -22,8 +23,6 @@ import { schemaUserEditBodyParams, schemaUserReadPublic } from "@lib/validations
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the user to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - users
|
||||
* responses:
|
||||
@@ -35,34 +34,26 @@ import { schemaUserEditBodyParams, schemaUserReadPublic } from "@lib/validations
|
||||
* description: User was not found
|
||||
* patch:
|
||||
* summary: Edit an existing user
|
||||
* consumes:
|
||||
* - application/json
|
||||
* operationId: editUserById
|
||||
* parameters:
|
||||
* - in: body
|
||||
* name: name
|
||||
* description: The users full name
|
||||
* schema:
|
||||
* type: string
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the user to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - users
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, user edited successfuly
|
||||
* model: User
|
||||
* 400:
|
||||
* description: Bad request. User body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* delete:
|
||||
* summary: Remove an existing user
|
||||
* operationId: deleteUserById
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
@@ -70,21 +61,17 @@ import { schemaUserEditBodyParams, schemaUserReadPublic } from "@lib/validations
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the user to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - users
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, user removed successfuly
|
||||
* model: User
|
||||
* 400:
|
||||
* description: Bad request. User id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function userById(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const { method, query, body, userId } = req;
|
||||
export async function userById({ method, query, body, userId }: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
console.log(body);
|
||||
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
|
||||
|
||||
@@ -10,11 +10,10 @@ import { schemaUserReadPublic } from "@lib/validations/user";
|
||||
* @swagger
|
||||
* /users:
|
||||
* get:
|
||||
* summary: Find all users (admin only), returns your user if regular user.
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* summary: Find all users.
|
||||
* tags:
|
||||
* - users
|
||||
* operationId: listUsers
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
@@ -23,8 +22,7 @@ import { schemaUserReadPublic } from "@lib/validations/user";
|
||||
* 404:
|
||||
* description: No users were found
|
||||
*/
|
||||
async function allUsers(req: NextApiRequest, res: NextApiResponse<UsersResponse>) {
|
||||
const userId = req.userId;
|
||||
async function allUsers({ userId }: NextApiRequest, res: NextApiResponse<UsersResponse>) {
|
||||
const data = await prisma.user.findMany({
|
||||
where: {
|
||||
id: userId,
|
||||
|
||||
@@ -21,22 +21,20 @@ import {
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the resource to delete
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
|
||||
* tags:
|
||||
* - resources
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, resource removed successfuly
|
||||
* model: Resource
|
||||
* 400:
|
||||
* description: Bad request. Resource id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function deleteResource(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
|
||||
const safe = schemaQueryIdParseInt.safeParse(req.query);
|
||||
if (!safe.success) throw new Error("Invalid request query", safe.error);
|
||||
export async function deleteResource({query}: NextApiRequest, res: NextApiResponse<BaseResponse>) {
|
||||
const safe = schemaQueryIdParseInt.safeParse(query);
|
||||
if (!safe.success) throw new Error("Invalid request query");
|
||||
|
||||
const data = await prisma.resource.delete({ where: { id: safe.data.id } });
|
||||
|
||||
|
||||
@@ -22,22 +22,20 @@ import {
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the resource to edit
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
|
||||
* tags:
|
||||
* - resources
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, resource edited successfuly
|
||||
* model: Resource
|
||||
* 400:
|
||||
* description: Bad request. Resource body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function editResource(req: NextApiRequest, res: NextApiResponse<ResourceResponse>) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(req.query);
|
||||
const safeBody = schemaResourceBodyParams.safeParse(req.body);
|
||||
export async function editResource({query, body}: NextApiRequest, res: NextApiResponse<ResourceResponse>) {
|
||||
const safeQuery = schemaQueryIdParseInt.safeParse(query);
|
||||
const safeBody = schemaResourceBodyParams.safeParse(body);
|
||||
|
||||
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
|
||||
const resource = await prisma.resource.update({
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
* @swagger
|
||||
* /v1/resources/{id}:
|
||||
* get:
|
||||
* summary: Find a resource by ID
|
||||
* summary: Find a resource
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
@@ -22,8 +22,7 @@ import {
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the resource to get
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
|
||||
* tags:
|
||||
* - resources
|
||||
* responses:
|
||||
@@ -34,8 +33,8 @@ import {
|
||||
* 404:
|
||||
* description: Resource was not found
|
||||
*/
|
||||
export async function resourceById(req: NextApiRequest, res: NextApiResponse<ResourceResponse>) {
|
||||
const safe = schemaQueryIdParseInt.safeParse(req.query);
|
||||
export async function resourceById({query}: NextApiRequest, res: NextApiResponse<ResourceResponse>) {
|
||||
const safe = schemaQueryIdParseInt.safeParse(query);
|
||||
if (!safe.success) throw new Error("Invalid request query");
|
||||
|
||||
const resource = await prisma.resource.findUnique({ where: { id: safe.data.id } });
|
||||
|
||||
@@ -11,8 +11,7 @@ import { schemaResourcePublic } from "@lib/validations/resource";
|
||||
* /v1/resources:
|
||||
* get:
|
||||
* summary: Find all resources
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
|
||||
* tags:
|
||||
* - resources
|
||||
* responses:
|
||||
|
||||
@@ -6,13 +6,18 @@ import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { PaymentResponse, PaymentsResponse } from "@lib/types";
|
||||
import { schemaPaymentBodyParams, schemaPaymentPublic } from "@lib/validations/payment";
|
||||
|
||||
async function createOrlistAllPayments(
|
||||
{method, body}: NextApiRequest,
|
||||
res: NextApiResponse<PaymentsResponse | PaymentResponse>
|
||||
) {
|
||||
if (method === "GET") {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/payments:
|
||||
* get:
|
||||
* summary: Find all payments
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
@@ -22,27 +27,7 @@ import { schemaPaymentBodyParams, schemaPaymentPublic } from "@lib/validations/p
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No payments were found
|
||||
* post:
|
||||
* summary: Creates a new payment
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, payment created
|
||||
* model: Payment
|
||||
* 400:
|
||||
* description: Bad request. Payment body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createOrlistAllPayments(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<PaymentsResponse | PaymentResponse>
|
||||
) {
|
||||
const { method } = req;
|
||||
if (method === "GET") {
|
||||
const payments = await prisma.payment.findMany();
|
||||
const data = payments.map((payment) => schemaPaymentPublic.parse(payment));
|
||||
if (data) res.status(200).json({ data });
|
||||
@@ -53,7 +38,24 @@ async function createOrlistAllPayments(
|
||||
error,
|
||||
});
|
||||
} else if (method === "POST") {
|
||||
const safe = schemaPaymentBodyParams.safeParse(req.body);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/payments:
|
||||
* post:
|
||||
* summary: Creates a new payment
|
||||
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, payment created
|
||||
* 400:
|
||||
* description: Bad request. Payment body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
const safe = schemaPaymentBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const payment = await prisma.payment.create({ data: safe.data });
|
||||
|
||||
@@ -18,22 +18,20 @@ import { schemaResourceBodyParams, schemaResourcePublic, withValidResource } fro
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Resource'
|
||||
* security:
|
||||
* - ApiKeyAuth: []
|
||||
|
||||
* tags:
|
||||
* - resources
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, resource created
|
||||
* model: Resource
|
||||
* 400:
|
||||
* description: Bad request. Resource body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createResource(req: NextApiRequest, res: NextApiResponse<ResourceResponse>) {
|
||||
const safe = schemaResourceBodyParams.safeParse(req.body);
|
||||
if (!safe.success) throw new Error("Invalid request body", safe.error);
|
||||
async function createResource({body}: NextApiRequest, res: NextApiResponse<ResourceResponse>) {
|
||||
const safe = schemaResourceBodyParams.safeParse(body);
|
||||
if (!safe.success) throw new Error("Invalid request body");
|
||||
|
||||
const resource = await prisma.resource.create({ data: safe.data });
|
||||
const data = schemaResourcePublic.parse(resource);
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
declare module "modify-response-middleware";
|
||||
|
||||
Reference in new issue
Block a user