From c52dcb679e24c4fe264ce367a88de02dc93a7c19 Mon Sep 17 00:00:00 2001 From: choubung Date: Wed, 29 Oct 2025 17:13:25 +0900 Subject: [PATCH] =?UTF-8?q?feat(coach):=20=EB=AA=A8=EB=93=A0=20=EB=8C=80?= =?UTF-8?q?=ED=99=94=20=ED=9E=88=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/finz/controller/CoachController.java | 12 ++++++++ .../domain/coach/CoachMessageRepository.java | 2 ++ .../com/finz/dto/coach/CoachMessageDto.java | 30 +++++++++++++++++++ .../java/com/finz/service/CoachService.java | 15 +++++++++- 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/finz/dto/coach/CoachMessageDto.java diff --git a/src/main/java/com/finz/controller/CoachController.java b/src/main/java/com/finz/controller/CoachController.java index f0c8816..6aab351 100644 --- a/src/main/java/com/finz/controller/CoachController.java +++ b/src/main/java/com/finz/controller/CoachController.java @@ -9,6 +9,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import com.finz.dto.coach.CoachMessageDto; +import java.util.List; @Slf4j @RestController @@ -41,4 +43,14 @@ public ResponseEntity sendMessage(@RequestBody MessageRequest CoachResponseDto response = coachService.generateResponse(DEFAULT_USER_ID, request); return ResponseEntity.ok(response); } + + // 그간의 대화 내역 조회 + @GetMapping("/history") + @Operation(summary = "대화 내역 조회", description = "AI 코치와의 전체 대화 내역을 조회합니다.") + public ResponseEntity> getChatHistory() { + log.info("대화 내역 조회 요청 - userId: {}", DEFAULT_USER_ID); + + List history = coachService.getChatHistory(DEFAULT_USER_ID); + return ResponseEntity.ok(history); + } } diff --git a/src/main/java/com/finz/domain/coach/CoachMessageRepository.java b/src/main/java/com/finz/domain/coach/CoachMessageRepository.java index 29c8542..16bd3ee 100644 --- a/src/main/java/com/finz/domain/coach/CoachMessageRepository.java +++ b/src/main/java/com/finz/domain/coach/CoachMessageRepository.java @@ -11,4 +11,6 @@ public interface CoachMessageRepository extends JpaRepository findTop20ByUserIdOrderByCreatedAtDesc(Long userId); + // 채팅방 입장 시 '전체' 대화 내역을 불러오기 위한 메서드 (시간 오름차순) + List findByUserIdOrderByCreatedAtAsc(Long userId); } diff --git a/src/main/java/com/finz/dto/coach/CoachMessageDto.java b/src/main/java/com/finz/dto/coach/CoachMessageDto.java new file mode 100644 index 0000000..02d875c --- /dev/null +++ b/src/main/java/com/finz/dto/coach/CoachMessageDto.java @@ -0,0 +1,30 @@ +package com.finz.dto.coach; + +import com.finz.domain.coach.CoachMessage; +import com.finz.domain.coach.MessageSender; +import com.finz.domain.coach.MessageType; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; + +// 과거 채팅 내역 조회용 DTO +@Getter +@Builder +public class CoachMessageDto { + private Long messageId; + private MessageSender sender; + private MessageType messageType; + private String content; + private LocalDateTime createdAt; + + public static CoachMessageDto fromEntity(CoachMessage entity) { + return CoachMessageDto.builder() + .messageId(entity.getMessageId()) + .sender(entity.getSender()) + .messageType(entity.getMessageType()) + .content(entity.getContent()) + .createdAt(entity.getCreatedAt()) + .build(); + } +} diff --git a/src/main/java/com/finz/service/CoachService.java b/src/main/java/com/finz/service/CoachService.java index a4f9727..576dc5c 100644 --- a/src/main/java/com/finz/service/CoachService.java +++ b/src/main/java/com/finz/service/CoachService.java @@ -33,7 +33,20 @@ public class CoachService { private final GoalRepository goalRepository; private final ExpenseRepository expenseRepository; private final GeminiApiClient geminiClient; - + + @Transactional(readOnly = true) // 데이터 변경이 없는 조회 작업 + public List getChatHistory(Long userId) { + log.info("대화 내역 조회 - userId: {}", userId); + + // 1. Repository를 통해 엔티티 조회 (시간 오름차순) + List messages = messageRepository.findByUserIdOrderByCreatedAtAsc(userId); + + // 2. 엔티티 리스트를 DTO 리스트로 변환 + return messages.stream() + .map(CoachMessageDto::fromEntity) // DTO의 팩토리 메서드 사용 + .collect(Collectors.toList()); + } + // 빠른 제안: 목표 설정 대화 시작 @Transactional public CoachResponseDto startGoalSettingConversation(Long userId) {