import { Body, Controller, Delete, Get, Path, Post, Put, Query, Request, Route, Security, Tags, } from "tsoa"; import { RequestWithUser } from "../interfaces/user"; import HttpStatus from "../interfaces/http-status"; import prisma from "../db"; import { Prisma } from "@prisma/client"; import { queryOrNot } from "../utils/relation"; import { notFoundError } from "../utils/error"; import dayjs from "dayjs"; import HttpError from "../interfaces/http-error"; import { createPermCondition } from "../services/permission"; type NotificationCreate = {}; type NotificationUpdate = {}; const permissionCondCompany = createPermCondition((_) => true); @Route("/api/v1/notification") @Tags("Notification") export class NotificationController extends Controller { @Get() @Security("keycloak") async getNotificationList( @Request() req: RequestWithUser, @Query() page: number = 1, @Query() pageSize: number = 30, @Query() query = "", ) { const where: Prisma.NotificationWhereInput = { AND: [ { OR: queryOrNot<(typeof where)[]>(query, [ { title: { contains: query } }, { detail: { contains: query } }, ]), }, { OR: [ { receiverId: req.user.sub }, req.user.roles.length > 0 ? { groupReceiver: { some: { name: { in: req.user.roles } } }, registeredBranch: { OR: permissionCondCompany(req.user) }, } : {}, ], }, ], NOT: { readByUser: { some: { id: req.user.sub } }, createdAt: dayjs().subtract(7, "days").toDate(), }, }; const [result, total] = await prisma.$transaction([ prisma.notification.findMany({ where, include: { readByUser: true } }), prisma.notification.count({ where }), ]); return { result: result.map((v) => ({ id: v.id, title: v.title, detail: v.detail, createdAt: v.createdAt, read: v.readByUser.some((v) => v.id === req.user.sub), })), page, pageSize, total, }; } @Get("{notificationId}") @Security("keycloak") async getNotification(@Request() req: RequestWithUser, @Path() notificationId: string) { const record = await prisma.notification.update({ where: { id: notificationId }, data: { readByUser: { connect: { id: req.user.sub }, }, }, }); if (!record) throw notFoundError("Notification"); return record; } @Post() @Security("keycloak") async createNotification(@Request() req: RequestWithUser, @Body() body: NotificationCreate) { // TODO: implement // this.setStatus(HttpStatus.CREATED); throw new HttpError(HttpStatus.NOT_IMPLEMENTED, "Not implemented.", "notImplemented"); } @Put("{notificationId}") @Security("keycloak") async updateNotification( @Request() req: RequestWithUser, @Path() notificationId: string, @Body() body: NotificationUpdate, ) { // TODO: implement throw new HttpError(HttpStatus.NOT_IMPLEMENTED, "Not implemented.", "notImplemented"); } @Delete("{notificationId}") @Security("keycloak") async deleteNotification(@Request() req: RequestWithUser, @Path() notificationId: string) { const record = await prisma.notification.deleteMany({ where: { id: notificationId } }); if (record.count === 0) throw notFoundError("Notification"); return record; } }