feat: schedules hardend

This commit is contained in:
Agusti Fernandez Pardo
2022-04-21 00:48:54 +02:00
parent 80c2c4bdae
commit cabe4ae9c6
3 changed files with 68 additions and 50 deletions
+10 -9
View File
@@ -9,7 +9,9 @@ This is the public REST api for cal.com. It exposes CRUD Endpoints of all our mo
- NextJS
- TypeScript
- Prisma
- No tRPC (for now) We hook directly into prisma client, but probably should look into adding a new @calcom/trpc package that adds pagination and such stuff and can be shared between webapp and API.
- No tRPC **
** (for now) We hook directly into prisma client, but probably should look into adding a new @calcom/trpc package that adds pagination and such stuff and can be shared between webapp and API.
## How to run it
@@ -138,24 +140,23 @@ tests/endpoint/resource.new.test.ts - Create new resource
| teams | ✅ | ✅ | ✅ | ✅ | ✅ |
| users | ✅ | 👤[1] | ✅ | ✅ | ✅ |
## Models missing userId relation.
## Models missing userId relation
- daily-event-references
- destination-calendars
- event-types-custom-input
- memberships
- reminder-mails
- schedules
## Models from database that are not exposed
mostly because they're deemed too sensitive can be revisited if needed.
mostly because they're deemed too sensitive can be revisited if needed. most are expected to be used via cal's webapp.
- [] Api Keys
- [] Credentials
- [] Webhooks
- [] ResetPasswordRequest
- [] VerificationToken
- [ ] Api Keys
- [ ] Credentials
- [ ] Webhooks
- [ ] ResetPasswordRequest
- [ ] VerificationToken
## Documentation (OpenAPI)
+53 -38
View File
@@ -4,6 +4,7 @@ import prisma from "@calcom/prisma";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import type { ScheduleResponse } from "@lib/types";
import { getCalcomUserId } from "@lib/utils/getCalcomUserId";
import { schemaScheduleBodyParams, schemaSchedulePublic } from "@lib/validations/schedule";
import {
schemaQueryIdParseInt,
@@ -90,47 +91,61 @@ export async function scheduleById(req: NextApiRequest, res: NextApiResponse<Sch
const safeQuery = schemaQueryIdParseInt.safeParse(query);
const safeBody = schemaScheduleBodyParams.safeParse(body);
if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error);
const userId = getCalcomUserId(res);
const userSchedules = await prisma.schedule.findMany({ where: { userId } });
const userScheduleIds = userSchedules.map((schedule) => schedule.id);
if (userScheduleIds.includes(safeQuery.data.id)) {
switch (method) {
case "GET":
await prisma.schedule
.findUnique({ where: { id: safeQuery.data.id } })
.then((data) => schemaSchedulePublic.parse(data))
.then((schedule) => res.status(200).json({ schedule }))
.catch((error: Error) =>
res.status(404).json({
message: `Schedule with id: ${safeQuery.data.id} not found`,
error,
})
);
break;
switch (method) {
case "GET":
await prisma.schedule
.findUnique({ where: { id: safeQuery.data.id } })
.then((data) => schemaSchedulePublic.parse(data))
.then((schedule) => res.status(200).json({ schedule }))
.catch((error: Error) =>
res.status(404).json({ message: `Schedule with id: ${safeQuery.data.id} not found`, error })
);
break;
case "PATCH":
if (!safeBody.success) {
throw new Error("Invalid request body");
}
await prisma.schedule
.update({ where: { id: safeQuery.data.id }, data: safeBody.data })
.then((data) => schemaSchedulePublic.parse(data))
.then((schedule) => res.status(200).json({ schedule }))
.catch((error: Error) =>
res.status(404).json({
message: `Schedule with id: ${safeQuery.data.id} not found`,
error,
})
);
break;
case "PATCH":
if (!safeBody.success) throw new Error("Invalid request body");
await prisma.schedule
.update({
where: { id: safeQuery.data.id },
data: safeBody.data,
})
.then((data) => schemaSchedulePublic.parse(data))
.then((schedule) => res.status(200).json({ schedule }))
.catch((error: Error) =>
res.status(404).json({ message: `Schedule with id: ${safeQuery.data.id} not found`, error })
);
break;
case "DELETE":
await prisma.schedule
.delete({ where: { id: safeQuery.data.id } })
.then(() =>
res.status(200).json({
message: `Schedule with id: ${safeQuery.data.id} deleted successfully`,
})
)
.catch((error: Error) =>
res.status(404).json({
message: `Schedule with id: ${safeQuery.data.id} not found`,
error,
})
);
break;
case "DELETE":
await prisma.schedule
.delete({ where: { id: safeQuery.data.id } })
.then(() =>
res.status(200).json({ message: `Schedule with id: ${safeQuery.data.id} deleted successfully` })
)
.catch((error: Error) =>
res.status(404).json({ message: `Schedule with id: ${safeQuery.data.id} not found`, error })
);
break;
default:
res.status(405).json({ message: "Method not allowed" });
break;
}
default:
res.status(405).json({ message: "Method not allowed" });
break;
}
} else res.status(401).json({ message: "Unauthorized" });
}
export default withMiddleware("HTTP_GET_DELETE_PATCH")(withValidQueryIdTransformParseInt(scheduleById));
+5 -3
View File
@@ -4,6 +4,7 @@ import prisma from "@calcom/prisma";
import { withMiddleware } from "@lib/helpers/withMiddleware";
import { ScheduleResponse, SchedulesResponse } from "@lib/types";
import { getCalcomUserId } from "@lib/utils/getCalcomUserId";
import { schemaScheduleBodyParams, schemaSchedulePublic, withValidSchedule } from "@lib/validations/schedule";
/**
@@ -42,8 +43,10 @@ async function createOrlistAllSchedules(
res: NextApiResponse<SchedulesResponse | ScheduleResponse>
) {
const { method } = req;
const userId = getCalcomUserId(res);
if (method === "GET") {
const data = await prisma.schedule.findMany();
const data = await prisma.schedule.findMany({ where: { userId } });
const schedules = data.map((schedule) => schemaSchedulePublic.parse(schedule));
if (schedules) res.status(200).json({ schedules });
else
@@ -55,8 +58,7 @@ async function createOrlistAllSchedules(
} else if (method === "POST") {
const safe = schemaScheduleBodyParams.safeParse(req.body);
if (!safe.success) throw new Error("Invalid request body");
const data = await prisma.schedule.create({ data: safe.data });
const data = await prisma.schedule.create({ data: { ...safe.data, userId } });
const schedule = schemaSchedulePublic.parse(data);
if (schedule) res.status(201).json({ schedule, message: "Schedule created successfully" });