From b0b784836e2d216fc7cf3efb309adafb99cbb521 Mon Sep 17 00:00:00 2001 From: avicenan Date: Fri, 22 May 2026 15:30:05 +0900 Subject: [PATCH] fix medical form --- src/controllers/file/file.ts | 5 +++-- src/controllers/medical_form.ts | 38 ++++++++++++++++++++++----------- src/controllers/room.ts | 27 ++++++++++++++++++----- src/swagger/builder.js | 4 ++++ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/controllers/file/file.ts b/src/controllers/file/file.ts index 822dd1a..1466b8e 100644 --- a/src/controllers/file/file.ts +++ b/src/controllers/file/file.ts @@ -57,9 +57,9 @@ export class FileController { } // Validate file type - const allowedMimes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']; + const allowedMimes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/svg+xml', 'image/svg']; if (!allowedMimes.includes(file.mimetype)) { - return ReturnHelper.errorResponse(res, 400, 400, Language.lang.failed_insert, "Invalid file type. Only JPG, PNG, and WEBP are allowed"); + return ReturnHelper.errorResponse(res, 400, 400, Language.lang.failed_insert, "Invalid file type. Only JPG, PNG, WEBP, and SVG are allowed"); } const ext = file.name.split('.'); const name = uuidv4() + '.' + ext[ext.length - 1]; @@ -190,6 +190,7 @@ export class FileController { webp: "image/webp", gif: "image/gif", pdf: "application/pdf", + svg: "image/svg+xml", }; const contentType = mimeMap[ext ?? ""] ?? "application/octet-stream"; diff --git a/src/controllers/medical_form.ts b/src/controllers/medical_form.ts index 38a20a1..fdca118 100644 --- a/src/controllers/medical_form.ts +++ b/src/controllers/medical_form.ts @@ -72,16 +72,19 @@ export class MedicalFormController { static async create(req: Request, res: Response, next: NextFunction): Promise { /* - #swagger.tags = ['Medical Form'] - #swagger.security = [{ "bearerAuth": [] }] - #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/medical_form" } } } } - */ + #swagger.tags = ['Medical Form'] + #swagger.security = [{ "bearerAuth": [] }] + #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/medical_form" } } } } + */ const queryRunner = OrmHelper.DB.createQueryRunner(); await queryRunner.startTransaction(); try { const schema = Joi.object().keys({ + title: Joi.string().max(256).required().label("Title"), name: Joi.string().max(256).required().label("Name"), description: Joi.string().max(512).required().label("Description"), + picture: Joi.string().max(512).allow("").optional().label("Picture"), + status: Joi.string().max(64).required().label("Status"), }); let param: any = await schema.validateAsync(req.body); @@ -91,8 +94,11 @@ export class MedicalFormController { if (exist) throw { message: "Medical Form " + Language.lang.failed_duplicate }; let medicalForm = new MedicalForm(); + medicalForm.title = param.title; medicalForm.name = param.name; medicalForm.description = param.description; + medicalForm.picture = param.picture || null; + medicalForm.status = param.status; medicalForm.created_by = req.auth.data.name; medicalForm.updated_by = req.auth.data.name; await queryRunner.manager.save(medicalForm); @@ -112,10 +118,10 @@ export class MedicalFormController { static async detail(req: Request, res: Response, next: NextFunction): Promise { /* - #swagger.tags = ['Medical Form'] - #swagger.security = [{ "bearerAuth": [] }] - #swagger.parameters['id'] = { description: '', in: 'path', type: 'string' } - */ + #swagger.tags = ['Medical Form'] + #swagger.security = [{ "bearerAuth": [] }] + #swagger.parameters['id'] = { description: '', in: 'path', type: 'string' } + */ try { const schema = Joi.object().keys({ id: Joi.string().uuid().required().label("Medical Form Id"), @@ -137,11 +143,11 @@ export class MedicalFormController { static async update(req: Request, res: Response, next: NextFunction): Promise { /* - #swagger.tags = ['Medical Form'] - #swagger.security = [{ "bearerAuth": [] }] - #swagger.parameters['id'] = { description: '', in: 'path', type: 'string' } - #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/medical_form" } } } } - */ + #swagger.tags = ['Medical Form'] + #swagger.security = [{ "bearerAuth": [] }] + #swagger.parameters['id'] = { description: '', in: 'path', type: 'string' } + #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/medical_form" } } } } + */ const queryRunner = OrmHelper.DB.createQueryRunner(); await queryRunner.startTransaction(); @@ -150,8 +156,11 @@ export class MedicalFormController { const schema = Joi.object().keys({ id: Joi.string().uuid().required().label("Medical Form ID"), + title: Joi.string().max(256).required().label("Title"), name: Joi.string().max(256).required().label("Name"), description: Joi.string().max(512).required().label("Description"), + picture: Joi.string().max(512).allow("").optional().label("Picture"), + status: Joi.string().max(64).required().label("Status"), }); let param: any = await schema.validateAsync(req.body); @@ -164,8 +173,11 @@ export class MedicalFormController { if (!medicalForm) throw { message: "Medical Form " + Language.lang.failed_not_found }; + medicalForm.title = param.title; medicalForm.name = param.name; medicalForm.description = param.description; + medicalForm.picture = param.picture || null; + medicalForm.status = param.status; medicalForm.updated_by = req.auth.data.name; await queryRunner.manager.save(medicalForm); diff --git a/src/controllers/room.ts b/src/controllers/room.ts index c7fff33..e504905 100644 --- a/src/controllers/room.ts +++ b/src/controllers/room.ts @@ -1,4 +1,4 @@ -import { Room, Paging, Service } from "entity"; +import { Room, Paging, Service, MedicalForm } from "entity"; import { NextFunction, Response } from "express"; import { Request } from "express-jwt"; import Joi from "joi"; @@ -15,7 +15,7 @@ import fileUpload from "express-fileupload"; import { v4 as uuidv4 } from "uuid"; import fs from "fs"; import path from "path"; -import { Brackets } from "typeorm"; +import { Brackets, In } from "typeorm"; import config from "../../config/stag.json"; const log: Logger = new Logger({ @@ -78,6 +78,7 @@ export class RoomController { const res_list = query .leftJoinAndSelect("Room.department", "department") .leftJoinAndSelect("Room.serviceclass", "serviceclass") + .leftJoinAndSelect("Room.medical_forms", "medical_forms") .orderBy("Room." + param.order_field, param.order_direction) .offset(offset) .limit(param.limit); @@ -167,6 +168,7 @@ export class RoomController { location: Joi.string().required().label("Location"), floor: Joi.number().required().label("Floor"), picture: Joi.string().required().label("picture"), + medical_forms: Joi.array().items(Joi.string().uuid()).optional().label("Medical Forms"), }); let param: any = await schema.validateAsync(req.body); @@ -180,6 +182,12 @@ export class RoomController { let serviceclass = await ServiceClassModel.list({ id: param.serviceclass }).then((q) => q.getOne()); if (!serviceclass) throw { message: "Class not found" }; + let medicalForms: MedicalForm[] = []; + if (param.medical_forms && param.medical_forms.length > 0) { + medicalForms = await queryRunner.manager.getRepository(MedicalForm).find({ where: { id: In(param.medical_forms) } }); + if (medicalForms.length !== param.medical_forms.length) throw { message: "Medical Form not found" }; + } + let room = new Room(); room.room = param.room; room.code = param.code; @@ -190,6 +198,7 @@ export class RoomController { room.location = param.location; room.picture = param.picture; room.floor = param.floor; + room.medical_forms = medicalForms; room.created_by = req.auth?.data.name; room.updated_by = req.auth?.data.name; await queryRunner.manager.save(room); @@ -217,7 +226,7 @@ export class RoomController { id: Joi.string().uuid().required().label("Room Id"), }); let param: any = await schema.validateAsync(req.params); - let room = await RoomModel.list({ "Room.id": param.id }).then((q) => q.leftJoinAndSelect("Room.department", "department").leftJoinAndSelect("Room.serviceclass", "serviceclass").getOne()); + let room = await RoomModel.list({ "Room.id": param.id }).then((q) => q.leftJoinAndSelect("Room.department", "department").leftJoinAndSelect("Room.serviceclass", "serviceclass").leftJoinAndSelect("Room.medical_forms", "medical_forms").getOne()); if (!room) throw { message: "Room Not Found" }; return ReturnHelper.successResponseAny(res, 200, Language.lang.success_view, room); } catch (e: unknown) { @@ -249,6 +258,7 @@ export class RoomController { status: Joi.string().required().label("Status"), location: Joi.string().required().label("Location"), picture: Joi.string().required().label("picture"), + medical_forms: Joi.array().items(Joi.string().uuid()).optional().label("Medical Forms"), }); let param: any = await schema.validateAsync(req.body); @@ -264,6 +274,12 @@ export class RoomController { let room = await RoomModel.list({ "Room.id": param.id }).then((q) => q.getOne()); if (!room) throw { message: "Room " + Language.lang.failed_not_found }; + let medicalForms: MedicalForm[] = []; + if (param.medical_forms && param.medical_forms.length > 0) { + medicalForms = await queryRunner.manager.getRepository(MedicalForm).find({ where: { id: In(param.medical_forms) } }); + if (medicalForms.length !== param.medical_forms.length) throw { message: "Medical Form not found" }; + } + room.room = param.room; room.code = param.code; room.description = param.description || null; @@ -273,6 +289,7 @@ export class RoomController { room.floor = param.floor; room.location = param.location; room.picture = param.picture; + room.medical_forms = medicalForms; room.updated_by = req.auth?.data.name; await queryRunner.manager.save(room); @@ -400,9 +417,9 @@ export class RoomController { } // Validate file type - const allowedMimes = ["image/jpeg", "image/jpg", "image/png", "image/webp"]; + const allowedMimes = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/svg+xml", "image/svg"]; if (!allowedMimes.includes(file.mimetype)) { - return ReturnHelper.errorResponse(res, 400, 400, Language.lang.failed_insert, "Invalid file type. Only JPG, PNG, and WEBP are allowed"); + return ReturnHelper.errorResponse(res, 400, 400, Language.lang.failed_insert, "Invalid file type. Only JPG, PNG, WEBP, and SVG are allowed"); } // Normalize path diff --git a/src/swagger/builder.js b/src/swagger/builder.js index 67cdde0..7e63986 100644 --- a/src/swagger/builder.js +++ b/src/swagger/builder.js @@ -132,6 +132,7 @@ const doc = { $status: "Y", $location: "Room location", $picture: "Room picture name", + medical_forms: ["uuid-string"], }, room_number: { $number: "101", @@ -215,8 +216,11 @@ const doc = { $status: { "@enum": ["Y", "N"] }, }, medical_form: { + $title: "Form title", $name: "Form name", $description: "Form description", + picture: "Form picture path", + $status: "Y", }, referenceRange: { $gender: { "@enum": ["male", "female"] },