-
Notifications
You must be signed in to change notification settings - Fork 0
feat(chat): add room user summaries #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/product-catalog-bundle
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,18 +4,23 @@ | |
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
| import java.util.function.Function; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import org.springframework.data.domain.Sort; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import com.comatching.chat.domain.dto.ChatRoomResponse; | ||
| import com.comatching.chat.domain.dto.ChatRoomResponse.UserSummary; | ||
| import com.comatching.chat.domain.entity.ChatRoom; | ||
| import com.comatching.chat.domain.repository.ChatMessageRepository; | ||
| import com.comatching.chat.domain.repository.ChatRoomRepository; | ||
| import com.comatching.chat.domain.repository.UnreadCountCondition; | ||
| import com.comatching.chat.domain.service.block.BlockService; | ||
| import com.comatching.chat.infra.client.MemberClient; | ||
| import com.comatching.common.dto.event.matching.MatchingSuccessEvent; | ||
| import com.comatching.common.dto.member.ProfileResponse; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
@@ -29,6 +34,7 @@ public class ChatRoomServiceImpl implements ChatRoomService { | |
| private final ChatRoomRepository chatRoomRepository; | ||
| private final ChatMessageRepository chatMessageRepository; | ||
| private final BlockService blockService; | ||
| private final MemberClient memberClient; | ||
|
|
||
| @Override | ||
| public void createChatRoom(MatchingSuccessEvent event) { | ||
|
|
@@ -62,9 +68,14 @@ public List<ChatRoomResponse> getMyChatRooms(Long memberId) { | |
| .toList(); | ||
|
|
||
| Map<String, Long> unreadCountsByRoom = getUnreadCountsByRoom(visibleRooms, memberId); | ||
| Map<Long, ProfileResponse> profilesByMemberId = getProfilesByMemberId(visibleRooms, memberId); | ||
|
|
||
| return visibleRooms.stream() | ||
| .map(room -> ChatRoomResponse.from(room, unreadCountsByRoom.getOrDefault(room.getId(), 0L))) | ||
| .map(room -> { | ||
| Long otherUserId = getOtherUserId(room, memberId); | ||
| UserSummary otherUser = toUserSummary(otherUserId, profilesByMemberId.get(otherUserId)); | ||
| return ChatRoomResponse.from(room, unreadCountsByRoom.getOrDefault(room.getId(), 0L), otherUser); | ||
| }) | ||
|
Comment on lines
73
to
+78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getMyChatRooms 메서드 내에서 채팅방 목록 조회, 차단된 방 필터링, 안 읽은 메시지 수 조회, 상대방 프로필 조회 등 여러 단계의 비즈니스 로직이 순차적으로 실행되고 있습니다. 각 단계가 private 메서드로 잘 분리되어 있지만, getMyChatRooms 메서드 자체의 책임이 다소 커 보입니다. 이 메서드의 복잡도를 줄이고 가독성을 높이기 위해, 각 단계를 더 명확하게 구분하는 방식으로 리팩토링하거나, 파이프라인 형태의 처리를 고려해볼 수 있습니다. 예를 들어, ChatRoom 객체에 otherUser와 unreadCount를 설정하는 책임을 별도의 도메인 서비스나 팩토리 메서드로 분리하는 것도 방법입니다. |
||
| .toList(); | ||
| } | ||
|
|
||
|
|
@@ -106,6 +117,32 @@ private Map<String, Long> getUnreadCountsByRoom(List<ChatRoom> rooms, Long membe | |
| return chatMessageRepository.countUnreadMessagesByRoom(unreadCountConditions, memberId); | ||
| } | ||
|
|
||
| private Map<Long, ProfileResponse> getProfilesByMemberId(List<ChatRoom> rooms, Long memberId) { | ||
| if (rooms.isEmpty()) { | ||
| return Map.of(); | ||
| } | ||
|
|
||
| List<Long> otherUserIds = rooms.stream() | ||
| .map(room -> getOtherUserId(room, memberId)) | ||
| .distinct() | ||
| .toList(); | ||
|
|
||
| List<ProfileResponse> profiles = memberClient.getProfiles(otherUserIds); | ||
| if (profiles == null || profiles.isEmpty()) { | ||
| return Map.of(); | ||
| } | ||
|
|
||
| return profiles.stream() | ||
| .collect(Collectors.toMap(ProfileResponse::memberId, Function.identity(), (left, right) -> left)); | ||
| } | ||
|
|
||
| private UserSummary toUserSummary(Long memberId, ProfileResponse profile) { | ||
| if (profile == null) { | ||
| return UserSummary.memberOnly(memberId); | ||
| } | ||
| return UserSummary.from(profile); | ||
| } | ||
|
|
||
| private LocalDateTime getMyLastReadAt(ChatRoom room, Long memberId) { | ||
| return memberId.equals(room.getInitiatorUserId()) | ||
| ? room.getInitiatorLastReadAt() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.comatching.chat.infra.client; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import org.springframework.cloud.openfeign.FeignClient; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
|
|
||
| import com.comatching.common.dto.member.ProfileResponse; | ||
|
|
||
| @FeignClient(name = "user-service", path = "/api/internal/users", url = "${user-service.url}") | ||
| public interface MemberClient { | ||
|
|
||
| @PostMapping("/profiles/bulk") | ||
| List<ProfileResponse> getProfiles(@RequestBody List<Long> memberIds); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,9 @@ | ||
| server: | ||
| port: 9003 | ||
|
|
||
| user-service: | ||
| url: http://localhost:9000 | ||
|
|
||
| spring: | ||
| application: | ||
| name: chat-service | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserSummary 레코드가 ChatRoomResponse 내부에 중첩되어 있습니다. 현재는 ChatRoomResponse와 밀접하게 관련되어 있어 문제가 없지만, 향후 다른 DTO에서도 사용자 요약 정보가 필요해질 경우 중복 코드가 발생할 수 있습니다. UserSummary를 별도의 최상위 레코드로 분리하여 재사용성을 높이고 ChatRoomResponse의 응집도를 유지하는 것을 고려해볼 수 있습니다.
References