From 8ee68e2acea4df6f713508c71835c4621946bb4d Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 13 Sep 2021 09:57:56 +0100 Subject: [PATCH] Converts booking deletion to soft-delete + more robust cancellation (#581) * Converts booking deletion to soft-delete + more robust cancellation * Update pages/api/cancel.ts infer type :) Co-authored-by: Alex Johansson Co-authored-by: Alex Johansson Co-authored-by: Bailey Pumfleet --- pages/api/cancel.ts | 38 +++++++++++++------ pages/bookings/index.tsx | 17 +++++---- .../migration.sql | 5 +++ prisma/schema.prisma | 8 ++++ 4 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 prisma/migrations/20210904162403_add_booking_status_enum/migration.sql diff --git a/pages/api/cancel.ts b/pages/api/cancel.ts index 3610f1da..9205f2db 100644 --- a/pages/api/cancel.ts +++ b/pages/api/cancel.ts @@ -1,15 +1,17 @@ -import prisma from "../../lib/prisma"; -import { deleteEvent } from "../../lib/calendarClient"; +import prisma from "@lib/prisma"; +import { deleteEvent } from "@lib/calendarClient"; import async from "async"; -import { deleteMeeting } from "../../lib/videoClient"; +import { deleteMeeting } from "@lib/videoClient"; +import { asStringOrNull } from "@lib/asStringOrNull"; +import { BookingStatus } from "@prisma/client"; export default async function handler(req, res) { if (req.method == "POST") { - const uid = req.body.uid; + const uid = asStringOrNull(req.body.uid); - const bookingToDelete = await prisma.booking.findFirst({ + const bookingToDelete = await prisma.booking.findUnique({ where: { - uid: uid, + uid, }, select: { id: true, @@ -28,6 +30,21 @@ export default async function handler(req, res) { }, }); + if (!bookingToDelete) { + return res.status(404).end(); + } + + // by cancelling first, and blocking whilst doing so; we can ensure a cancel + // action always succeeds even if subsequent integrations fail cancellation. + await prisma.booking.update({ + where: { + uid, + }, + data: { + status: BookingStatus.CANCELLED, + }, + }); + const apiDeletes = async.mapLimit(bookingToDelete.user.credentials, 5, async (credential) => { const bookingRefUid = bookingToDelete.references.filter((ref) => ref.type === credential.type)[0]?.uid; if (bookingRefUid) { @@ -38,23 +55,20 @@ export default async function handler(req, res) { } } }); + const attendeeDeletes = prisma.attendee.deleteMany({ where: { bookingId: bookingToDelete.id, }, }); + const bookingReferenceDeletes = prisma.bookingReference.deleteMany({ where: { bookingId: bookingToDelete.id, }, }); - const bookingDeletes = prisma.booking.delete({ - where: { - id: bookingToDelete.id, - }, - }); - await Promise.all([apiDeletes, attendeeDeletes, bookingReferenceDeletes, bookingDeletes]); + await Promise.all([apiDeletes, attendeeDeletes, bookingReferenceDeletes]); //TODO Perhaps send emails to user and client to tell about the cancellation diff --git a/pages/bookings/index.tsx b/pages/bookings/index.tsx index 282e8de0..21be95dd 100644 --- a/pages/bookings/index.tsx +++ b/pages/bookings/index.tsx @@ -10,6 +10,7 @@ import classNames from "@lib/classNames"; import { ClockIcon, XIcon } from "@heroicons/react/outline"; import Loader from "@components/Loader"; import { getSession } from "@lib/auth"; +import { BookingStatus } from "@prisma/client"; export default function Bookings({ bookings }) { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -44,8 +45,7 @@ export default function Bookings({ bookings }) { {bookings - .filter((booking) => !booking.confirmed && !booking.rejected) - .concat(bookings.filter((booking) => booking.confirmed || booking.rejected)) + .filter((booking) => booking.status !== BookingStatus.CANCELLED) .map((booking) => (
@@ -66,11 +66,13 @@ export default function Bookings({ bookings }) { - + {booking.attendees.length !== 0 && ( + + )}
@@ -232,6 +234,7 @@ export async function getServerSideProps(context) { id: true, startTime: true, endTime: true, + status: true, }, orderBy: { startTime: "asc", diff --git a/prisma/migrations/20210904162403_add_booking_status_enum/migration.sql b/prisma/migrations/20210904162403_add_booking_status_enum/migration.sql new file mode 100644 index 00000000..a8c72845 --- /dev/null +++ b/prisma/migrations/20210904162403_add_booking_status_enum/migration.sql @@ -0,0 +1,5 @@ +-- CreateEnum +CREATE TYPE "BookingStatus" AS ENUM ('cancelled', 'accepted', 'rejected', 'pending'); + +-- AlterTable +ALTER TABLE "Booking" ADD COLUMN "status" "BookingStatus" NOT NULL DEFAULT E'accepted'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a5b8b10b..4777c2e8 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -136,6 +136,13 @@ model Attendee { bookingId Int? } +enum BookingStatus { + CANCELLED @map("cancelled") + ACCEPTED @map("accepted") + REJECTED @map("rejected") + PENDING @map("pending") +} + model Booking { id Int @id @default(autoincrement()) uid String @unique @@ -157,6 +164,7 @@ model Booking { updatedAt DateTime? confirmed Boolean @default(true) rejected Boolean @default(false) + status BookingStatus @default(ACCEPTED) } model Schedule {