From 52cc72a46fb3dde85c125e61b2a82a4e71f336bd Mon Sep 17 00:00:00 2001 From: GerHerMo Date: Thu, 2 Oct 2025 12:47:24 +0900 Subject: [PATCH 1/2] refactor: edit Dto & Service --- .../domain/chatbot/dto/ChatResponseDto.java | 12 ++++++-- .../chatbot/service/ChatbotService.java | 28 +++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/back/domain/chatbot/dto/ChatResponseDto.java b/src/main/java/com/back/domain/chatbot/dto/ChatResponseDto.java index 59170e8..533eab5 100644 --- a/src/main/java/com/back/domain/chatbot/dto/ChatResponseDto.java +++ b/src/main/java/com/back/domain/chatbot/dto/ChatResponseDto.java @@ -1,5 +1,6 @@ package com.back.domain.chatbot.dto; +import com.back.domain.chatbot.enums.MessageSender; import com.back.domain.chatbot.enums.MessageType; import lombok.AllArgsConstructor; import lombok.Builder; @@ -16,9 +17,12 @@ @Builder public class ChatResponseDto { + private Long id; // 메시지 ID (DB 저장 후 생성) + private Long userId; // 사용자 ID private String message; // 텍스트 메시지 + private MessageSender sender; // 메시지 발신자 (USER / CHATBOT) private MessageType type; // 메시지 표시 타입 - private LocalDateTime timestamp; + private LocalDateTime createdAt; // 생성 시간 (timestamp → createdAt으로 변경) // 단계별 추천 관련 데이터 (type이 RADIO_OPTIONS 또는 CARD_LIST일 때 사용) private StepRecommendationResponseDto stepData; @@ -30,12 +34,14 @@ public class ChatResponseDto { public ChatResponseDto(String message) { this.message = message; this.type = MessageType.TEXT; - this.timestamp = LocalDateTime.now(); + this.sender = MessageSender.CHATBOT; + this.createdAt = LocalDateTime.now(); } public ChatResponseDto(String message, StepRecommendationResponseDto stepData) { this.message = message; - this.timestamp = LocalDateTime.now(); + this.sender = MessageSender.CHATBOT; + this.createdAt = LocalDateTime.now(); this.stepData = stepData; // stepData 내용에 따라 type 자동 설정 diff --git a/src/main/java/com/back/domain/chatbot/service/ChatbotService.java b/src/main/java/com/back/domain/chatbot/service/ChatbotService.java index 2e35555..4d2b57a 100644 --- a/src/main/java/com/back/domain/chatbot/service/ChatbotService.java +++ b/src/main/java/com/back/domain/chatbot/service/ChatbotService.java @@ -129,9 +129,11 @@ else if (currentStep >= 1 && currentStep <= 4) { String response = generateAIResponse(requestDto); return ChatResponseDto.builder() + .userId(requestDto.getUserId()) .message(response) + .sender(MessageSender.CHATBOT) .type(MessageType.TEXT) - .timestamp(LocalDateTime.now()) + .createdAt(LocalDateTime.now()) .build(); } catch (Exception e) { @@ -254,6 +256,7 @@ public ChatResponseDto createGreetingMessage(Long userId) { // 중복 확인: 동일한 인사말이 이미 존재하는지 확인 boolean greetingExists = chatConversationRepository.existsByUserIdAndMessage(userId, greetingMessage); + ChatConversation savedGreeting = null; // 중복되지 않을 경우에만 DB에 저장 if (!greetingExists) { ChatConversation greeting = ChatConversation.builder() @@ -262,18 +265,21 @@ public ChatResponseDto createGreetingMessage(Long userId) { .sender(MessageSender.CHATBOT) .createdAt(LocalDateTime.now()) .build(); - chatConversationRepository.save(greeting); + savedGreeting = chatConversationRepository.save(greeting); log.info("인사말 저장 완료 - userId: {}", userId); } else { log.info("이미 인사말이 존재하여 저장 생략 - userId: {}", userId); } - // ChatResponseDto 반환 + // ChatResponseDto 반환 (요청된 형식에 맞춰 id, userId, sender, type, createdAt 포함) return ChatResponseDto.builder() + .id(savedGreeting != null ? savedGreeting.getId() : null) + .userId(userId) .message(greetingMessage) + .sender(MessageSender.CHATBOT) .type(MessageType.RADIO_OPTIONS) .stepData(stepData) - .timestamp(LocalDateTime.now()) + .createdAt(LocalDateTime.now()) .build(); } @@ -390,8 +396,9 @@ private String generateAIResponse(ChatRequestDto requestDto) { public ChatResponseDto createLoadingMessage() { return ChatResponseDto.builder() .message("응답을 생성하는 중...") + .sender(MessageSender.CHATBOT) .type(MessageType.LOADING) - .timestamp(LocalDateTime.now()) + .createdAt(LocalDateTime.now()) .metaData(ChatResponseDto.MetaData.builder() .isTyping(true) .build()) @@ -438,9 +445,11 @@ private ChatResponseDto generateAIResponseWithContext(ChatRequestDto requestDto, String response = generateAIResponse(requestDto); return ChatResponseDto.builder() + .userId(requestDto.getUserId()) .message(response) + .sender(MessageSender.CHATBOT) .type(MessageType.TEXT) - .timestamp(LocalDateTime.now()) + .createdAt(LocalDateTime.now()) .metaData(ChatResponseDto.MetaData.builder() .actionType(mode) .currentStep(0) @@ -455,8 +464,9 @@ private ChatResponseDto generateAIResponseWithContext(ChatRequestDto requestDto, private ChatResponseDto createErrorResponse(String errorMessage) { return ChatResponseDto.builder() .message(errorMessage) + .sender(MessageSender.CHATBOT) .type(MessageType.ERROR) - .timestamp(LocalDateTime.now()) + .createdAt(LocalDateTime.now()) .build(); } @@ -517,11 +527,13 @@ private ChatResponseDto handleStepRecommendation(ChatRequestDto requestDto) { .build(); return ChatResponseDto.builder() + .userId(requestDto.getUserId()) .message(message) + .sender(MessageSender.CHATBOT) .type(type) .stepData(stepData) .metaData(metaData) - .timestamp(LocalDateTime.now()) + .createdAt(LocalDateTime.now()) .build(); } From 085112c2403d5c310ee1652f2d33cd341aacc470 Mon Sep 17 00:00:00 2001 From: GerHerMo Date: Thu, 2 Oct 2025 12:55:37 +0900 Subject: [PATCH 2/2] fix: return inner data on chatbot/chat --- .../chatbot/service/ChatbotService.java | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/back/domain/chatbot/service/ChatbotService.java b/src/main/java/com/back/domain/chatbot/service/ChatbotService.java index 4d2b57a..cd4ce25 100644 --- a/src/main/java/com/back/domain/chatbot/service/ChatbotService.java +++ b/src/main/java/com/back/domain/chatbot/service/ChatbotService.java @@ -126,14 +126,15 @@ else if (currentStep >= 1 && currentStep <= 4) { // ========== 3순위: 기본 일반 대화 ========== log.info("[DEFAULT] 일반 대화 모드 - userId: {}", requestDto.getUserId()); - String response = generateAIResponse(requestDto); + ChatConversation savedResponse = generateAIResponse(requestDto); return ChatResponseDto.builder() + .id(savedResponse.getId()) .userId(requestDto.getUserId()) - .message(response) + .message(savedResponse.getMessage()) .sender(MessageSender.CHATBOT) .type(MessageType.TEXT) - .createdAt(LocalDateTime.now()) + .createdAt(savedResponse.getCreatedAt()) .build(); } catch (Exception e) { @@ -172,9 +173,10 @@ private String buildConversationContext(List recentChats) { /** * 대화 저장 - 변경사항: 사용자 메시지와 봇 응답을 각각 별도로 저장 + * @return 저장된 봇 응답 엔티티 (id 포함) */ @Transactional - public void saveConversation(ChatRequestDto requestDto, String response) { + public ChatConversation saveConversation(ChatRequestDto requestDto, String response) { // 1. 사용자 메시지 저장 ChatConversation userMessage = ChatConversation.builder() .userId(requestDto.getUserId()) @@ -191,7 +193,7 @@ public void saveConversation(ChatRequestDto requestDto, String response) { .sender(MessageSender.CHATBOT) .createdAt(LocalDateTime.now()) .build(); - chatConversationRepository.save(botResponse); + return chatConversationRepository.save(botResponse); } /** @@ -356,8 +358,9 @@ private String postProcessResponse(String response, InternalMessageType type) { /** * AI 응답 생성 + * @return 저장된 봇 응답 엔티티 (id 포함) */ - private String generateAIResponse(ChatRequestDto requestDto) { + private ChatConversation generateAIResponse(ChatRequestDto requestDto) { log.info("Normal chat mode for userId: {}", requestDto.getUserId()); // 메시지 타입 감지 (내부 enum 사용) @@ -384,10 +387,8 @@ private String generateAIResponse(ChatRequestDto requestDto) { // 응답 후처리 response = postProcessResponse(response, messageType); - // 대화 저장 - 사용자 메시지와 봇 응답을 각각 저장 - saveConversation(requestDto, response); - - return response; + // 대화 저장 - 사용자 메시지와 봇 응답을 각각 저장하고 저장된 봇 응답 반환 + return saveConversation(requestDto, response); } /** @@ -442,14 +443,15 @@ private boolean isStepRecommendationTrigger(String message) { * 일반 대화와 구분하여 추천에 특화된 응답 생성 */ private ChatResponseDto generateAIResponseWithContext(ChatRequestDto requestDto, String mode) { - String response = generateAIResponse(requestDto); + ChatConversation savedResponse = generateAIResponse(requestDto); return ChatResponseDto.builder() + .id(savedResponse.getId()) .userId(requestDto.getUserId()) - .message(response) + .message(savedResponse.getMessage()) .sender(MessageSender.CHATBOT) .type(MessageType.TEXT) - .createdAt(LocalDateTime.now()) + .createdAt(savedResponse.getCreatedAt()) .metaData(ChatResponseDto.MetaData.builder() .actionType(mode) .currentStep(0) @@ -518,6 +520,24 @@ private ChatResponseDto handleStepRecommendation(ChatRequestDto requestDto) { type = MessageType.RADIO_OPTIONS; } + // 사용자 메시지 저장 (단계별 추천 요청) + ChatConversation userMessage = ChatConversation.builder() + .userId(requestDto.getUserId()) + .message(requestDto.getMessage()) + .sender(MessageSender.USER) + .createdAt(LocalDateTime.now()) + .build(); + chatConversationRepository.save(userMessage); + + // 봇 응답 저장 + ChatConversation botResponse = ChatConversation.builder() + .userId(requestDto.getUserId()) + .message(message) + .sender(MessageSender.CHATBOT) + .createdAt(LocalDateTime.now()) + .build(); + ChatConversation savedResponse = chatConversationRepository.save(botResponse); + // 메타데이터 포함 ChatResponseDto.MetaData metaData = ChatResponseDto.MetaData.builder() .currentStep(currentStep) @@ -527,13 +547,14 @@ private ChatResponseDto handleStepRecommendation(ChatRequestDto requestDto) { .build(); return ChatResponseDto.builder() + .id(savedResponse.getId()) .userId(requestDto.getUserId()) .message(message) .sender(MessageSender.CHATBOT) .type(type) .stepData(stepData) .metaData(metaData) - .createdAt(LocalDateTime.now()) + .createdAt(savedResponse.getCreatedAt()) .build(); }