[Feat] 모임 홈 화면에서 유저가 참여중인 모임 방 조회 api#68
Conversation
|
""" Walkthrough진행률이 높은 n개의 참여중인 모임방을 조회하는 새로운 API 엔드포인트( Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller
participant Service
participant UserPort
participant RoomPort
participant Repository
Client->>Controller: GET /rooms/home/joined?userId&Page
Controller->>Service: getHomeJoinedRoomList(query)
Service->>UserPort: getUserNickname(userId)
UserPort-->>Service: nickname
Service->>RoomPort: searchHomeJoinedRooms(userId, today, pageable)
RoomPort->>Repository: searchHomeJoinedRooms(userId, today, pageable)
Repository-->>RoomPort: Page<RoomSearchResult>
RoomPort-->>Service: Page<RoomSearchResult>
Service-->>Controller: RoomGetHomeJoinedListResponse
Controller-->>Client: BaseResponse<RoomGetHomeJoinedListResponse>
Assessment against linked issues
Suggested labels
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (11)
src/main/java/konkuk/thip/room/adapter/out/jpa/RoomJpaEntity.java (1)
10-10: TODO 주석의 문법을 수정하세요."이방에" → "이 방에"로 수정이 필요합니다. 또한 TODO 주석을 더 구체적으로 작성하는 것을 권장합니다.
-//TODO 방에 이방에 참여중인 인원수 추가 +//TODO 이 방에 참여중인 인원수 필드 추가 (participantCount)src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java (1)
13-13: 메서드 파라미터명을 더 일반적으로 변경을 고려하세요.
today파라미터명이 구체적이지만,currentDate나date가 더 일반적이고 재사용 가능한 이름일 수 있습니다.- Page<RoomGetHomeJoinedListResponse.RoomSearchResult> searchHomeJoinedRooms(Long userId, LocalDate today, Pageable pageable); + Page<RoomGetHomeJoinedListResponse.RoomSearchResult> searchHomeJoinedRooms(Long userId, LocalDate currentDate, Pageable pageable);src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepository.java (1)
13-13: RoomQueryPort와 일관성을 위해 파라미터명 통일을 고려하세요.RoomQueryPort에서 제안한 것과 동일하게
today파라미터를currentDate로 변경하여 일관성을 유지하는 것을 권장합니다.- Page<RoomGetHomeJoinedListResponse.RoomSearchResult> searchHomeJoinedRooms(Long userId, LocalDate today, Pageable pageable); + Page<RoomGetHomeJoinedListResponse.RoomSearchResult> searchHomeJoinedRooms(Long userId, LocalDate currentDate, Pageable pageable);src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (2)
24-25: 생성자 의존성 순서 변경 사유를 확인해주세요.
RoomGetHomeJoinedListUseCase와RoomVerifyPasswordUseCase의 순서가 변경되었는데, 특별한 이유가 있는지 확인해주세요. 일관된 순서 유지가 좋겠습니다.
47-48: 페이지 파라미터 검증을 추가하는 것을 고려해보세요.현재
@RequestParam("page")만으로는 음수나 0 값에 대한 검증이 없습니다.@Min(1)같은 validation 어노테이션 추가를 고려해보세요.-public BaseResponse<RoomGetHomeJoinedListResponse> getHomeJoinedRooms(@UserId final Long userId, - @RequestParam("page") final int page) { +public BaseResponse<RoomGetHomeJoinedListResponse> getHomeJoinedRooms(@UserId final Long userId, + @RequestParam("page") @Min(1) final int page) {src/main/java/konkuk/thip/room/application/service/RoomGetHomeJoinedListService.java (2)
43-43: LocalDate.now() 사용 시 테스트 가능성을 고려해보세요.고정된 현재 날짜로 인해 테스트 시 예측 가능한 결과를 얻기 어려울 수 있습니다. Clock 주입이나 파라미터로 날짜를 받는 것을 고려해보세요.
-Page<RoomGetHomeJoinedListResponse.RoomSearchResult> result = roomQueryPort.searchHomeJoinedRooms(query.userId(), LocalDate.now(), pageable); +// Clock 주입을 통한 테스트 가능한 구현 고려 +Page<RoomGetHomeJoinedListResponse.RoomSearchResult> result = roomQueryPort.searchHomeJoinedRooms(query.userId(), LocalDate.now(), pageable);
56-56: 공백 스타일을 일관되게 유지해주세요.
if(page< 1)에서 연산자 앞뒤 공백이 일관되지 않습니다.-if(page< 1) { +if (page < 1) {src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetHomeJoinedListResponse.java (1)
14-20: 미래 필드 구현을 위한 주석 추가를 고려해보세요.PR 설명에서 언급된 참여자 수 필드에 대한 placeholder 주석이 보이지 않습니다.
memberCount필드가 현재 구현된 것인지, 향후 추가될 것인지 명확히 해주세요.public record RoomSearchResult( Long roomId, String bookImageUrl, String bookTitle, + // TODO: 실제 참여자 수 계산 로직 구현 필요 int memberCount, int userPercentage ) {}src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepositoryImpl.java (2)
158-163: TODO: Room 엔티티에 멤버 수 필드 추가 고려현재 서브쿼리로 멤버 수를 조회하고 있는데, 성능 개선을 위해 Room 엔티티에 멤버 수 필드를 추가하는 것이 좋을 것 같습니다.
이 개선사항에 대한 이슈를 생성해드릴까요?
188-188: 키셋 페이징 도입으로 성능 개선 가능오프셋 페이징 대신 키셋(커서) 페이징을 사용하면 대용량 데이터에서 성능이 크게 향상될 수 있습니다. 특히 페이지 번호가 커질수록 성능 차이가 두드러집니다.
src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java (1)
76-109: 테스트 데이터 관리 개선 제안현재
@BeforeEach와 각 테스트 메서드에서 테스트 데이터를 생성하고 있습니다. 테스트 간 격리는 잘 되어 있지만, 공통 테스트 데이터 생성 로직을 헬퍼 메서드로 추출하면 유지보수성이 향상될 것 같습니다.예를 들어:
+private UserJpaEntity createTestUserWithAlias(String nickname) { + AliasJpaEntity alias = TestEntityFactory.createLiteratureAlias(); + aliasJpaRepository.save(alias); + return userJpaRepository.save(TestEntityFactory.createUser(alias)); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java(3 hunks)src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetHomeJoinedListResponse.java(1 hunks)src/main/java/konkuk/thip/room/adapter/out/jpa/RoomJpaEntity.java(1 hunks)src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java(2 hunks)src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepository.java(1 hunks)src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepositoryImpl.java(3 hunks)src/main/java/konkuk/thip/room/application/port/in/RoomGetHomeJoinedListUseCase.java(1 hunks)src/main/java/konkuk/thip/room/application/port/in/dto/RoomGetHomeJoinedListQuery.java(1 hunks)src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java(2 hunks)src/main/java/konkuk/thip/room/application/service/RoomGetHomeJoinedListService.java(1 hunks)src/test/java/konkuk/thip/common/util/TestEntityFactory.java(2 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java(1 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsControllerTest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (8)
src/main/java/konkuk/thip/room/adapter/out/jpa/RoomJpaEntity.java (1)
Learnt from: hd0rable
PR: THIP-TextHip/THIP-Server#57
File: src/test/java/konkuk/thip/room/domain/RoomTest.java:0-0
Timestamp: 2025-07-08T16:30:33.771Z
Learning: Room 도메인에서 startDate는 현재 날짜 이후여야 하는 도메인 규칙이 있어서, 테스트에서 만료된 상태를 시뮬레이션하려면 reflection을 사용해야 한다.
src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java (1)
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.
src/main/java/konkuk/thip/room/application/port/in/RoomGetHomeJoinedListUseCase.java (1)
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.
src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (1)
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.
src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (1)
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.
src/main/java/konkuk/thip/room/application/service/RoomGetHomeJoinedListService.java (1)
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.
src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java (1)
Learnt from: hd0rable
PR: THIP-TextHip/THIP-Server#57
File: src/test/java/konkuk/thip/room/domain/RoomTest.java:0-0
Timestamp: 2025-07-08T16:30:33.771Z
Learning: Room 도메인에서 startDate는 현재 날짜 이후여야 하는 도메인 규칙이 있어서, 테스트에서 만료된 상태를 시뮬레이션하려면 reflection을 사용해야 한다.
src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsControllerTest.java (1)
Learnt from: hd0rable
PR: THIP-TextHip/THIP-Server#57
File: src/test/java/konkuk/thip/room/domain/RoomTest.java:0-0
Timestamp: 2025-07-08T16:30:33.771Z
Learning: Room 도메인에서 startDate는 현재 날짜 이후여야 하는 도메인 규칙이 있어서, 테스트에서 만료된 상태를 시뮬레이션하려면 reflection을 사용해야 한다.
🧬 Code Graph Analysis (1)
src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java (1)
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (1)
TestEntityFactory(14-136)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (15)
src/main/java/konkuk/thip/room/application/port/in/RoomGetHomeJoinedListUseCase.java (1)
1-8: 잘 설계된 UseCase 인터페이스입니다.단일 책임 원칙을 준수하고 있으며, 메서드명과 파라미터 타입이 명확합니다. 인터페이스 설계가 깔끔합니다.
src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (1)
31-34: 구현이 적절합니다.어댑터 패턴을 올바르게 따르고 있으며, CQRS QueryPort 컨벤션에 맞게 response DTO를 반환하는 조회 메서드로 구현되었습니다.
src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (1)
49-52: 엔드포인트 구현이 적절합니다.Query DTO 빌더 패턴을 사용하여 깔끔하게 구현되었고, 기존 코드 패턴과 일관성이 있습니다.
src/main/java/konkuk/thip/room/application/service/RoomGetHomeJoinedListService.java (3)
23-23: 페이지 크기 상수가 적절합니다.기본 페이지 크기 10은 적절하며, 상수로 정의하여 유지보수성이 좋습니다.
36-36: 사용자 조회 시 예외 처리를 확인해주세요.
userCommandPort.findById()가 사용자를 찾지 못할 경우 발생하는 예외가 적절히 처리되는지 확인해주세요. 일반적으로 404 응답이 적절할 것 같습니다.
30-53: 전체적인 서비스 로직이 잘 구현되었습니다.단계별 구현이 명확하고 트랜잭션 처리, 페이지네이션 로직이 적절합니다.
src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetHomeJoinedListResponse.java (1)
5-12: Response 구조가 잘 설계되었습니다.페이지네이션 메타데이터와 사용자 정보가 적절히 포함되어 있고, record 사용으로 불변성이 보장됩니다.
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (3)
7-7: Import 통합이 적절합니다.테스트 유틸리티에서 wildcard import 사용은 허용되며, 코드가 더 깔끔해졌습니다.
86-97: 커스텀 룸 생성 메서드가 잘 구현되었습니다.날짜 범위를 지정할 수 있어 필터링 테스트에 유용할 것 같습니다. 메서드 시그니처와 구현이 기존 패턴과 일관됩니다.
99-107: 사용자-룸 관계 생성 메서드가 유용합니다.
userPercentage파라미터를 통해 진행률 기반 정렬 테스트가 가능하고,currentPage를 0으로 초기화하는 것이 적절합니다.src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepositoryImpl.java (2)
145-212: 전반적으로 구현이 잘 되었습니다!새로 추가된
searchHomeJoinedRooms메서드가 요구사항에 맞게 잘 구현되었습니다. 사용자가 참여 중인 방을 진행률 내림차순, 시작일 오름차순으로 정렬하여 조회하는 로직이 명확합니다.
197-197: 진행률 반올림으로 인한 정밀도 손실 확인 필요
userPercentage를Math.round로 반올림하여 정수로 변환하고 있습니다. 예를 들어 80.4%와 80.6% 모두 80%로 표시됩니다. 이러한 정밀도 손실이 비즈니스 요구사항에 부합하는지 확인이 필요합니다.src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsControllerTest.java (2)
20-24: 컨트롤러 테스트가 잘 구성되었습니다페이지 파라미터 검증을 위한 단위 테스트가 적절하게 작성되었습니다.
22-22: 보안 필터 비활성화 확인 필요
@AutoConfigureMockMvc(addFilters = false)로 보안 필터를 비활성화하고 있습니다. 단위 테스트에서는 일반적인 접근이지만, 실제 환경과의 차이가 발생할 수 있습니다.보안 필터를 비활성화한 특별한 이유가 있나요? 통합 테스트에서는 보안 필터를 포함하여 테스트하는 것도 고려해보세요.
src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java (1)
35-39: 통합 테스트가 매우 체계적으로 작성되었습니다모든 주요 시나리오를 포함하여 테스트 커버리지가 우수합니다:
- 기본 정렬 동작
- 진행률이 같을 때의 정렬
- 모집 중인 방 제외
- 빈 결과 처리
src/main/java/konkuk/thip/room/application/port/in/dto/RoomGetHomeJoinedListQuery.java
Show resolved
Hide resolved
buzz0331
left a comment
There was a problem hiding this comment.
수고하셨습니다~~!! 간단한 리뷰 남겼으니 확인 부탁드릴게요
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| //TODO 방에 이방에 참여중인 인원수 추가 |
| t.get(room.roomId), | ||
| t.get(book.imageUrl), | ||
| t.get(room.title), | ||
| t.get(memberCountSubQuery).intValue(), |
There was a problem hiding this comment.
p3: 추후에 count 변수를 사용했을 때 혹시라도 초기화가 안되어 있으면 NPE가 발생할 것 같아요. (저도 기록장 조회를 구현하면서 많이 발생했습니다..) 다음과 같이 수정하면, NPE를 방지할 수 있을 것 같습니다!
Optional.ofNullable(t.get(memberCountSubQuery)).map(Number::intValue).orElse(0);
There was a problem hiding this comment.
앗 넵넵!! 해당 쿼리로 조회된 row는 내가 참여한 방을 보장하므로 대신 1로 초기화하는 방식으로 수정하겠습니닷~!
| .map(t -> new RoomGetHomeJoinedListResponse.RoomSearchResult( | ||
| t.get(room.roomId), | ||
| t.get(book.imageUrl), | ||
| t.get(room.title), | ||
| t.get(memberCountSubQuery).intValue(), | ||
| (int) Math.round(t.get(userRoom.userPercentage)) |
There was a problem hiding this comment.
p3: builder 패턴 적용하는거 어떨까요..?
seongjunnoh
left a comment
There was a problem hiding this comment.
LGTM
요구사항 모두 잘 구현해주신것 같습니다! 테스트 코드도 깔끔하게 작성해주셔서 보기 편했습니다!
| // 1. 검색 조건(where) 조립 | ||
| // 유저가 참여한 방만: userId 조건 | ||
| // 활동 기간 중인 방만: startDate ≤ today ≤ endDate | ||
| BooleanBuilder where = new BooleanBuilder(); | ||
| where.and(userRoom.userJpaEntity.userId.eq(userId)); | ||
| where.and(room.startDate.loe(date)); | ||
| where.and(room.endDate.goe(date)); |
| .orderBy( | ||
| userRoom.userPercentage.desc(), // 진행률 높은 순(내림차순) | ||
| room.startDate.asc() // 진행률 같으면 활동 시작일 빠른 순 (오름차순) | ||
| ) |
|



#️⃣ 연관된 이슈
📝 작업 내용
모집중인 방은 조회 결과에 포함되지 않습니다.
📸 스크린샷
💬 리뷰 요구사항
추후에 개발될 참여중인 모집방 조회와 겹치지 않게 하고, 저희 컨벤션인 도메인 Room을 메서드 앞에 붙이자는 조건을 따르려고하니까 메서드 명이 조금 직관적이지 않을수있는데 좋은 메서드명이있을까요..?
📌 PR 진행 시 이러한 점들을 참고해 주세요
Summary by CodeRabbit
신규 기능
버그 수정
테스트