import { Prisma, Status } from "@prisma/client"; import { Body, Controller, Delete, Get, Path, Post, Put, Query, Request, Route, Tags } from "tsoa"; import { Body, Controller, Delete, Get, Path, Post, Put, Query, Request, Route, Security, Tags, } from "tsoa"; import { RequestWithUser } from "../interfaces/user"; import prisma from "../db"; import minio from "../services/minio"; import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; if (!process.env.MINIO_BUCKET) { throw Error("Require MinIO bucket."); } const MINIO_BUCKET = process.env.MINIO_BUCKET; export type CustomerCreate = { code?: string; status?: Status; customerType: string; customerName: string; customerNameEN: string; }; export type CustomerUpdate = { code?: string; status?: "ACTIVE" | "INACTIVE"; customerType?: string; customerName?: string; customerNameEN?: string; }; function imageLocation(id: string) { return `customer/img-${id}`; } @Route("api/customer") @Tags("Customer") @Security("keycloak") export class CustomerController extends Controller { @Get() async list( @Query() query: string = "", @Query() page: number = 1, @Query() pageSize: number = 30, ) { const where = { OR: [{ customerName: { contains: query } }, { customerNameEN: { contains: query } }], } satisfies Prisma.CustomerWhereInput; const [result, total] = await prisma.$transaction([ prisma.customer.findMany({ where, take: pageSize, skip: (page - 1) * pageSize, }), prisma.customer.count({ where }), ]); return { result: await Promise.all( result.map(async (v) => ({ ...v, imageUrl: await minio.presignedGetObject(MINIO_BUCKET, imageLocation(v.id), 12 * 60 * 60), })), ), page, pageSize, total, }; } @Post() async create(@Request() req: RequestWithUser, @Body() body: CustomerCreate) { const record = await prisma.customer.create({ data: { ...body, createdBy: req.user.name, updateBy: req.user.name, }, }); this.setStatus(HttpStatus.CREATED); return Object.assign(record, { imageUrl: await minio.presignedGetObject( MINIO_BUCKET, imageLocation(record.id), 12 * 60 * 60, ), imageUploadUrl: await minio.presignedPutObject( MINIO_BUCKET, imageLocation(record.id), 12 * 60 * 60, ), }); } }