Skip to content

feat(chat): add room user summaries#51

Open
popeye0618 wants to merge 1 commit into
feat/product-catalog-bundlefrom
feat/chat-room-user-summary
Open

feat(chat): add room user summaries#51
popeye0618 wants to merge 1 commit into
feat/product-catalog-bundlefrom
feat/chat-room-user-summary

Conversation

@popeye0618
Copy link
Copy Markdown
Member

개요

채팅방 목록 응답에 상대방 요약 정보를 포함합니다.

@codex

변경 사항

  • chat-service에 user-service bulk profile Feign client를 추가했습니다.
  • ChatRoomResponse에 otherUser 요약 정보를 추가했습니다.
  • 차단된 채팅방을 제외한 뒤 상대 프로필과 안 읽은 메시지 수를 함께 조회합니다.

테스트

  • 테스트를 실행했습니다. ./gradlew :chat-service:test --tests com.comatching.chat.domain.service.chatroom.ChatRoomServiceImplTest
  • 관련 수동 검증을 완료했습니다.
  • 테스트가 필요 없는 변경입니다.

체크리스트

  • 브랜치명이 규칙을 따릅니다.
  • 커밋 메시지가 컨벤션을 따릅니다.
  • 이슈와 PR이 연결되어 있습니다.
  • 작업 완료 후 merge 가능한 상태입니다.

스크린샷 / 참고 자료

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이번 PR은 Feign Client를 도입하여 채팅방 목록 조회 시 상대방의 프로필 정보(닉네임, 이미지, 대학, 나이 등)를 함께 반환하도록 기능을 확장했습니다. 이를 위해 MemberClient를 추가하고 ChatRoomServiceImpl에서 프로필 정보를 벌크로 조회하여 DTO에 매핑하는 로직을 구현했습니다. 리뷰에서는 ChatRoomResponse 내부에 정의된 UserSummary 레코드를 재사용성과 응집도를 위해 별도 파일로 분리할 것과, getMyChatRooms 메서드의 책임이 과도하므로 가독성 및 유지보수성을 위해 로직을 분리하거나 리팩토링할 것을 제안했습니다.

Comment on lines +39 to +60
public record UserSummary(
Long memberId,
String nickname,
String profileImageUrl,
String university,
Integer age
) {
public static UserSummary from(ProfileResponse profile) {
KoreanAge age = KoreanAge.fromBirthDate(profile.birthDate());
return new UserSummary(
profile.memberId(),
profile.nickname(),
profile.profileImageUrl(),
profile.university(),
age != null ? age.getValue() : null
);
}

public static UserSummary memberOnly(Long memberId) {
return new UserSummary(memberId, null, null, null, null);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

UserSummary 레코드가 ChatRoomResponse 내부에 중첩되어 있습니다. 현재는 ChatRoomResponse와 밀접하게 관련되어 있어 문제가 없지만, 향후 다른 DTO에서도 사용자 요약 정보가 필요해질 경우 중복 코드가 발생할 수 있습니다. UserSummary를 별도의 최상위 레코드로 분리하여 재사용성을 높이고 ChatRoomResponse의 응집도를 유지하는 것을 고려해볼 수 있습니다.

References
  1. 클래스와 메서드가 하나의 이유로만 변경되는지 확인합니다. (link)
  2. 중복 로직이 유틸, 공통 컴포넌트, 도메인 메서드로 추출 가능한지 검토합니다. (link)

Comment on lines 73 to +78
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);
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

getMyChatRooms 메서드 내에서 채팅방 목록 조회, 차단된 방 필터링, 안 읽은 메시지 수 조회, 상대방 프로필 조회 등 여러 단계의 비즈니스 로직이 순차적으로 실행되고 있습니다. 각 단계가 private 메서드로 잘 분리되어 있지만, getMyChatRooms 메서드 자체의 책임이 다소 커 보입니다. 이 메서드의 복잡도를 줄이고 가독성을 높이기 위해, 각 단계를 더 명확하게 구분하는 방식으로 리팩토링하거나, 파이프라인 형태의 처리를 고려해볼 수 있습니다. 예를 들어, ChatRoom 객체에 otherUser와 unreadCount를 설정하는 책임을 별도의 도메인 서비스나 팩토리 메서드로 분리하는 것도 방법입니다.

References
  1. 클래스와 메서드가 하나의 이유로만 변경되는지 확인합니다. (link)
  2. 메서드가 과도하게 길지 않은지 (한 가지 책임만 가지는지) 확인합니다. (link)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant