From 80d585fcc240635189f47bb367172e549fb0bc04 Mon Sep 17 00:00:00 2001 From: RedAvocado Date: Tue, 24 Mar 2026 15:12:12 +0700 Subject: [PATCH 1/2] feat(medical-record): view medical record details --- .../repository/EmployeeInfoRepository.java | 3 + .../controller/MedicalRecordController.java | 24 +++++-- .../request/MedicalRecordIdRequest.java | 19 ++++++ .../response/MedicalRecordDetailResponse.java | 64 +++++++++++++++++++ .../GetMedicalRecordDetailService.java | 49 ++++++++++++++ 5 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 hms-api/src/main/java/com/hospital/hms/medical/request/MedicalRecordIdRequest.java create mode 100644 hms-api/src/main/java/com/hospital/hms/medical/response/MedicalRecordDetailResponse.java create mode 100644 hms-api/src/main/java/com/hospital/hms/medical/service/GetMedicalRecordDetailService.java diff --git a/hms-api/src/main/java/com/hospital/hms/employee/repository/EmployeeInfoRepository.java b/hms-api/src/main/java/com/hospital/hms/employee/repository/EmployeeInfoRepository.java index c9a224a..3167c2b 100644 --- a/hms-api/src/main/java/com/hospital/hms/employee/repository/EmployeeInfoRepository.java +++ b/hms-api/src/main/java/com/hospital/hms/employee/repository/EmployeeInfoRepository.java @@ -18,6 +18,9 @@ public interface EmployeeInfoRepository extends JpaRepository findById(UUID id); + @EntityGraph(attributePaths = {"account", "department"}) + Optional findByAccount_Id(UUID id); + @Override @EntityGraph(attributePaths = {"account", "department"}) Page findAll(Specification spec, Pageable pageable); diff --git a/hms-api/src/main/java/com/hospital/hms/medical/controller/MedicalRecordController.java b/hms-api/src/main/java/com/hospital/hms/medical/controller/MedicalRecordController.java index 8874a74..3f90f0c 100644 --- a/hms-api/src/main/java/com/hospital/hms/medical/controller/MedicalRecordController.java +++ b/hms-api/src/main/java/com/hospital/hms/medical/controller/MedicalRecordController.java @@ -2,8 +2,11 @@ import com.hospital.hms.base.api.ApiResponse; import com.hospital.hms.base.response.PaginatedResponse; +import com.hospital.hms.medical.request.MedicalRecordIdRequest; import com.hospital.hms.medical.request.SearchMedicalRecordRequest; +import com.hospital.hms.medical.response.MedicalRecordDetailResponse; import com.hospital.hms.medical.response.MedicalRecordResponse; +import com.hospital.hms.medical.service.GetMedicalRecordDetailService; import com.hospital.hms.medical.service.GetMedicalRecordService; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; @@ -12,10 +15,9 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.UUID; @RestController @RequestMapping("/medical-records") @@ -25,6 +27,7 @@ public class MedicalRecordController { private final GetMedicalRecordService getMedicalRecordService; + private final GetMedicalRecordDetailService getMedicalRecordDetailService; @GetMapping @PreAuthorize("hasAnyRole('ADMIN', 'RECEPTIONIST', 'DOCTOR')") @@ -36,4 +39,17 @@ public ResponseEntity>> get ApiResponse.success(data, "Get medical records successfully", HttpStatus.OK.value()) ); } + + @GetMapping("/{id}") + @PreAuthorize("hasAnyRole('ADMIN', 'RECEPTIONIST', 'DOCTOR')") + public ResponseEntity> getMedicalRecordDetails( + @PathVariable UUID id + ) { + MedicalRecordIdRequest request = new MedicalRecordIdRequest(id); + + MedicalRecordDetailResponse data = getMedicalRecordDetailService.execute(request); + return ResponseEntity.status(HttpStatus.OK).body( + ApiResponse.success(data, "Get medical record detail successfully", HttpStatus.OK.value()) + ); + } } diff --git a/hms-api/src/main/java/com/hospital/hms/medical/request/MedicalRecordIdRequest.java b/hms-api/src/main/java/com/hospital/hms/medical/request/MedicalRecordIdRequest.java new file mode 100644 index 0000000..a22a1dc --- /dev/null +++ b/hms-api/src/main/java/com/hospital/hms/medical/request/MedicalRecordIdRequest.java @@ -0,0 +1,19 @@ +package com.hospital.hms.medical.request; + +import com.hospital.hms.base.request.BaseRequest; +import jakarta.validation.constraints.NotNull; +import lombok.*; +import lombok.experimental.SuperBuilder; + +import java.util.UUID; + +@Getter +@Setter +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class MedicalRecordIdRequest extends BaseRequest { + @NotNull(message = "Id are required ") + private UUID id; +} diff --git a/hms-api/src/main/java/com/hospital/hms/medical/response/MedicalRecordDetailResponse.java b/hms-api/src/main/java/com/hospital/hms/medical/response/MedicalRecordDetailResponse.java new file mode 100644 index 0000000..110054c --- /dev/null +++ b/hms-api/src/main/java/com/hospital/hms/medical/response/MedicalRecordDetailResponse.java @@ -0,0 +1,64 @@ +package com.hospital.hms.medical.response; + +import com.hospital.hms.common.enums.Gender; +import com.hospital.hms.employee.entity.EmployeeInfo; +import com.hospital.hms.medical.entity.MedicalRecord; +import com.hospital.hms.patient.entity.PatientInfo; + +import java.time.LocalDate; + +public record MedicalRecordDetailResponse( + PatientInfoResponse patient, + DoctorSummary doctor, + String description, + String doctorAdvice + +) { + public record PatientInfoResponse( + String fullName, + Gender gender, + LocalDate dob, + String address, + String phone, + String email, + String bloodType, + String allergies + ) { + public static PatientInfoResponse from(PatientInfo patientInfo) { + return new PatientInfoResponse( + patientInfo.getAccount().getFullName(), + patientInfo.getAccount().getGender(), + patientInfo.getAccount().getDob(), + patientInfo.getAccount().getAddress(), + patientInfo.getAccount().getPhone(), + patientInfo.getAccount().getEmail(), + patientInfo.getBloodType(), + patientInfo.getAllergies() + ); + } + } + + public record DoctorSummary( + String fullName, + String departmentName, + String code + ) { + public static DoctorSummary from(EmployeeInfo employeeInfo) { + return new DoctorSummary( + employeeInfo.getAccount().getFullName(), + employeeInfo.getDepartment().getName(), + employeeInfo.getCode() + ); + } + } + + public static MedicalRecordDetailResponse from(MedicalRecord medicalRecord, EmployeeInfo employeeInfo) { + return new MedicalRecordDetailResponse( + PatientInfoResponse.from(medicalRecord.getPatient()), + DoctorSummary.from(employeeInfo), + medicalRecord.getDescription(), + medicalRecord.getDoctorAdvice() + ); + } +} + diff --git a/hms-api/src/main/java/com/hospital/hms/medical/service/GetMedicalRecordDetailService.java b/hms-api/src/main/java/com/hospital/hms/medical/service/GetMedicalRecordDetailService.java new file mode 100644 index 0000000..7383b3d --- /dev/null +++ b/hms-api/src/main/java/com/hospital/hms/medical/service/GetMedicalRecordDetailService.java @@ -0,0 +1,49 @@ +package com.hospital.hms.medical.service; + +import com.hospital.hms.base.service.BaseService; +import com.hospital.hms.employee.entity.EmployeeInfo; +import com.hospital.hms.employee.repository.EmployeeInfoRepository; +import com.hospital.hms.exception.NotFoundException; +import com.hospital.hms.medical.entity.MedicalRecord; +import com.hospital.hms.medical.repository.MedicalRecordRepository; +import com.hospital.hms.medical.request.MedicalRecordIdRequest; +import com.hospital.hms.medical.response.MedicalRecordDetailResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class GetMedicalRecordDetailService extends BaseService { + + private final MedicalRecordRepository medicalRecordRepository; + private final EmployeeInfoRepository employeeInfoRepository; + + @Override + @Transactional(readOnly = true) + public MedicalRecordDetailResponse execute(MedicalRecordIdRequest request) { + return super.execute(request); + } + + @Override + protected MedicalRecordDetailResponse doProcess(MedicalRecordIdRequest request) { + MedicalRecord md = medicalRecordRepository.findById(request.getId()).orElseThrow( + () -> new NotFoundException("Medical record with id: " + request.getId() + " not found") + ); + + EmployeeInfo ei = employeeInfoRepository.findByAccount_Id(md.getDoctor().getId()).orElseThrow( + () -> new NotFoundException("Employee info with id: " + md.getDoctor().getId() + " not found") + ); + + if ( + request.getUserContext().hasRole("DOCTOR") + && !request.getUserContext().getUserId().equals(md.getDoctor().getId()) + ) { + throw new AccessDeniedException("You are not allow to view this medical record"); + } + + + return MedicalRecordDetailResponse.from(md, ei); + } +} From 890f202caa6b635de0132c706cd1a3bf7040c46a Mon Sep 17 00:00:00 2001 From: RedAvocado Date: Tue, 24 Mar 2026 15:12:31 +0700 Subject: [PATCH 2/2] chorus: update use docker by hand --- hms-api/src/main/resources/application.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hms-api/src/main/resources/application.yml b/hms-api/src/main/resources/application.yml index f44ff7b..65b4c09 100644 --- a/hms-api/src/main/resources/application.yml +++ b/hms-api/src/main/resources/application.yml @@ -6,6 +6,10 @@ spring: application: name: Hospital Management System API + docker: + compose: + enabled: false + # ------ MySQL (JPA/Hibernate) ------ datasource: url: jdbc:mysql://localhost:3306/hms_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC