-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* [FEAT] 채팅 기능 추 * [FEAT] 채팅방 종료시 접근할 수 없도록 로직 추가 * [FEAT] 채팅방 참가 및 퇴장시 로직 추가 * [FEAT] Session 관리를 위한 ConcurrentHashMap Repository 추 * [FEAT] 채팅방 상세 데이터 조회, 채팅 생성 로직 구현 * [FEAT] 채팅방 전체 리스트 조회 구현 * [FEAT] Swagger 추가
- Loading branch information
Showing
27 changed files
with
739 additions
and
2 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
src/main/java/io/oeid/mogakgo/common/swagger/template/ChatSwagger.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package io.oeid.mogakgo.common.swagger.template; | ||
|
||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; | ||
|
||
import io.oeid.mogakgo.core.properties.swagger.error.SwaggerChatErrorExamples; | ||
import io.oeid.mogakgo.core.properties.swagger.error.SwaggerProjectErrorExamples; | ||
import io.oeid.mogakgo.core.properties.swagger.error.SwaggerUserErrorExamples; | ||
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomDataRes; | ||
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomPublicRes; | ||
import io.oeid.mogakgo.exception.dto.ErrorResponse; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import io.swagger.v3.oas.annotations.enums.ParameterIn; | ||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.ExampleObject; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import java.util.List; | ||
import org.springframework.http.ResponseEntity; | ||
|
||
@Tag(name = "Chat", description = "채팅 관련 API") | ||
@SuppressWarnings("unused") | ||
public interface ChatSwagger { | ||
|
||
@Operation(summary = "채팅방 목록 조회", description = "사용자의 채팅방 목록을 조회하는 API") | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "채팅방 목록 조회 성공"), | ||
@ApiResponse(responseCode = "404", description = "요청한 유저가 존재하지 않음", | ||
content = @Content( | ||
mediaType = APPLICATION_JSON_VALUE, | ||
schema = @Schema(implementation = ErrorResponse.class), | ||
examples = @ExampleObject(name = "E020301", value = SwaggerUserErrorExamples.USER_NOT_FOUND) | ||
)) | ||
}) | ||
ResponseEntity<List<ChatRoomPublicRes>> getChatRoomList(@Parameter(hidden = true) Long userId); | ||
|
||
@Operation(summary = "채팅방 상세 조회", description = "채팅방의 상세 정보를 조회하는 API") | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "채팅방 상세 조회 성공"), | ||
@ApiResponse(responseCode = "404", description = "요청한 데이터가 유효하지 않음", | ||
content = @Content( | ||
mediaType = APPLICATION_JSON_VALUE, | ||
schema = @Schema(implementation = ErrorResponse.class), | ||
examples = { | ||
@ExampleObject(name = "E020301", value = SwaggerUserErrorExamples.USER_NOT_FOUND), | ||
@ExampleObject(name = "E030301", value = SwaggerProjectErrorExamples.PROJECT_NOT_FOUND), | ||
@ExampleObject(name = "E110301", value = SwaggerChatErrorExamples.CHAT_ROOM_NOT_FOUND) | ||
} | ||
)) | ||
}) | ||
ResponseEntity<ChatRoomDataRes> getChatRoomDetailData(@Parameter(hidden = true) Long userId, | ||
@Parameter(in = ParameterIn.PATH) String chatRoomId); | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/io/oeid/mogakgo/core/configuration/WebSocketConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package io.oeid.mogakgo.core.configuration; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.socket.WebSocketHandler; | ||
import org.springframework.web.socket.config.annotation.EnableWebSocket; | ||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; | ||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; | ||
|
||
@Configuration | ||
@RequiredArgsConstructor | ||
@EnableWebSocket | ||
public class WebSocketConfig implements WebSocketConfigurer { | ||
|
||
private final WebSocketHandler webSocketHandler; | ||
|
||
@Override | ||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { | ||
registry.addHandler(webSocketHandler, "/ws/chat").setAllowedOrigins("*"); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/io/oeid/mogakgo/core/properties/swagger/error/SwaggerChatErrorExamples.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package io.oeid.mogakgo.core.properties.swagger.error; | ||
|
||
public class SwaggerChatErrorExamples { | ||
|
||
public static final String CHAT_ROOM_NOT_FOUND = "{\"timestamp\":\"2024-02-17T10:07:31.404Z\",\"statusCode\":404,\"code\":\"E110301\",\"message\":\"해당 채팅방이 존재하지 않습니다.\"}"; | ||
|
||
private SwaggerChatErrorExamples() { | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/main/java/io/oeid/mogakgo/domain/chat/application/ChatService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package io.oeid.mogakgo.domain.chat.application; | ||
|
||
import io.oeid.mogakgo.domain.chat.application.dto.req.ChatRoomCreateReq; | ||
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomCreateRes; | ||
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomDataRes; | ||
import io.oeid.mogakgo.domain.chat.application.dto.res.ChatRoomPublicRes; | ||
import io.oeid.mogakgo.domain.chat.entity.document.ChatRoom; | ||
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRepository; | ||
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRoomRoomJpaRepository; | ||
import io.oeid.mogakgo.domain.matching.exception.MatchingException; | ||
import io.oeid.mogakgo.domain.project.domain.entity.Project; | ||
import io.oeid.mogakgo.domain.project.exception.ProjectException; | ||
import io.oeid.mogakgo.domain.project.infrastructure.ProjectJpaRepository; | ||
import io.oeid.mogakgo.domain.user.application.UserCommonService; | ||
import io.oeid.mogakgo.domain.user.domain.User; | ||
import io.oeid.mogakgo.exception.code.ErrorCode404; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class ChatService { | ||
|
||
private final UserCommonService userCommonService; | ||
private final ChatRoomRoomJpaRepository chatRoomRepository; | ||
private final ChatRepository chatRepository; | ||
private final ProjectJpaRepository projectRepository; | ||
|
||
// 채팅방 리스트 조회 | ||
// TODO 마지막 채팅 기록 가져오기 구현 | ||
public List<ChatRoomPublicRes> findAllChatRoomByUserId(Long userId) { | ||
userCommonService.getUserById(userId); | ||
return chatRoomRepository.findAllChatRoomByUserId(userId); | ||
} | ||
|
||
// 채팅방 생성 | ||
@Transactional | ||
public ChatRoomCreateRes createChatRoom(Long creatorId, ChatRoomCreateReq request) { | ||
Project project = projectRepository.findById(request.getProjectId()) | ||
.orElseThrow(() -> new MatchingException(ErrorCode404.PROJECT_NOT_FOUND)); | ||
User creator = userCommonService.getUserById(creatorId); | ||
User sender = userCommonService.getUserById(request.getSenderId()); | ||
ChatRoom chatRoom = chatRoomRepository.save( | ||
ChatRoom.builder().project(project).creator(creator).sender(sender).build()); | ||
chatRepository.createCollection(chatRoom.getId()); | ||
return ChatRoomCreateRes.from(chatRoom); | ||
} | ||
|
||
// 채팅방 조회 | ||
public ChatRoomDataRes findAllChatInChatRoom(Long userId, String chatRoomId) { | ||
var user = userCommonService.getUserById(userId); | ||
var chatRoom = chatRoomRepository.findById(chatRoomId) | ||
.orElseThrow(() -> new MatchingException(ErrorCode404.CHAT_ROOM_NOT_FOUND)); | ||
chatRoom.validateContainsUser(user); | ||
var project = projectRepository.findById(chatRoom.getProject().getId()) | ||
.orElseThrow(() -> new ProjectException(ErrorCode404.PROJECT_NOT_FOUND)); | ||
var chatList = chatRepository.findAllByCollection(chatRoomId); | ||
return ChatRoomDataRes.of(project.getMeetingInfo(), chatList); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
src/main/java/io/oeid/mogakgo/domain/chat/application/ChatWebSocketService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package io.oeid.mogakgo.domain.chat.application; | ||
|
||
|
||
import static io.oeid.mogakgo.exception.code.ErrorCode500.CHAT_WEB_SOCKET_ERROR; | ||
|
||
import io.oeid.mogakgo.domain.chat.entity.document.ChatMessage; | ||
import io.oeid.mogakgo.domain.chat.entity.document.ChatRoom; | ||
import io.oeid.mogakgo.domain.chat.entity.enums.ChatStatus; | ||
import io.oeid.mogakgo.domain.chat.exception.ChatException; | ||
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRepository; | ||
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRoomRoomJpaRepository; | ||
import io.oeid.mogakgo.domain.chat.infrastructure.ChatRoomSessionRepository; | ||
import io.oeid.mogakgo.exception.code.ErrorCode400; | ||
import io.oeid.mogakgo.exception.code.ErrorCode404; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.web.socket.TextMessage; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Service | ||
public class ChatWebSocketService { | ||
|
||
private final ChatRoomRoomJpaRepository chatRoomJpaRepository; | ||
private final ChatRepository chatRepository; | ||
private final ChatRoomSessionRepository chatRoomSessionRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public ChatRoom findChatRoomById(String roomId) { | ||
ChatRoom chatRoom = chatRoomJpaRepository.findById(roomId).orElseThrow(() -> new ChatException(ErrorCode404.CHAT_ROOM_NOT_FOUND)); | ||
if(chatRoom.getStatus().equals(ChatStatus.CLOSED)){ | ||
throw new ChatException(ErrorCode400.CHAT_ROOM_CLOSED); | ||
} | ||
return chatRoom; | ||
} | ||
|
||
public void saveChatMessage(ChatMessage chatMessage, String roomId) { | ||
chatRepository.save(chatMessage, roomId); | ||
} | ||
|
||
public void closeChatRoom(String roomId) { | ||
ChatRoom chatRoom = chatRoomJpaRepository.findById(roomId).orElseThrow(() -> new ChatException(ErrorCode404.CHAT_ROOM_NOT_FOUND)); | ||
chatRoomSessionRepository.removeRoom(chatRoom.getId()); | ||
chatRoom.closeChat(); | ||
} | ||
|
||
public void addSessionToRoom(String roomId, WebSocketSession session) { | ||
chatRoomSessionRepository.addSession(roomId, session); | ||
} | ||
|
||
public void removeSessionFromRoom(String roomId, WebSocketSession session) { | ||
chatRoomSessionRepository.removeSession(roomId, session); | ||
} | ||
|
||
public void sendMessageToEachSocket(String roomId, TextMessage textMessage){ | ||
chatRoomSessionRepository.getSession(roomId).forEach(session -> { | ||
try { | ||
session.sendMessage(textMessage); | ||
} catch (Exception e) { | ||
log.error("sendMessageToEachSocket: {}", e.getMessage()); | ||
throw new ChatException(CHAT_WEB_SOCKET_ERROR); | ||
} | ||
}); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/io/oeid/mogakgo/domain/chat/application/dto/req/ChatRoomCreateReq.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package io.oeid.mogakgo.domain.chat.application.dto.req; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public class ChatRoomCreateReq { | ||
private Long projectId; | ||
private Long senderId; | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/io/oeid/mogakgo/domain/chat/application/dto/res/ChatRoomCreateRes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.oeid.mogakgo.domain.chat.application.dto.res; | ||
|
||
import io.oeid.mogakgo.domain.chat.entity.document.ChatRoom; | ||
import io.oeid.mogakgo.domain.chat.entity.enums.ChatStatus; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
public class ChatRoomCreateRes { | ||
|
||
private String roomId; | ||
private Long projectId; | ||
private Long creatorId; | ||
private Long senderId; | ||
private ChatStatus chatStatus; | ||
|
||
private ChatRoomCreateRes(String roomId, Long projectId, Long creatorId, Long senderId, | ||
ChatStatus chatStatus) { | ||
this.roomId = roomId; | ||
this.projectId = projectId; | ||
this.creatorId = creatorId; | ||
this.senderId = senderId; | ||
this.chatStatus = chatStatus; | ||
} | ||
|
||
public static ChatRoomCreateRes from(ChatRoom chatRoom) { | ||
return new ChatRoomCreateRes(chatRoom.getId(), chatRoom.getProject().getId(), | ||
chatRoom.getCreator().getId(), chatRoom.getSender().getId(), chatRoom.getStatus()); | ||
} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/io/oeid/mogakgo/domain/chat/application/dto/res/ChatRoomDataRes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package io.oeid.mogakgo.domain.chat.application.dto.res; | ||
|
||
import io.oeid.mogakgo.domain.chat.application.vo.ChatData; | ||
import io.oeid.mogakgo.domain.chat.application.vo.ChatRoomProjectInfo; | ||
import io.oeid.mogakgo.domain.chat.entity.document.ChatMessage; | ||
import io.oeid.mogakgo.domain.project.domain.entity.vo.MeetingInfo; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.util.List; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Schema(description = "채팅방 데이터 조회 응답") | ||
@Getter | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
@NoArgsConstructor | ||
public class ChatRoomDataRes { | ||
|
||
private ChatRoomProjectInfo project; | ||
private List<ChatData> data; | ||
|
||
public static ChatRoomDataRes of(MeetingInfo meetingInfo, List<ChatMessage> data) { | ||
ChatRoomProjectInfo project = new ChatRoomProjectInfo(meetingInfo.getMeetDetail(), | ||
meetingInfo.getMeetStartTime(), meetingInfo.getMeetEndTime()); | ||
return new ChatRoomDataRes(project, data.stream().map(ChatData::from).toList()); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/io/oeid/mogakgo/domain/chat/application/dto/res/ChatRoomPublicRes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.oeid.mogakgo.domain.chat.application.dto.res; | ||
|
||
import io.oeid.mogakgo.domain.chat.application.vo.ChatUserInfo; | ||
import io.oeid.mogakgo.domain.chat.entity.enums.ChatStatus; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Schema(description = "채팅방 리스트 조회 응답") | ||
@Getter | ||
@AllArgsConstructor | ||
public class ChatRoomPublicRes { | ||
@Schema(description = "프로젝트 ID") | ||
private Long projectId; | ||
@Schema(description = "채팅방 ID") | ||
private String chatRoomId; | ||
@Schema(description = "마지막 메시지") | ||
private String lastMessage; | ||
@Schema(description = "마지막 메시지 생성 시간") | ||
private LocalDateTime lastMessageCreatedAt; | ||
@Schema(description = "채팅방 상태") | ||
private ChatStatus status; | ||
|
||
private List<ChatUserInfo> profiles; | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/io/oeid/mogakgo/domain/chat/application/vo/ChatData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package io.oeid.mogakgo.domain.chat.application.vo; | ||
|
||
import io.oeid.mogakgo.domain.chat.entity.document.ChatMessage; | ||
import io.oeid.mogakgo.domain.chat.entity.enums.ChatMessageType; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDateTime; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Schema(description = "채팅 데이터") | ||
@Getter | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class ChatData { | ||
|
||
@Schema(description = "메시지 타입") | ||
private ChatMessageType messageType; | ||
@Schema(description = "보낸 사람 ID") | ||
private Long senderId; | ||
@Schema(description = "메시지") | ||
private String message; | ||
@Schema(description = "생성 시간") | ||
private LocalDateTime createdAt; | ||
|
||
public static ChatData from(ChatMessage chatMessage) { | ||
return new ChatData(chatMessage.getMessageType(), chatMessage.getSenderId(), | ||
chatMessage.getMessage(), chatMessage.getCreatedAt()); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/io/oeid/mogakgo/domain/chat/application/vo/ChatRoomProjectInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.oeid.mogakgo.domain.chat.application.vo; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDateTime; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Schema(description = "채팅방 프로젝트 정보") | ||
@Getter | ||
@AllArgsConstructor | ||
public class ChatRoomProjectInfo { | ||
|
||
@Schema(description = "프로젝트 설명") | ||
private String meetDetail; | ||
@Schema(description = "프로젝트 시작 시간") | ||
private LocalDateTime meetStartTime; | ||
@Schema(description = "프로젝트 종료 시간") | ||
private LocalDateTime meetEndTime; | ||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/io/oeid/mogakgo/domain/chat/application/vo/ChatUserInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package io.oeid.mogakgo.domain.chat.application.vo; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Schema(description = "채팅방 유저 정보") | ||
@Getter | ||
@AllArgsConstructor | ||
public class ChatUserInfo { | ||
@Schema(description = "유저 ID") | ||
private Long userId; | ||
@Schema(description = "유저 이름") | ||
private String username; | ||
@Schema(description = "유저 프로필 이미지 URL") | ||
private String avatarUrl; | ||
} |
Oops, something went wrong.