Merge pull request #16 from calcom/feat/add-payments-and-reminder-mails
commit
902aacfb12
|
@ -16,6 +16,7 @@ import {
|
|||
Membership,
|
||||
Payment,
|
||||
Schedule,
|
||||
ReminderMail,
|
||||
} from "@calcom/prisma/client";
|
||||
|
||||
// Base response, used for all responses
|
||||
|
@ -160,3 +161,11 @@ export type WebhookResponse = BaseResponse & {
|
|||
export type WebhooksResponse = BaseResponse & {
|
||||
data?: Partial<Webhook>[];
|
||||
};
|
||||
|
||||
// ReminderMail
|
||||
export type ReminderMailResponse = BaseResponse & {
|
||||
data?: Partial<ReminderMail>;
|
||||
};
|
||||
export type ReminderMailsResponse = BaseResponse & {
|
||||
data?: Partial<ReminderMail>[];
|
||||
};
|
||||
|
|
|
@ -13,7 +13,6 @@ export const schemaEventTypeCustomInputPublic = EventTypeCustomInput.omit({});
|
|||
const schemaEventTypeCustomInputRequiredParams = z.object({
|
||||
label: z.string(),
|
||||
required: z.boolean(),
|
||||
// eventType: EventTypeModel.optional(),
|
||||
type: z.enum(["TEXT", "TEXTLONG", "NUMBER", "BOOL"]),
|
||||
eventType: z.object({
|
||||
connect: z.object({
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { withValidation } from "next-validations";
|
||||
import { z } from "zod";
|
||||
|
||||
import { _ReminderMailModel as ReminderMail } from "@calcom/prisma/zod";
|
||||
|
||||
export const schemaReminderMailBaseBodyParams = ReminderMail.omit({ id: true }).partial();
|
||||
|
||||
export const schemaReminderMailPublic = ReminderMail.omit({});
|
||||
|
||||
const schemaReminderMailRequiredParams = z.object({
|
||||
referenceId: z.number().int(),
|
||||
reminderType: z.enum(["PENDING_BOOKING_CONFIRMATION"]),
|
||||
elapsedMinutes: z.number().int(),
|
||||
});
|
||||
|
||||
export const schemaReminderMailBodyParams = schemaReminderMailBaseBodyParams.merge(
|
||||
schemaReminderMailRequiredParams
|
||||
);
|
||||
|
||||
export const withValidReminderMail = withValidation({
|
||||
schema: schemaReminderMailBodyParams,
|
||||
type: "Zod",
|
||||
mode: "body",
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { BaseResponse } from "@lib/types";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/payments/{id}/delete:
|
||||
* delete:
|
||||
* summary: Remove an existing payment
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the payment to delete
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, payment removed successfuly
|
||||
* model: Payment
|
||||
* 400:
|
||||
* description: Bad request. Payment id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function deletePayment(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
|
||||
const safe = await schemaQueryIdParseInt.safeParse(req.query);
|
||||
if (!safe.success) throw new Error("Invalid request query", safe.error);
|
||||
|
||||
const data = await prisma.payment.delete({ where: { id: safe.data.id } });
|
||||
|
||||
if (data) res.status(200).json({ message: `Payment with id: ${safe.data.id} deleted successfully` });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(400).json({
|
||||
message: `Payment with id: ${safe.data.id} was not able to be processed`,
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deletePayment));
|
|
@ -0,0 +1,56 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { PaymentResponse } from "@lib/types";
|
||||
import { schemaPaymentBodyParams, schemaPaymentPublic, withValidPayment } from "@lib/validations/payment";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/payments/{id}/edit:
|
||||
* patch:
|
||||
* summary: Edit an existing payment
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the payment to edit
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, payment edited successfuly
|
||||
* model: Payment
|
||||
* 400:
|
||||
* description: Bad request. Payment body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function editPayment(req: NextApiRequest, res: NextApiResponse<PaymentResponse>) {
|
||||
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
|
||||
const safeBody = await schemaPaymentBodyParams.safeParse(req.body);
|
||||
|
||||
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
|
||||
const payment = await prisma.payment.update({
|
||||
where: { id: safeQuery.data.id },
|
||||
data: safeBody.data,
|
||||
});
|
||||
const data = schemaPaymentPublic.parse(payment);
|
||||
|
||||
if (data) res.status(200).json({ data });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`,
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_PATCH")(withValidQueryIdTransformParseInt(withValidPayment(editPayment)));
|
|
@ -0,0 +1,51 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { PaymentResponse } from "@lib/types";
|
||||
import { schemaPaymentPublic } from "@lib/validations/payment";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/payments/{id}:
|
||||
* get:
|
||||
* summary: Get a payment by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the payment to get
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: Payment was not found
|
||||
*/
|
||||
export async function paymentById(req: NextApiRequest, res: NextApiResponse<PaymentResponse>) {
|
||||
const safe = await schemaQueryIdParseInt.safeParse(req.query);
|
||||
if (!safe.success) throw new Error("Invalid request query");
|
||||
|
||||
const payment = await prisma.payment.findUnique({ where: { id: safe.data.id } });
|
||||
const data = schemaPaymentPublic.parse(payment);
|
||||
|
||||
if (payment) res.status(200).json({ data });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: "Payment was not found",
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(paymentById));
|
|
@ -0,0 +1,37 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { PaymentsResponse } from "@lib/types";
|
||||
import { schemaPaymentPublic } from "@lib/validations/payment";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/payments:
|
||||
* get:
|
||||
* summary: Get all payments
|
||||
* tags:
|
||||
* - payments
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No payments were found
|
||||
*/
|
||||
async function allPayments(_: NextApiRequest, res: NextApiResponse<PaymentsResponse>) {
|
||||
const payments = await prisma.payment.findMany();
|
||||
const data = payments.map((payment) => schemaPaymentPublic.parse(payment));
|
||||
|
||||
if (data) res.status(200).json({ data });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: "No Payments were found",
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_GET")(allPayments);
|
|
@ -0,0 +1,48 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { PaymentResponse } from "@lib/types";
|
||||
import { schemaPaymentBodyParams, schemaPaymentPublic, withValidPayment } from "@lib/validations/payment";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/payments/new:
|
||||
* post:
|
||||
* summary: Creates a new payment
|
||||
* requestBody:
|
||||
* description: Optional description in *Markdown*
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Payment'
|
||||
* 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 createPayment(req: NextApiRequest, res: NextApiResponse<PaymentResponse>) {
|
||||
const safe = schemaPaymentBodyParams.safeParse(req.body);
|
||||
if (!safe.success) throw new Error("Invalid request body", safe.error);
|
||||
|
||||
const payment = await prisma.payment.create({ data: safe.data });
|
||||
const data = schemaPaymentPublic.parse(payment);
|
||||
|
||||
if (data) res.status(201).json({ data, message: "Payment created successfully" });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(400).json({
|
||||
message: "Could not create new payment",
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_POST")(withValidPayment(createPayment));
|
|
@ -0,0 +1,50 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { BaseResponse } from "@lib/types";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/reminder-mails/{id}/delete:
|
||||
* delete:
|
||||
* summary: Remove an existing reminderMail
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the reminderMail to delete
|
||||
* tags:
|
||||
* - reminderMails
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, reminderMail removed successfuly
|
||||
* model: ReminderMail
|
||||
* 400:
|
||||
* description: Bad request. ReminderMail id is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function deleteReminderMail(req: NextApiRequest, res: NextApiResponse<BaseResponse>) {
|
||||
const safe = await schemaQueryIdParseInt.safeParse(req.query);
|
||||
if (!safe.success) throw new Error("Invalid request query", safe.error);
|
||||
|
||||
const data = await prisma.reminderMail.delete({ where: { id: safe.data.id } });
|
||||
|
||||
if (data) res.status(200).json({ message: `ReminderMail with id: ${safe.data.id} deleted successfully` });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(400).json({
|
||||
message: `ReminderMail with id: ${safe.data.id} was not able to be processed`,
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_DELETE")(withValidQueryIdTransformParseInt(deleteReminderMail));
|
|
@ -0,0 +1,62 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { ReminderMailResponse } from "@lib/types";
|
||||
import {
|
||||
schemaReminderMailBodyParams,
|
||||
schemaReminderMailPublic,
|
||||
withValidReminderMail,
|
||||
} from "@lib/validations/reminder-mail";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/reminder-mails/{id}/edit:
|
||||
* patch:
|
||||
* summary: Edit an existing reminderMail
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the reminderMail to edit
|
||||
* tags:
|
||||
* - reminderMails
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, reminderMail edited successfuly
|
||||
* model: ReminderMail
|
||||
* 400:
|
||||
* description: Bad request. ReminderMail body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
export async function editReminderMail(req: NextApiRequest, res: NextApiResponse<ReminderMailResponse>) {
|
||||
const safeQuery = await schemaQueryIdParseInt.safeParse(req.query);
|
||||
const safeBody = await schemaReminderMailBodyParams.safeParse(req.body);
|
||||
|
||||
if (!safeQuery.success || !safeBody.success) throw new Error("Invalid request");
|
||||
const reminderMail = await prisma.reminderMail.update({
|
||||
where: { id: safeQuery.data.id },
|
||||
data: safeBody.data,
|
||||
});
|
||||
const data = schemaReminderMailPublic.parse(reminderMail);
|
||||
|
||||
if (data) res.status(200).json({ data });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`,
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_PATCH")(
|
||||
withValidQueryIdTransformParseInt(withValidReminderMail(editReminderMail))
|
||||
);
|
|
@ -0,0 +1,51 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { ReminderMailResponse } from "@lib/types";
|
||||
import { schemaReminderMailPublic } from "@lib/validations/reminder-mail";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
} from "@lib/validations/shared/queryIdTransformParseInt";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/reminder-mails/{id}:
|
||||
* get:
|
||||
* summary: Get a reminderMail by ID
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* schema:
|
||||
* type: integer
|
||||
* required: true
|
||||
* description: Numeric ID of the reminderMail to get
|
||||
* tags:
|
||||
* - reminderMails
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: ReminderMail was not found
|
||||
*/
|
||||
export async function reminderMailById(req: NextApiRequest, res: NextApiResponse<ReminderMailResponse>) {
|
||||
const safe = await schemaQueryIdParseInt.safeParse(req.query);
|
||||
if (!safe.success) throw new Error("Invalid request query");
|
||||
|
||||
const reminderMail = await prisma.reminderMail.findUnique({ where: { id: safe.data.id } });
|
||||
const data = schemaReminderMailPublic.parse(reminderMail);
|
||||
|
||||
if (reminderMail) res.status(200).json({ data });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: "ReminderMail was not found",
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_GET")(withValidQueryIdTransformParseInt(reminderMailById));
|
|
@ -0,0 +1,37 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { ReminderMailsResponse } from "@lib/types";
|
||||
import { schemaReminderMailPublic } from "@lib/validations/reminder-mail";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/reminder-mails:
|
||||
* get:
|
||||
* summary: Get all reminderMails
|
||||
* tags:
|
||||
* - reminderMails
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
* 404:
|
||||
* description: No reminderMails were found
|
||||
*/
|
||||
async function allReminderMails(_: NextApiRequest, res: NextApiResponse<ReminderMailsResponse>) {
|
||||
const reminderMails = await prisma.reminderMail.findMany();
|
||||
const data = reminderMails.map((reminderMail) => schemaReminderMailPublic.parse(reminderMail));
|
||||
|
||||
if (data) res.status(200).json({ data });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(404).json({
|
||||
message: "No ReminderMails were found",
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_GET")(allReminderMails);
|
|
@ -0,0 +1,52 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { ReminderMailResponse } from "@lib/types";
|
||||
import {
|
||||
schemaReminderMailBodyParams,
|
||||
schemaReminderMailPublic,
|
||||
withValidReminderMail,
|
||||
} from "@lib/validations/reminder-mail";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/reminder-mails/new:
|
||||
* post:
|
||||
* summary: Creates a new reminderMail
|
||||
* requestBody:
|
||||
* description: Optional description in *Markdown*
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/ReminderMail'
|
||||
* tags:
|
||||
* - reminderMails
|
||||
* responses:
|
||||
* 201:
|
||||
* description: OK, reminderMail created
|
||||
* model: ReminderMail
|
||||
* 400:
|
||||
* description: Bad request. ReminderMail body is invalid.
|
||||
* 401:
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function createReminderMail(req: NextApiRequest, res: NextApiResponse<ReminderMailResponse>) {
|
||||
const safe = schemaReminderMailBodyParams.safeParse(req.body);
|
||||
if (!safe.success) throw new Error("Invalid request body", safe.error);
|
||||
|
||||
const reminderMail = await prisma.reminderMail.create({ data: safe.data });
|
||||
const data = schemaReminderMailPublic.parse(reminderMail);
|
||||
|
||||
if (data) res.status(201).json({ data, message: "ReminderMail created successfully" });
|
||||
else
|
||||
(error: Error) =>
|
||||
res.status(400).json({
|
||||
message: "Could not create new reminderMail",
|
||||
error,
|
||||
});
|
||||
}
|
||||
|
||||
export default withMiddleware("HTTP_POST")(withValidReminderMail(createReminderMail));
|
Loading…
Reference in New Issue