Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.piuda.callcare.domain.medication.controller;

import com.piuda.callcare.domain.medication.dto.request.MedicationCreateRequest;
import com.piuda.callcare.domain.medication.dto.response.MedicationDetailResponse;
import com.piuda.callcare.domain.medication.dto.response.MedicationGroupItemResponse;
import com.piuda.callcare.domain.medication.dto.response.MedicationResponse;
import com.piuda.callcare.domain.medication.service.command.MedicationCommandService;
import com.piuda.callcare.domain.medication.service.query.MedicationQueryService;
Expand All @@ -11,10 +11,12 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;

@Tag(name = "Medication", description = "약 등록 API")
Expand All @@ -35,12 +37,14 @@ public ResponseEntity<ApiResponse<List<MedicationResponse>>> registerBatch(
return ResponseUtils.created(medicationCommandService.registerBatch(userId, requests));
}

@Operation(summary = "약 상세 정보 조회", description = "약 카드 클릭 시 주의사항/부작용/용법·용량/효능·효과를 반환합니다. DrugInfo 미연결 약은 의약품 정보 필드 null로 반환됩니다.")
@GetMapping("/{medicationId}/detail")
public ResponseEntity<ApiResponse<MedicationDetailResponse>> getDetail(
@Operation(summary = "약물노트 그룹 상세 조회", description = "병원+처방일 그룹 카드 클릭 시 해당 그룹의 약 리스트와 각 약의 메모를 반환합니다. hospitalName/prescriptionDate 미전달 시 null 그룹 조회.")
@GetMapping("/group")
public ResponseEntity<ApiResponse<List<MedicationGroupItemResponse>>> getGroup(
@AuthenticationPrincipal Long userId,
@PathVariable Long medicationId
@RequestParam Long seniorId,
@RequestParam(required = false) String hospitalName,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate prescriptionDate
) {
return ResponseUtils.ok(medicationQueryService.getDetail(userId, medicationId));
return ResponseUtils.ok(medicationQueryService.getGroup(userId, seniorId, hospitalName, prescriptionDate));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.piuda.callcare.domain.medication.converter;

import com.piuda.callcare.domain.druginfo.entity.DrugInfo;
import com.piuda.callcare.domain.medication.dto.response.MedicationDetailResponse;
import com.piuda.callcare.domain.medication.dto.response.MedicationGroupItemResponse;
import com.piuda.callcare.domain.medication.dto.response.MedicationResponse;
import com.piuda.callcare.domain.medication.entity.Medication;
import com.piuda.callcare.domain.medication.entity.MedicationSchedule;
Expand All @@ -13,18 +12,19 @@
@Component
public class MedicationConverter {

// Medication → MedicationDetailResponse (약 상세 조회용, DrugInfo 없으면 전 필드 null)
public MedicationDetailResponse toDetailResponse(Medication medication) {
DrugInfo drugInfo = medication.getDrugInfo();
if (drugInfo == null) {
return new MedicationDetailResponse(medication.getDrugName(), null, null, null, null);
}
return new MedicationDetailResponse(
// Medication → MedicationGroupItemResponse (약물노트 그룹 상세 조회용)
public MedicationGroupItemResponse toGroupItemResponse(Medication medication) {
return new MedicationGroupItemResponse(
medication.getId(),
medication.getDrugName(),
drugInfo.getEfcyQesitm(),
drugInfo.getUseMethodQesitm(),
drugInfo.getAtpnQesitm(),
drugInfo.getSeQesitm()
medication.getDrugType(),
medication.getImageUrl(),
medication.getTimesPerDay(),
medication.getDosagePerTime(),
medication.getStartDate(),
medication.getEndDate(),
medication.getTotalDays(),
medication.getMemo()
);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.piuda.callcare.domain.medication.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;

import java.time.LocalDate;

@Schema(description = "그룹 내 약 단건 응답")
public record MedicationGroupItemResponse(

@Schema(description = "약 ID")
Long medicationId,

@Schema(description = "약 이름")
String drugName,

@Schema(description = "약 종류 (없으면 null)")
String drugType,

@Schema(description = "약 이미지 URL (없으면 null)")
String imageUrl,

@Schema(description = "1일 복용 횟수")
Integer timesPerDay,

@Schema(description = "1회 복용량 (예: 1정, 5ml)")
String dosagePerTime,

@Schema(description = "복용 시작일")
LocalDate startDate,

@Schema(description = "복용 종료일 (없으면 null)")
LocalDate endDate,

@Schema(description = "총 복용 일수 (없으면 null)")
Integer totalDays,

@Schema(description = "메모 — OCR 자동 생성 또는 사용자 직접 입력 (없으면 null)")
String memo
) {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.piuda.callcare.domain.medication.repository;

import java.time.LocalDate;
import java.util.List;

import com.piuda.callcare.domain.medication.entity.Medication;
Expand Down Expand Up @@ -27,4 +28,17 @@ public interface MedicationRepository extends JpaRepository<Medication, Long> {
AND m.isActive = true
""")
List<Medication> findActiveWithDrugInfoBySeniorId(@Param("seniorId") Long seniorId);

// 약물노트 그룹 상세 조회: 병원명 + 처방일 조합이 그룹 키 (둘 다 null 가능)
@Query("""
SELECT m FROM Medication m
WHERE m.senior.id = :seniorId
AND ((:hospitalName IS NULL AND m.hospitalName IS NULL) OR m.hospitalName = :hospitalName)
AND ((:prescriptionDate IS NULL AND m.prescriptionDate IS NULL) OR m.prescriptionDate = :prescriptionDate)
AND m.isActive = true
ORDER BY m.createdAt ASC
""")
List<Medication> findByGroup(@Param("seniorId") Long seniorId,
@Param("hospitalName") String hospitalName,
@Param("prescriptionDate") LocalDate prescriptionDate);
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
package com.piuda.callcare.domain.medication.service.query;

import com.piuda.callcare.domain.medication.converter.MedicationConverter;
import com.piuda.callcare.domain.medication.dto.response.MedicationDetailResponse;
import com.piuda.callcare.domain.medication.dto.response.MedicationGroupItemResponse;
import com.piuda.callcare.domain.medication.entity.Medication;
import com.piuda.callcare.domain.medication.repository.MedicationRepository;
import com.piuda.callcare.domain.senior.repository.SeniorRepository;
import com.piuda.callcare.global.exception.CallCareException;
import com.piuda.callcare.global.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MedicationQueryService {

private final MedicationRepository medicationRepository;
private final SeniorRepository seniorRepository;
private final MedicationConverter medicationConverter;

public MedicationDetailResponse getDetail(Long userId, Long medicationId) {
Medication medication = medicationRepository.findById(medicationId)
.orElseThrow(() -> new CallCareException(ErrorCode.MEDICATION_NOT_FOUND));
if (userId != null && !medication.getSenior().getUser().getId().equals(userId)) {
public List<MedicationGroupItemResponse> getGroup(Long userId, Long seniorId, String hospitalName, LocalDate prescriptionDate) {
if (userId == null) {
throw new CallCareException(ErrorCode.FORBIDDEN);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
return medicationConverter.toDetailResponse(medication);
seniorRepository.findByIdAndUser_Id(seniorId, userId)
.orElseThrow(() -> new CallCareException(ErrorCode.SENIOR_NOT_FOUND));
List<Medication> medications = medicationRepository.findByGroup(seniorId, hospitalName, prescriptionDate);
return medications.stream()
.map(medicationConverter::toGroupItemResponse)
.toList();
}
}