From 4b3463e97c43d15e93023b36c5ae3b03dd25f741 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 8 Aug 2025 16:39:12 +0900 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=A0=84=EC=86=A1=20API=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room/controller/ChatRoomController.kt | 19 +++ .../sodalive/chat/room/dto/ChatRoomDto.kt | 41 ++++++ .../CharacterChatParticipantRepository.kt | 8 ++ .../chat/room/service/ChatRoomService.kt | 130 ++++++++++++++++++ 4 files changed, 198 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/controller/ChatRoomController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/controller/ChatRoomController.kt index 7be88a4..6f6f10b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/controller/ChatRoomController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/controller/ChatRoomController.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.chat.room.controller import kr.co.vividnext.sodalive.chat.room.dto.CreateChatRoomRequest +import kr.co.vividnext.sodalive.chat.room.dto.SendChatMessageRequest import kr.co.vividnext.sodalive.chat.room.service.ChatRoomService import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.common.SodaException @@ -116,4 +117,22 @@ class ChatRoomController( chatRoomService.leaveChatRoom(member, chatRoomId) ApiResponse.ok(true) } + + /** + * 채팅방 메시지 전송 API + * - 참여 여부 검증(미참여시 "잘못된 접근입니다") + * - 외부 API 호출 (/api/chat, POST) 재시도 최대 3회 + * - 성공 시 내 메시지/캐릭터 메시지 저장 후 캐릭터 메시지 리스트 반환 + */ + @PostMapping("/{chatRoomId}/send") + fun sendMessage( + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, + @PathVariable chatRoomId: Long, + @RequestBody request: SendChatMessageRequest + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + if (member.auth == null) throw SodaException("본인인증을 하셔야 합니다.") + + ApiResponse.ok(chatRoomService.sendMessage(member, chatRoomId, request.message)) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/dto/ChatRoomDto.kt b/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/dto/ChatRoomDto.kt index 60ffe61..79bd7cb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/dto/ChatRoomDto.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/dto/ChatRoomDto.kt @@ -93,3 +93,44 @@ data class ExternalCharacterData( val age: String, val gender: String ) + +/** + * 채팅 메시지 전송 요청 DTO + */ +data class SendChatMessageRequest( + val message: String +) + +/** + * 채팅 메시지 전송 응답 DTO (캐릭터 메시지 리스트) + */ +data class SendChatMessageResponse( + val characterMessages: List +) + +/** + * 외부 API 채팅 전송 응답 DTO + */ +data class ExternalChatSendResponse( + val success: Boolean, + val message: String?, + val data: ExternalChatSendData? +) + +/** + * 외부 API 채팅 전송 데이터 DTO + */ +data class ExternalChatSendData( + val sessionId: String, + val characterResponse: ExternalCharacterMessage +) + +/** + * 외부 API 캐릭터 메시지 DTO + */ +data class ExternalCharacterMessage( + val id: String, + val content: String, + val timestamp: String, + val messageType: String +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/repository/CharacterChatParticipantRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/repository/CharacterChatParticipantRepository.kt index edd5e60..3d4f144 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/repository/CharacterChatParticipantRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/chat/room/repository/CharacterChatParticipantRepository.kt @@ -18,6 +18,14 @@ interface CharacterChatParticipantRepository : JpaRepository