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("api/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 RoleMenuPermissionCreate = { userRole: string; permission: string; }; type RoleMenuPermissionEdit = { userRole?: string; permission?: string; }; @Route("api/v1/permission/menu/{menuId}/role") @Tags("Permission") @Security("keycloak") export class RoleMenuController extends Controller { @Get() async listRoleMenu(@Path() menuId: string) { const record = await prisma.roleMenuPermission.findMany({ where: { menuId }, orderBy: [{ userRole: "asc" }, { createdAt: "asc" }], }); return record; } @Post() async createRoleMenu(@Path() menuId: string, @Body() body: RoleMenuPermissionCreate) { const menu = await prisma.menu.findFirst({ where: { id: menuId } }); if (!menu) { throw new HttpError( HttpStatus.BAD_REQUEST, "Menu not found.", "missing_or_invalid_parameter", ); } const record = await prisma.roleMenuPermission.create({ data: Object.assign(body, { menuId }), }); this.setStatus(HttpStatus.CREATED); return record; } @Put("{roleMenuId}") async editRoleMenu( @Path("roleMenuId") id: string, @Path() menuId: string, @Body() body: RoleMenuPermissionEdit, ) { const record = await prisma.roleMenuPermission .update({ where: { id, menuId }, data: body, }) .catch((e) => { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { throw new HttpError(HttpStatus.NOT_FOUND, "Role menu cannot be found.", "data_not_found"); } throw new Error(e); }); return record; } @Delete("{roleMenuId}") async deleteRoleMenu(@Path("roleMenuId") id: string, @Path() menuId: string) { const record = await prisma.roleMenuPermission.deleteMany({ where: { id, menuId }, }); if (record.count <= 0) { throw new HttpError(HttpStatus.NOT_FOUND, "Role menu cannot be found.", "data_not_found"); } } } type MenuComponentCreate = { componentId: string; componentTag: string; menuId: string; }; type MenuComponentEdit = { componentId?: string; componentTag?: string; menuId?: string; }; @Route("api/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", ); } } } type RoleMenuComponentPermissionCreate = { userRole: string; permission: string; }; type RoleMenuComponentPermissionEdit = { userRole?: string; permission?: string; }; @Route("api/v1/permission/menu-component/{menuComponentId}/role") @Tags("Permission") @Security("keycloak") export class RoleMenuComponentController extends Controller { @Get() async listRoleMenuComponent(@Path() menuComponentId: string) { const record = await prisma.roleMenuComponentPermission.findMany({ where: { menuComponentId }, orderBy: [{ userRole: "asc" }, { createdAt: "asc" }], }); return record; } @Post() async createRoleMenuComponent( @Path() menuComponentId: string, @Body() body: RoleMenuComponentPermissionCreate, ) { const menu = await prisma.menuComponent.findFirst({ where: { id: menuComponentId } }); if (!menu) { throw new HttpError( HttpStatus.BAD_REQUEST, "Menu not found.", "missing_or_invalid_parameter", ); } const record = await prisma.roleMenuComponentPermission.create({ data: Object.assign(body, { menuComponentId }), }); this.setStatus(HttpStatus.CREATED); return record; } @Put("{roleMenuComponentId}") async editRoleMenuComponent( @Path("roleMenuComponentId") id: string, @Path() menuComponentId: string, @Body() body: RoleMenuComponentPermissionEdit, ) { const record = await prisma.roleMenuComponentPermission .update({ where: { id, menuComponentId }, data: body, }) .catch((e) => { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { throw new HttpError( HttpStatus.NOT_FOUND, "Role menu component cannot be found.", "data_not_found", ); } throw new Error(e); }); return record; } @Delete("{roleMenuComponentId}") async deleteRoleMenuComponent( @Path("roleMenuComponentId") id: string, @Path() menuComponentId: string, ) { const record = await prisma.roleMenuComponentPermission.deleteMany({ where: { id, menuComponentId }, }); if (record.count <= 0) { throw new HttpError( HttpStatus.NOT_FOUND, "Role menu component cannot be found.", "data_not_found", ); } } }