diff --git a/src/controllers/employee-controller.ts b/src/controllers/employee-controller.ts index c0dfc42..8365cd4 100644 --- a/src/controllers/employee-controller.ts +++ b/src/controllers/employee-controller.ts @@ -38,6 +38,10 @@ function imageLocation(id: string) { return `employee/${id}/profile-image`; } +function attachmentLocation(id: string, filename?: string) { + return `employee/${id}/attachment/${filename}`; +} + type EmployeeCreate = { customerBranchId: string; @@ -774,3 +778,91 @@ export class EmployeeController extends Controller { }); } } +@Route("api/v1/employee/{employeeId}/attachment") +@Tags("Employee") +@Security("keycloak") +export class EmployeeAttachmentController extends Controller { + @Get() + async listAttachment(@Path() employeeId: string) { + const record = await prisma.employee.findFirst({ + where: { id: employeeId }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Employee cannot be found.", "employeeNotFound"); + } + + const list = await new Promise((resolve, reject) => { + const item: string[] = []; + + const stream = minio.listObjectsV2(MINIO_BUCKET, attachmentLocation(employeeId)); + + stream.on("data", (v) => v && v.name && item.push(v.name)); + stream.on("end", () => resolve(item)); + stream.on("error", () => reject(new Error("MinIO error."))); + }); + + return list.map((v) => v.split("/").at(-1) as string); + } + + @Get("{filename}") + async getAttachment( + @Request() req: RequestWithUser, + @Path() employeeId: string, + @Path() filename: string, + ) { + const record = await prisma.employee.findFirst({ + where: { id: employeeId }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Employee cannot be found.", "employeeNotFound"); + } + + return req.res?.redirect( + await minio.presignedGetObject( + MINIO_BUCKET, + attachmentLocation(record.id, filename), + 12 * 60 * 60, + ), + ); + } + + @Put("{filename}") + async addAttachment( + @Request() req: RequestWithUser, + @Path() employeeId: string, + @Path() filename: string, + ) { + const record = await prisma.employee.findFirst({ + where: { id: employeeId }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Employee cannot be found.", "employeeNotFound"); + } + + return req.res?.redirect( + await minio.presignedPutObject( + MINIO_BUCKET, + attachmentLocation(record.id, filename), + 12 * 60 * 60, + ), + ); + } + + @Delete("{filename}") + async deleteAttachment(@Path() employeeId: string, @Path() filename: string) { + const record = await prisma.employee.findFirst({ + where: { id: employeeId }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Employee cannot be found.", "employeeNotFound"); + } + + await minio.removeObject(MINIO_BUCKET, attachmentLocation(record.id, filename), { + forceDelete: true, + }); + } +}