From 1cb345c316a3a5ed18cdcf8892cdfe2e600aec2a Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Sun, 29 May 2022 17:15:12 +0200 Subject: [PATCH] de-duplicated (un-)linkMedia --- src/Controllers/discipline.controller.ts | 58 -------------- src/Controllers/event.controller.ts | 64 --------------- src/Controllers/media.controller.ts | 95 +++++++++++++++++++++++ src/Controllers/role_schema.controller.ts | 58 -------------- src/Routes/discipline.routes.ts | 14 ---- src/Routes/event.routes.ts | 10 --- src/Routes/media.routes.ts | 26 ++++++- src/Routes/role_schema.routes.ts | 10 --- 8 files changed, 120 insertions(+), 215 deletions(-) diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index f6ea601..25bd7ae 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -286,61 +286,3 @@ export const deleteDiscipline = async (req: Request throw e; } }; - -interface visualParams { - disciplinePid: string; -} - -interface visualBody { - mediaPid: string; -} - -export const addVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED") { - res.status(403).json(createInsufficientPermissionsError()); - } - - const { disciplinePid } = req.params; - - const discipline = await prisma.discipline.update({ - where: { pid: disciplinePid }, - data: { - visual: { connect: { pid: req.body.mediaPid } }, - }, - }); - - if (!discipline) { - throw new NotFoundError("discipline", disciplinePid); - } - - return res.status(200).json({ - type: "success", - payload: {}, - }); -}; - -export const deleteVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED") { - res.status(403).json(createInsufficientPermissionsError()); - } - - const { disciplinePid, pid } = req.params; - - try { - await prisma.discipline.update({ - where: { - pid: disciplinePid, - }, - data: { - visual: { disconnect: { pid } }, - }, - }); - return res.status(204).end(); - } catch (e) { - if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { - throw new NotFoundError("discipline", disciplinePid); - } - - throw e; - } -}; diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index 7975165..70cdc57 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -272,67 +272,3 @@ export const deleteEvent = async (req: Request, res: Res throw e; } }; - -// REVIEW: This code **will** need to be de-duplicated - -interface visualParams { - eventPid: string; -} - -interface visualBody { - mediaPid: string; -} - -export const addVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED") { - res.status(403).json(createInsufficientPermissionsError()); - } - - const { eventPid } = req.params; - - if (typeof req.body.mediaPid !== "string") { - res.status(400).json(generateInvalidBodyError({ mediaPid: DataType.STRING })); - } - - const event = await prisma.event.update({ - where: { pid: eventPid }, - data: { - visual: { connect: { pid: req.body.mediaPid } }, - }, - }); - - if (!event) { - throw new NotFoundError("event", eventPid); - } - - return res.status(200).json({ - type: "success", - payload: {}, - }); -}; - -export const deleteVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED") { - res.status(403).json(createInsufficientPermissionsError()); - } - - const { eventPid, pid } = req.params; - - try { - await prisma.event.update({ - where: { - pid: eventPid, - }, - data: { - visual: { disconnect: { pid } }, - }, - }); - return res.status(204).end(); - } catch (e) { - if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { - throw new NotFoundError("discipline", eventPid); - } - - throw e; - } -}; diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index eb78bc3..83a34c3 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -12,9 +12,18 @@ import { type } from "os"; import { unlink } from "fs/promises"; import ForwardableError from "../Middleware/error/ForwardableError"; import SchemaError from "../Middleware/error/SchemaError"; +import { z } from "zod"; +import { updateEvent } from "./event.controller"; require("express-async-errors"); +const linkMediaBody = z.object({ + tableToUpdate: z.enum(["EVENT", "ROLE_SCHEMA", "DISCIPLINE"]), + mediaPid: z.string(), +}); + +const unlinkMediaBody = linkMediaBody.omit({ mediaPid: true, }); + function createMediaLinks(fileName: string) { return [{ rel: "self", type: "GET", href: `/api/media/${fileName}` }]; } @@ -189,3 +198,89 @@ export const deleteMedia = async (req: Request, res: Response) => { throw e; } }; + +//TODO: maybe create a function that adds the tableToUpdate based on path +// and call it before calling (un)linkMedia + +export const linkMedia = async ( + req: Request<{ pid: string }, {}, { mediaPid: string, tableToUpdate: string }>, + res: Response) => { + if (req.auth?.permission_level != "ELEVATED") { + res.status(403).json(createInsufficientPermissionsError()); + } + + const zBody = linkMediaBody.safeParse(req.body); + + if(zBody.success === false) { + return res.status(400).json( + generateInvalidBodyError({ + mediaPid: DataType.UUID, + tableToUpdate: DataType.STRING, + }) + ); + } + + const { pid } = req.params; + const { mediaPid, tableToUpdate } = zBody.data; + + const updatedRec = await getPrismaUpdateFKT(tableToUpdate)({ + where: { pid }, + data: { + visual: { connect: { pid: mediaPid } }, + }, + }); + + if (!updatedRec) { + throw new NotFoundError(tableToUpdate, pid); + } + + return res.status(200).json({ + type: "success", + payload: {}, + }); +}; + +export const unlinkMedia = async ( + req: Request<{ pid: string, mediaPid: string }, {}, { tableToUpdate: string }>, + res: Response) => { + if (req.auth?.permission_level != "ELEVATED") { + res.status(403).json(createInsufficientPermissionsError()); + } + + const zBody = linkMediaBody.safeParse(req.body); + + if(zBody.success === false) { + return res.status(400).json( + generateInvalidBodyError({ + mediaPid: DataType.UUID, + tableToUpdate: DataType.STRING, + }) + ); + } + + const { pid } = req.params; + const { mediaPid, tableToUpdate } = zBody.data; + + try { + await getPrismaUpdateFKT(tableToUpdate)({ + where: pid, + data: { visual: { disconnect: { pid: mediaPid } }, + }, + }); + return res.status(204).end(); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { + throw new NotFoundError(tableToUpdate, pid); + } + + throw e; + } +}; + +function getPrismaUpdateFKT( tableToUpdate: string ): Function { + switch(tableToUpdate) { + case "EVENT": return prisma.event.update; + case "DISCIPLINE": return prisma.discipline.update; + default: return prisma.roleSchema.update; + } +} diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index 36265de..78951d0 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -123,61 +123,3 @@ export const createRoleSchema = async ( throw e; } }; - -interface visualParams { - schemaPid: string; -} - -interface visualBody { - mediaPid: string; -} - -export const addVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED") { - res.status(403).json(createInsufficientPermissionsError()); - } - - const { schemaPid } = req.params; - - const schema = await prisma.roleSchema.update({ - where: { pid: schemaPid }, - data: { - visual: { connect: { pid: req.body.mediaPid } }, - }, - }); - - if (!schema) { - throw new NotFoundError("role_schema", schemaPid); - } - - return res.status(200).json({ - type: "success", - payload: {}, - }); -}; - -export const deleteVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED") { - res.status(403).json(createInsufficientPermissionsError()); - } - - const { schemaPid, pid } = req.params; - - try { - await prisma.roleSchema.update({ - where: { - pid: schemaPid, - }, - data: { - visual: { disconnect: { pid } }, - }, - }); - return res.status(204).end(); - } catch (e) { - if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { - throw new NotFoundError("role_schema", schemaPid); - } - - throw e; - } -}; diff --git a/src/Routes/discipline.routes.ts b/src/Routes/discipline.routes.ts index 2d97a8e..288cc30 100644 --- a/src/Routes/discipline.routes.ts +++ b/src/Routes/discipline.routes.ts @@ -1,10 +1,8 @@ import express from "express"; import eventRouter from "./event.routes"; import { - addVisual, createDiscipline, deleteDiscipline, - deleteVisual, getAllDisciplines, getDiscipline, } from "../Controllers/discipline.controller"; @@ -18,18 +16,6 @@ router.get("/:pid", getDiscipline); router.delete<"/:pid", { pid: string }>("/:pid", requireAuthentication, deleteDiscipline); -router.post<"/:disciplinePid/images", { disciplinePid: string }>( - "/:disciplinePid/images", - requireAuthentication, - addVisual -); - -router.delete<"/:disciplinePid/images/:pid", { disciplinePid: string; pid: string }>( - "/:disciplinePid/images/:pid", - requireAuthentication, - deleteVisual -); - eventRouter.post("/:eventPid/disciplines", requireAuthentication, createDiscipline); export default router; diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index 5e68bd8..7c2d34d 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -2,9 +2,7 @@ import Express from "express"; import { string } from "zod"; import { addEvent, - addVisual, deleteEvent, - deleteVisual, getAllEvents, getEvent, updateEvent, @@ -22,12 +20,4 @@ router.patch<"/:pid/", { pid: string }>("/:pid/", requireAuthentication, updateE router.delete<"/:pid/", { pid: string }>("/:pid/", requireAuthentication, deleteEvent); -router.post<"/:eventPid/media", { eventPid: string }>("/:eventPid/media", requireAuthentication, addVisual); - -router.delete<"/:eventPid/media/:pid", { eventPid: string; pid: string }>( - "/:eventPid/media/:pid", - requireAuthentication, - deleteVisual -); - export default router; diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index f340de1..e4c633a 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -1,7 +1,7 @@ import express from "express"; import fileUpload from "express-fileupload"; import { requireAuthentication } from "../Middleware/auth/auth"; -import { deleteMedia, getAllMedia, getMediaMeta, uploadImage } from "../Controllers/media.controller"; +import { deleteMedia, getAllMedia, getMediaMeta, linkMedia, unlinkMedia, uploadImage } from "../Controllers/media.controller"; import eventRouter from "./event.routes"; import disciplineRouter from "./discipline.routes"; import roleSchemaRouter from "./role_schema.routes"; @@ -19,4 +19,28 @@ router.get("/:pid/meta", getMediaMeta); router.delete("/:pid", requireAuthentication, deleteMedia); +eventRouter.post<"/:pid/media", { pid: string }>( + "/:pid/media", requireAuthentication, linkMedia +); + +eventRouter.delete<"/:pid/media/:mediaPid", { pid: string, mediaPid: string }>( + "/:pid/media/:mediaPid", requireAuthentication, unlinkMedia +); + +disciplineRouter.post<"/:pid/media", { pid: string }>( + "/:pid/media", requireAuthentication, linkMedia +); + +disciplineRouter.delete<"/:pid/media/:mediaPid", { pid: string, mediaPid: string }>( + "/:pid/media/:mediaPid", requireAuthentication, unlinkMedia +); + +roleSchemaRouter.post<"/:pid/media", { pid: string }>( + "/:pid/media", requireAuthentication, linkMedia +); + +roleSchemaRouter.delete<"/:pid/media/:mediaPid", { pid: string, mediaPid: string }>( + "/:pid/media/:mediaPid", requireAuthentication, unlinkMedia +); + export default router; diff --git a/src/Routes/role_schema.routes.ts b/src/Routes/role_schema.routes.ts index f6ada5f..688dafc 100644 --- a/src/Routes/role_schema.routes.ts +++ b/src/Routes/role_schema.routes.ts @@ -1,9 +1,7 @@ import express from "express"; import disciplineRouter from "./discipline.routes"; import { - addVisual, createRoleSchema, - deleteVisual, getAllRoleSchemas, getAllRoleSchemasWithParam, getRoleSchema, @@ -20,12 +18,4 @@ disciplineRouter.get("/:disciplinePid/role-schemas", getAllRoleSchemasWithParam) disciplineRouter.post("/:disciplinePid/role-schemas", requireAuthentication, createRoleSchema); -router.post<"/:schemaPid/images", { schemaPid: string }>("/:schemaPid/images", requireAuthentication, addVisual); - -router.delete<"/:schemaPid/images/:pid", { schemaPid: string; pid: string }>( - "/:schemaPid/images/:pid", - requireAuthentication, - deleteVisual -); - export default router;