Skip to content

[Feat] 모임 홈 화면에서 유저가 참여중인 모임 방 조회 api#68

Merged
hd0rable merged 17 commits intodevelopfrom
feat/#56-get-home-user-room
Jul 13, 2025
Merged

[Feat] 모임 홈 화면에서 유저가 참여중인 모임 방 조회 api#68
hd0rable merged 17 commits intodevelopfrom
feat/#56-get-home-user-room

Conversation

@hd0rable
Copy link
Member

@hd0rable hd0rable commented Jul 12, 2025

#️⃣ 연관된 이슈

closes #56

📝 작업 내용

  • 모임 홈 화면에서 유저가 참여중인 모임 방 조회 api를 개발했습니다.
  • api 흐름은 다음과 같습니다.
controller :  request dto -> query로 매핑 & Usecase로 query 전달
application : page값 검증 & Persistence Port 호출 및 결과를 응답 DTO로 변환하여 반환
persistence adapter : QueryDSL을 이용해 해당 조건에 필터링, 정렬된 데이터 반환
  • 사용자의 모임 홈 화면에서 조회되는 참여중인 모임 방은 현재 진행중인 방에 한해서만 조회됩니다. 즉, 현재 사용자가 참여 중이지만
    모집중인 방은 조회 결과에 포함되지 않습니다.
  • 조회 결과는 사용자의 진행도가 높은순, 같다면 방의 시작시간이 빠른 순으로 정렬됩니다.
  • Room안에 참여중인 유저의 수 필드값이 추가될 것을 고려하여 해당 부분 주석으로 작성해뒀습니다.
  • 통합,단위 테스트도 같이 작성했습니다.

📸 스크린샷

image

💬 리뷰 요구사항

추후에 개발될 참여중인 모집방 조회와 겹치지 않게 하고, 저희 컨벤션인 도메인 Room을 메서드 앞에 붙이자는 조건을 따르려고하니까 메서드 명이 조금 직관적이지 않을수있는데 좋은 메서드명이있을까요..?

📌 PR 진행 시 이러한 점들을 참고해 주세요

* P1 : 꼭 반영해 주세요 (Request Changes) - 이슈가 발생하거나 취약점이 발견되는 케이스 등
* P2 : 반영을 적극적으로 고려해 주시면 좋을 것 같아요 (Comment)
* P3 : 이런 방법도 있을 것 같아요~ 등의 사소한 의견입니다 (Chore)

Summary by CodeRabbit

  • 신규 기능

    • 사용자가 참여 중인 방 목록을 조회하는 새로운 API(/rooms/home/joined)가 추가되었습니다. 해당 목록은 페이지네이션 및 정렬(참여율 내림차순, 시작일 오름차순 기준)이 적용되어 제공됩니다.
  • 버그 수정

    • 페이지 번호가 1 미만이거나 누락된 경우 올바른 에러 메시지와 함께 400 오류가 반환됩니다.
  • 테스트

    • 신규 API의 정상 동작, 정렬, 필터링(모집 중인 방 제외), 빈 목록 반환, 페이지 파라미터 검증에 대한 통합 테스트가 추가되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Jul 12, 2025

"""

Walkthrough

진행률이 높은 n개의 참여중인 모임방을 조회하는 새로운 API 엔드포인트(/rooms/home/joined)가 추가되었습니다. 이를 위해 관련 DTO, 서비스, 포트, 영속성 계층 메서드, 컨트롤러, 테스트 코드가 일괄적으로 도입 및 확장되었습니다. 기존 코드에는 영향이 없습니다.

Changes

파일/경로 요약 변경 내용 요약
RoomQueryController.java /rooms/home/joined GET 엔드포인트 및 관련 의존성 추가
RoomGetHomeJoinedListResponse.java 참여중인 모임방 리스트 및 페이징 정보 DTO 신설
RoomGetHomeJoinedListQuery.java 쿼리용 DTO(유저ID, 페이지) 신설
RoomGetHomeJoinedListUseCase.java, RoomGetHomeJoinedListService.java 유즈케이스 인터페이스 및 구현 서비스 신설, 비즈니스 로직 구현
RoomQueryPort.java, RoomQueryPersistenceAdapter.java, RoomQueryRepository.java, RoomQueryRepositoryImpl.java 참여중인 모임방 조회용 메서드 신설 및 구현, 쿼리 로직 추가
RoomJpaEntity.java 참가자 수 필드 추가 예정 주석(TODO)만 추가
TestEntityFactory.java 테스트용 커스텀 Room, UserRoom 생성 메서드 추가
RoomGetHomeJoinedRoomsApiTest.java 엔드포인트 통합 테스트 신설(정상, 정렬, 제외, 빈 결과 등 시나리오)
RoomGetHomeJoinedRoomsControllerTest.java 컨트롤러 유효성 검증(페이지 파라미터) 테스트 신설

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>
Loading

Assessment against linked issues

Objective Addressed Explanation
진행률이 높은 n개의 참여중인 모임방 조회 API 개발 (#56)
API의 정렬(진행률 desc, 시작일 asc), 페이징, 유효성 검증 (#56)
테스트 코드로 다양한 시나리오(정상, 정렬, 제외, 빈 결과, 유효성) 검증 (#56)

Suggested labels

🧸 현준

Poem

🐇
새로운 방 리스트, 토끼가 뛰어—
참여중인 모임, 진행률로 줄세워!
페이징도 척척, 유효성도 똑똑,
테스트까지 완벽,
오늘도 모임방에서
토끼는 신나게 점프!
🥕🎉
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5de0951 and 2b347de.

📒 Files selected for processing (4)
  • src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetHomeJoinedListResponse.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepositoryImpl.java (4 hunks)
  • src/main/java/konkuk/thip/room/application/service/RoomGetHomeJoinedListService.java (1 hunks)
  • src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetHomeJoinedListResponse.java
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/java/konkuk/thip/room/application/service/RoomGetHomeJoinedListService.java
  • src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryRepositoryImpl.java
  • src/test/java/konkuk/thip/room/adapter/in/web/RoomGetHomeJoinedRoomsApiTest.java
⏰ 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
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 파라미터명이 구체적이지만, currentDatedate가 더 일반적이고 재사용 가능한 이름일 수 있습니다.

-    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: 생성자 의존성 순서 변경 사유를 확인해주세요.

RoomGetHomeJoinedListUseCaseRoomVerifyPasswordUseCase의 순서가 변경되었는데, 특별한 이유가 있는지 확인해주세요. 일관된 순서 유지가 좋겠습니다.


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

📥 Commits

Reviewing files that changed from the base of the PR and between f9ed731 and 5de0951.

📒 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: 진행률 반올림으로 인한 정밀도 손실 확인 필요

userPercentageMath.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: 통합 테스트가 매우 체계적으로 작성되었습니다

모든 주요 시나리오를 포함하여 테스트 커버리지가 우수합니다:

  • 기본 정렬 동작
  • 진행률이 같을 때의 정렬
  • 모집 중인 방 제외
  • 빈 결과 처리

buzz0331
buzz0331 previously approved these changes Jul 12, 2025
Copy link
Contributor

@buzz0331 buzz0331 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다~~!! 간단한 리뷰 남겼으니 확인 부탁드릴게요


import java.time.LocalDate;

//TODO 방에 이방에 참여중인 인원수 추가
Copy link
Contributor

Choose a reason for hiding this comment

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

👍🏻

t.get(room.roomId),
t.get(book.imageUrl),
t.get(room.title),
t.get(memberCountSubQuery).intValue(),
Copy link
Contributor

Choose a reason for hiding this comment

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

p3: 추후에 count 변수를 사용했을 때 혹시라도 초기화가 안되어 있으면 NPE가 발생할 것 같아요. (저도 기록장 조회를 구현하면서 많이 발생했습니다..) 다음과 같이 수정하면, NPE를 방지할 수 있을 것 같습니다!

Optional.ofNullable(t.get(memberCountSubQuery)).map(Number::intValue).orElse(0);

Copy link
Member Author

Choose a reason for hiding this comment

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

앗 넵넵!! 해당 쿼리로 조회된 row는 내가 참여한 방을 보장하므로 대신 1로 초기화하는 방식으로 수정하겠습니닷~!

Comment on lines 192 to 197
.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))
Copy link
Contributor

@buzz0331 buzz0331 Jul 12, 2025

Choose a reason for hiding this comment

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

p3: builder 패턴 적용하는거 어떨까요..?

seongjunnoh
seongjunnoh previously approved these changes Jul 13, 2025
Copy link
Collaborator

@seongjunnoh seongjunnoh left a comment

Choose a reason for hiding this comment

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

LGTM
요구사항 모두 잘 구현해주신것 같습니다! 테스트 코드도 깔끔하게 작성해주셔서 보기 편했습니다!

Comment on lines +150 to +156
// 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));
Copy link
Collaborator

Choose a reason for hiding this comment

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

LGTM

Comment on lines +181 to +184
.orderBy(
userRoom.userPercentage.desc(), // 진행률 높은 순(내림차순)
room.startDate.asc() // 진행률 같으면 활동 시작일 빠른 순 (오름차순)
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

LGTM

@hd0rable hd0rable dismissed stale reviews from seongjunnoh and buzz0331 via 2b347de July 13, 2025 04:53
@sonarqubecloud
Copy link

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[THIP2025-96] [feat] 진행률이 높은 n개의 참여중인 모임방 조회 api 개발

3 participants