From 625420417e295de6d5485dafdffc43f6f3ed3385 Mon Sep 17 00:00:00 2001 From: percyfikri Date: Wed, 14 Aug 2024 14:22:58 +0700 Subject: [PATCH] update : Revision after first pull request on management-aspect --- .../src/routes/managementAspect/route.ts | 363 +++++++++--------- 1 file changed, 180 insertions(+), 183 deletions(-) diff --git a/apps/backend/src/routes/managementAspect/route.ts b/apps/backend/src/routes/managementAspect/route.ts index 8f0074a..dbbf1fb 100644 --- a/apps/backend/src/routes/managementAspect/route.ts +++ b/apps/backend/src/routes/managementAspect/route.ts @@ -1,51 +1,52 @@ - import { and, eq, ilike, isNull, or, sql } from "drizzle-orm"; - import { Hono } from "hono"; +import { and, eq, ilike, isNull, or, sql } from "drizzle-orm"; +import { Hono } from "hono"; - import { z } from "zod"; - import { HTTPException } from "hono/http-exception"; - import db from "../../drizzle"; - import { aspects } from "../../drizzle/schema/aspects"; - import { subAspects } from "../../drizzle/schema/subAspects"; - import HonoEnv from "../../types/HonoEnv"; - import requestValidator from "../../utils/requestValidator"; - import authInfo from "../../middlewares/authInfo"; - import checkPermission from "../../middlewares/checkPermission"; +import { z } from "zod"; +import db from "../../drizzle"; +import { aspects } from "../../drizzle/schema/aspects"; +import { subAspects } from "../../drizzle/schema/subAspects"; +import HonoEnv from "../../types/HonoEnv"; +import requestValidator from "../../utils/requestValidator"; +import authInfo from "../../middlewares/authInfo"; +import checkPermission from "../../middlewares/checkPermission"; +import { forbidden } from "../../errors/DashboardError"; +import { notFound } from "../../errors/DashboardError"; - // Schema for creating and updating aspects - export const aspectFormSchema = z.object({ - name: z.string().min(1).max(50), - subAspects: z - .string() - .refine( - (data) => { - try { - const parsed = JSON.parse(data); - return Array.isArray(parsed); - } catch { - return false; - } - }, - { - message: "Sub Aspects must be an array", +// Schema for creating and updating aspects +export const aspectFormSchema = z.object({ + name: z.string().min(1).max(50), + subAspects: z + .string() + .refine( + (data) => { + try { + const parsed = JSON.parse(data); + return Array.isArray(parsed); + } catch { + return false; } - ) - .optional(), - }); + }, + { + message: "Sub Aspects must be an array", + } + ) + .optional(), +}); - export const aspectUpdateSchema = aspectFormSchema.extend({ - subAspects: z.string().optional().or(z.literal("")), - }); +export const aspectUpdateSchema = aspectFormSchema.extend({ + subAspects: z.string().optional().or(z.literal("")), +}); - // Schema for creating and updating subAspects - export const subAspectFormSchema = z.object({ - name: z.string().min(1).max(50), - aspectId: z.string().uuid(), - }); +// Schema for creating and updating subAspects +export const subAspectFormSchema = z.object({ + name: z.string().min(1).max(50), + aspectId: z.string().uuid(), +}); - export const subAspectUpdateSchema = subAspectFormSchema.extend({}); +export const subAspectUpdateSchema = subAspectFormSchema.extend({}); - const managementAspectRoute = new Hono() - .use(authInfo) +const managementAspectRoute = new Hono() + .use(authInfo) /** * Get All Aspects (With Metadata) * @@ -53,6 +54,7 @@ * - includeTrashed: boolean (default: false) * - withMetadata: boolean */ + // Get all aspects .get( "/", @@ -76,8 +78,8 @@ async (c) => { const { includeTrashed, page, limit, q } = c.req.valid("query"); - const totalCountQuery = includeTrashed - ? sql`(SELECT count(*) FROM ${aspects})` + const totalCountQuery = includeTrashed + ? sql`(SELECT count(*) FROM ${aspects})` : sql`(SELECT count(*) FROM ${aspects} WHERE ${aspects.deletedAt} IS NULL)`; const result = await db @@ -110,7 +112,7 @@ }); } ) - + // Get aspect by id .get( "/:id", @@ -124,10 +126,12 @@ async (c) => { const aspectId = c.req.param("id"); - if (!aspectId) throw new HTTPException(400, { message: "Missing id" }); + if (!aspectId) + throw notFound({ + message: "Missing id", + }); - const includeTrashed = - c.req.query("includeTrashed")?.toLowerCase() === "true"; + const includeTrashed = c.req.query("includeTrashed")?.toLowerCase() === "true"; const queryResult = await db .select({ @@ -143,15 +147,10 @@ }) .from(aspects) .leftJoin(subAspects, eq(aspects.id, subAspects.aspectId)) - .where( - and( - eq(aspects.id, aspectId), - !includeTrashed ? isNull(aspects.deletedAt) : undefined - ) - ); + .where(and(eq(aspects.id, aspectId), !includeTrashed ? isNull(aspects.deletedAt) : undefined)); if (!queryResult.length) - throw new HTTPException(404, { + throw forbidden({ message: "The aspect does not exist", }); @@ -172,42 +171,44 @@ ) // Create aspect - .post( - "/", - checkPermission("managementAspect.create"), - requestValidator("json", aspectFormSchema), + .post("/", + checkPermission("managementAspect.create"), + requestValidator("json", aspectFormSchema), async (c) => { const aspectData = c.req.valid("json"); - // Validasi untuk mengecek apakah nama aspek sudah ada - const existingAspect = await db - .select() - .from(aspects) - .where(ilike(aspects.name, aspectData.name)); + // Validation to check if the aspect name already exists + const existingAspect = await db + .select() + .from(aspects) + .where(eq(aspects.name, aspectData.name)); - if (existingAspect.length > 0) { - throw new HTTPException(400, { message: "Aspect name already existss" }); - } - - const aspect = await db - .insert(aspects) - .values({ - name: aspectData.name, - }) - .returning(); - - if (aspectData.subAspects) { - const subAspectsArray = JSON.parse(aspectData.subAspects) as string[]; - - if (subAspectsArray.length) { - await db.insert(subAspects).values( - subAspectsArray.map((subAspect) => ({ - aspectId: aspect[0].id, - name: subAspect, - })) - ); - } + if (existingAspect.length > 0) { + throw forbidden({ + message: "Aspect name already exists", + }); + } + + const aspect = await db + .insert(aspects) + .values({ + name: aspectData.name, + }) + .returning(); + + // if sub-aspects are available, parse them into a string array + if (aspectData.subAspects) { + const subAspectsArray = JSON.parse(aspectData.subAspects) as string[]; + // if there are sub-aspects, insert them into the database + if (subAspectsArray.length) { + await db.insert(subAspects).values( + subAspectsArray.map((subAspect) => ({ + aspectId: aspect[0].id, + name: subAspect, + })) + ); } + } return c.json( { @@ -220,58 +221,61 @@ // Update aspect .patch( - "/:id", - checkPermission("managementAspect.update"), - requestValidator("json", aspectUpdateSchema), + "/:id", + checkPermission("managementAspect.update"), + requestValidator("json", aspectUpdateSchema), async (c) => { const aspectId = c.req.param("id"); const aspectData = c.req.valid("json"); - // Validasi untuk mengecek apakah nama aspek baru sudah ada - const existingAspect = await db - .select() - .from(aspects) - .where( - and( - ilike(aspects.name, aspectData.name), - isNull(aspects.deletedAt), - sql`${aspects.id} <> ${aspectId}` - ) - ); + // Validation to check if the new aspect name already exists + const existingAspect = await db + .select() + .from(aspects) + .where( + and( + eq(aspects.name, aspectData.name), + isNull(aspects.deletedAt), + sql`${aspects.id} <> ${aspectId}` + ) + ); - if (existingAspect.length > 0) { - throw new HTTPException(400, { message: "Aspect name already exists" }); - } + if (existingAspect.length > 0) { + throw forbidden({ + message: "Aspect name already exists", + }); + } - const aspect = await db - .select() - .from(aspects) - .where(and(eq(aspects.id, aspectId), isNull(aspects.deletedAt))); + const aspect = await db + .select() + .from(aspects) + .where(and(eq(aspects.id, aspectId), isNull(aspects.deletedAt))); - if (!aspect[0]) return c.notFound(); + if (!aspect[0]) throw notFound(); - await db - .update(aspects) - .set({ - ...aspectData, - updatedAt: new Date(), - }) - .where(eq(aspects.id, aspectId)); + await db + .update(aspects) + .set({ + ...aspectData, + updatedAt: new Date(), + }) + .where(eq(aspects.id, aspectId)); - if (aspectData.subAspects) { - const subAspectsArray = JSON.parse(aspectData.subAspects) as string[]; + //Update for Sub-Aspects + // if (aspectData.subAspects) { + // const subAspectsArray = JSON.parse(aspectData.subAspects) as string[]; - await db.delete(subAspects).where(eq(subAspects.aspectId, aspectId)); + // await db.delete(subAspects).where(eq(subAspects.aspectId, aspectId)); - if (subAspectsArray.length) { - await db.insert(subAspects).values( - subAspectsArray.map((subAspect) => ({ - aspectId: aspectId, - name: subAspect, - })) - ); - } - } + // if (subAspectsArray.length) { + // await db.insert(subAspects).values( + // subAspectsArray.map((subAspect) => ({ + // aspectId: aspectId, + // name: subAspect, + // })) + // ); + // } + // } return c.json({ message: "Aspect updated successfully", @@ -286,34 +290,31 @@ requestValidator( "form", z.object({ - skipTrash: z.string().default("false"), + // skipTrash: z.string().default("false"), }) ), async (c) => { const aspectId = c.req.param("id"); - const skipTrash = c.req.valid("form").skipTrash.toLowerCase() === "true"; + // const skipTrash = c.req.valid("form").skipTrash.toLowerCase() === "true"; const aspect = await db .select() .from(aspects) - .where(and(eq(aspects.id, aspectId), skipTrash ? undefined : isNull(aspects.deletedAt))); + .where(and(eq(aspects.id, aspectId), isNull(aspects.deletedAt))); if (!aspect[0]) - throw new HTTPException(404, { + throw notFound({ message: "The aspect is not found", }); - if (skipTrash) { - await db.delete(aspects).where(eq(aspects.id, aspectId)); - } else { - await db + await db .update(aspects) .set({ deletedAt: new Date(), }) - .where(and(eq(aspects.id, aspectId), isNull(aspects.deletedAt))); - } + .where(eq(aspects.id, aspectId)); + return c.json({ message: "Aspect deleted successfully", }); @@ -322,8 +323,8 @@ // Undo delete .patch( - "/restore/:id", - checkPermission("managementAspect.restore"), + "/restore/:id", + checkPermission("managementAspect.restore"), async (c) => { const aspectId = c.req.param("id"); @@ -332,7 +333,7 @@ if (!aspect) return c.notFound(); if (!aspect.deletedAt) { - throw new HTTPException(400, { + throw forbidden({ message: "The aspect is not deleted", }); } @@ -345,20 +346,22 @@ } ) - // Get sub aspects by aspect ID + // Get sub aspects by aspect ID .get( - "/subAspects/:aspectId", - checkPermission("managementAspect.readAll"), + "/subAspects/:aspectId", + checkPermission("managementAspect.readAll"), async (c) => { const aspectId = c.req.param("aspectId"); const aspect = await db .select() .from(aspects) - .where(and(eq(aspects.id, aspectId), isNull(aspects.deletedAt))); + .where(and( + eq(aspects.id, aspectId), + isNull(aspects.deletedAt))); if (!aspect[0]) - throw new HTTPException(404, { + throw notFound({ message: "The aspect is not found", }); @@ -375,34 +378,35 @@ // Create sub aspect .post( - "/subAspect", - checkPermission("managementAspect.create"), - requestValidator("json", subAspectFormSchema), + "/subAspect", + checkPermission("managementAspect.create"), + requestValidator("json", subAspectFormSchema), async (c) => { const subAspectData = c.req.valid("json"); - // Validasi untuk mengecek apakah nama sub aspek sudah ada + // Validation to check if the sub aspect name already exists const existingSubAspect = await db .select() .from(subAspects) .where( and( - ilike(subAspects.name, subAspectData.name), - eq(subAspects.aspectId, subAspectData.aspectId) - ) - ); + eq(subAspects.name, subAspectData.name), + eq(subAspects.aspectId, subAspectData.aspectId))); if (existingSubAspect.length > 0) { - throw new HTTPException(400, { message: "Nama Sub Aspek sudah tersedia!" }); + throw forbidden({ message: "Nama Sub Aspek sudah tersedia!" }); } - const aspect = await db + const [aspect] = await db .select() .from(aspects) - .where(and(eq(aspects.id, subAspectData.aspectId), isNull(aspects.deletedAt))); + .where( + and( + eq(aspects.id, subAspectData.aspectId), + isNull(aspects.deletedAt))); - if (!aspect[0]) - throw new HTTPException(404, { + if (!aspect) + throw forbidden({ message: "The aspect is not found", }); @@ -419,36 +423,25 @@ // Update sub aspect .patch( - "/subAspect/:id", - checkPermission("managementAspect.update"), - requestValidator("json", subAspectUpdateSchema), + "/subAspect/:id", checkPermission("managementAspect.update"), + requestValidator("json", subAspectUpdateSchema), async (c) => { const subAspectId = c.req.param("id"); const subAspectData = c.req.valid("json"); - // Validasi untuk mengecek apakah nama sub aspek baru sudah ada + // Validation to check if the new sub aspect name already exists const existingSubAspect = await db .select() .from(subAspects) .where( - and( - ilike(subAspects.name, subAspectData.name), - eq(subAspects.aspectId, subAspectData.aspectId), - sql`${subAspects.id} <> ${subAspectId}` - ) - ); + eq(subAspects.aspectId, subAspectData.aspectId)); if (existingSubAspect.length > 0) { - throw new HTTPException(400, { message: "Name Sub Aspect already exists" }); + throw forbidden({ message: "Name Sub Aspect already exists" }); } - const subAspect = await db - .select() - .from(subAspects) - .where(eq(subAspects.id, subAspectId)); - - if (!subAspect[0]) - throw new HTTPException(404, { + if (!existingSubAspect[0]) + throw notFound({ message: "The sub aspect is not found", }); @@ -463,13 +456,12 @@ return c.json({ message: "Sub aspect updated successfully", }); - } - ) + }) // Delete sub aspect .delete( - "/subAspect/:id", - checkPermission("managementAspect.delete"), + "/subAspect/:id", + checkPermission("managementAspect.delete"), async (c) => { const subAspectId = c.req.param("id"); @@ -479,11 +471,17 @@ .where(eq(subAspects.id, subAspectId)); if (!subAspect[0]) - throw new HTTPException(404, { + throw notFound({ message: "The sub aspect is not found", }); - await db.delete(subAspects).where(eq(subAspects.id, subAspectId)); + await db + .update(subAspects) + .set({ + deletedAt: new Date(), + }) + .where(eq(subAspects.id, subAspectId)); + // await db.delete(subAspects).where(eq(subAspects.id, subAspectId)); return c.json({ message: "Sub aspect deleted successfully", @@ -491,5 +489,4 @@ } ); - export default managementAspectRoute; - +export default managementAspectRoute;