import { Body, Controller, Delete, Get, Path, Post, Put, Route, Security, Tags } from "tsoa"; import prisma from "../db"; import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; type MenuCreate = { caption: string; captionEN: string; menuType: string; url: string; parentId?: string; }; type MenuEdit = { caption: string; captionEN: string; menuType: string; url: string; }; @Route("v1/permission/menu") @Tags("Permission") @Security("keycloak") export class MenuController extends Controller { @Get() async listMenu() { const record = await prisma.menu.findMany({ include: { children: true, roleMenuPermission: true }, orderBy: { createdAt: "asc" }, }); return record; } @Post() async createMenu(@Body() body: MenuCreate) { if (body.parentId) { const parent = await prisma.menu.findFirst({ where: { id: body.parentId } }); if (!parent) { throw new HttpError( HttpStatus.BAD_REQUEST, "Parent menu not found.", "missing_or_invalid_parameter", ); } } const record = await prisma.menu.create({ include: { parent: true }, data: body, }); this.setStatus(HttpStatus.CREATED); return record; } @Put("{menuId}") async editMenu(@Path("menuId") id: string, @Body() body: MenuEdit) { const record = await prisma.menu .update({ include: { parent: true }, where: { id }, data: body, }) .catch((e) => { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { throw new HttpError(HttpStatus.NOT_FOUND, "Menu cannot be found.", "data_not_found"); } throw new Error(e); }); return record; } @Delete("{menuId}") async deleteMenu(@Path("menuId") id: string) { const record = await prisma.menu.deleteMany({ where: { id } }); if (record.count <= 0) { throw new HttpError(HttpStatus.NOT_FOUND, "Menu cannot be found.", "data_not_found"); } } } type MenuComponentCreate = { componentId: string; componentTag: string; menuId: string; }; type MenuComponentEdit = { componentId?: string; componentTag?: string; menuId?: string; }; @Route("v1/permission/menu-component") @Tags("Permission") @Security("keycloak") export class MenuComponentController extends Controller { @Get() async listMenuComponent() { const record = await prisma.menuComponent.findMany({ include: { roleMenuComponentPermission: true }, orderBy: { createdAt: "asc" }, }); return record; } @Post() async createMenuComponent(@Body() body: MenuComponentCreate) { const menu = await prisma.menu.findFirst({ where: { id: body.menuId } }); if (!menu) { throw new HttpError( HttpStatus.BAD_REQUEST, "Menu not found.", "missing_or_invalid_parameter", ); } const record = await prisma.menuComponent.create({ data: body, }); this.setStatus(HttpStatus.CREATED); return record; } @Put("{menuComponentId}") async editMenuComponent(@Path("menuComponentId") id: string, @Body() body: MenuComponentEdit) { if (body.menuId) { const menu = await prisma.menu.findFirst({ where: { id: body.menuId } }); if (!menu) { throw new HttpError( HttpStatus.BAD_REQUEST, "Menu not found.", "missing_or_invalid_parameter", ); } } const record = await prisma.menuComponent .update({ include: { roleMenuComponentPermission: true }, where: { id }, data: body, }) .catch((e) => { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { throw new HttpError( HttpStatus.NOT_FOUND, "Menu component cannot be found.", "data_not_found", ); } throw new Error(e); }); return record; } @Delete("{menuComponentId}") async deleteMenuComponent(@Path("menuComponentId") id: string) { const record = await prisma.menuComponent.deleteMany({ where: { id } }); if (record.count <= 0) { throw new HttpError( HttpStatus.NOT_FOUND, "Menu component cannot be found.", "data_not_found", ); } } }