Skip to content

[feat] 특정 책으로 모집중인 모임방 조회#142

Merged
buzz0331 merged 20 commits intodevelopfrom
feat/#140-recruiting-room-with-book
Aug 6, 2025
Merged

[feat] 특정 책으로 모집중인 모임방 조회#142
buzz0331 merged 20 commits intodevelopfrom
feat/#140-recruiting-room-with-book

Conversation

@buzz0331
Copy link
Contributor

@buzz0331 buzz0331 commented Aug 5, 2025

#️⃣ 연관된 이슈

closes #140

📝 작업 내용

조회 형식은 기존과 거의 동일합니다.

  1. Cursor 디코딩
  2. isbn으로 모임방 조회 (마감 임박순 정렬, 자기 자신도 포함, status = ACTIVE, 아직 시작되지 않은)
  3. CursorBasedList -> Response DTO

📸 스크린샷

💬 리뷰 요구사항

리팩토링 된 부분이 꽤 있어서 확인 부탁드립니다!

  • 기존 Book 도메인의 DTO 컨벤션이 다르게 되어있어서 모두 고쳤습니다.
  • BookCommandPort의 findByISBN과 getByISBNOrThrow 분리
  • 책 상세보기에서 recruitingReadCount -> readCount
  • 중요!! : persistenceAdapter 쪽에서 List -> CursorBasedList로 파싱하는 과정이 계속 반복되는 것 같아 공통 함수형 인터페이스로 통합하고 람다 캡처를 사용해서 각각의 필요한 식별자는 동적으로 넘기도록 하였습니다. (userId, isbn 등)
    관련 내용은 노션에 문서화해두겠습니다.

같은 도메인에서 조회 api 구현시 대부분 같은 필드를 커서로 잡고 사용하는 것 같아서 커서 기반 페이징 처리시 위와 같은 방식으로 공통 함수형 인터페이스 하나를 두고 람다 캡처를 이용하면 중복 코드를 줄일 수 있을 것 같습니다!

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

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

Summary by CodeRabbit

  • 신규 기능

    • 특정 도서의 모집 중인 방 목록을 조회하는 새로운 API 엔드포인트가 추가되었습니다. (ISBN 및 커서 기반 페이지네이션 지원)
    • 도서 모집방 목록, 도서 저장 여부, 인기 도서 등 응답 포맷이 간결한 이름으로 개선되었습니다.
  • 버그 수정

    • 도서 상세 검색 결과에서 모집 중인 인원 수 필드명이 readCount로 변경되어 일관성을 높였습니다.
  • 리팩터링

    • 여러 DTO 및 API 응답 클래스의 명칭이 간소화되어 가독성과 유지보수가 용이해졌습니다.
    • 내부 도서 조회 방식이 Optional 및 명확한 예외 처리 방식으로 변경되었습니다.
  • 테스트

    • 도서 모집방 API에 대한 통합 테스트가 추가되어, 정상 동작 및 페이지네이션 시나리오가 검증됩니다.
    • 기존 테스트 코드가 변경된 DTO 명칭에 맞게 수정되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Aug 5, 2025

Walkthrough

이 변경사항은 도메인 객체 및 API 응답/요청 DTO의 네이밍을 일관성 있게 정비하고, 책 관련 모집방(Recruiting Room) 조회 기능을 신규로 추가합니다. 또한, 도메인 계층에서 ISBN으로 책을 조회하는 방식이 Optional 반환 및 예외 처리 방식으로 개선되었으며, 관련 서비스와 테스트 코드도 이에 맞게 수정되었습니다.

Changes

Cohort / File(s) Change Summary
Book Saved/IsSaved DTO 네이밍 및 컨트롤러/테스트 반영
src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java, src/main/java/konkuk/thip/book/adapter/in/web/request/BookIsSavedRequest.java, src/main/java/konkuk/thip/book/adapter/in/web/response/BookIsSavedResponse.java, src/main/java/konkuk/thip/book/adapter/in/web/response/PostBookIsSavedResponse.java, src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java
요청/응답 DTO 이름을 PostBookIsSaved*에서 BookIsSaved*로 변경하고, 컨트롤러 및 테스트에서 해당 타입을 사용하도록 수정. 기존 DTO 파일 삭제 및 신규 DTO 생성.
Book 검색/상세/랭킹/모집방 응답 DTO 네이밍 및 컨트롤러 반영
src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java, src/main/java/konkuk/thip/book/adapter/in/web/response/BookDetailSearchResponse.java, src/main/java/konkuk/thip/book/adapter/in/web/response/BookSearchListResponse.java, src/main/java/konkuk/thip/book/adapter/in/web/response/BookMostSearchResponse.java, src/main/java/konkuk/thip/book/adapter/in/web/response/GetBookMostSearchResponse.java, src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java, src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java
DTO 클래스명을 GetBook*Response에서 Book*Response로 일괄 변경 및 컨트롤러, 테스트 반영. 모집방 응답 DTO 및 관련 컨트롤러 엔드포인트 추가.
Book 모집방 조회 신규 기능
src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java, src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java, src/main/java/konkuk/thip/book/application/port/in/BookRecruitingRoomsUseCase.java, src/main/java/konkuk/thip/book/application/service/BookRecruitingRoomsService.java, src/main/java/konkuk/thip/book/application/mapper/BookQueryMapper.java, src/test/java/konkuk/thip/book/adapter/in/web/BookRecruitingRoomApiTest.java
책별 모집방 목록을 조회하는 신규 API 엔드포인트 및 서비스, 포트, 매퍼, 응답 DTO, 테스트 추가.
도메인: ISBN 기반 Book 조회 Optional/예외 처리 개선
src/main/java/konkuk/thip/book/adapter/out/persistence/BookCommandPersistenceAdapter.java, src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java, src/main/java/konkuk/thip/book/application/service/BookSavedService.java, src/main/java/konkuk/thip/book/application/service/BookMostSearchRankService.java, src/main/java/konkuk/thip/book/application/service/BookSearchService.java, src/main/java/konkuk/thip/feed/application/service/FeedCreateService.java, src/main/java/konkuk/thip/room/application/service/RoomCreateService.java
findByIsbn 반환 타입을 Optional로 변경하고, getByIsbnOrThrow 메서드 추가. 서비스 계층에서 해당 메서드 사용하도록 수정.
BookDetailSearchResult 필드명 변경
src/main/java/konkuk/thip/book/application/port/in/dto/BookDetailSearchResult.java, src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java
recruitingReadCount 필드명을 readCount로 변경 및 관련 코드 일괄 반영.
Room 모집방 조회 관련 포트/어댑터/리포지토리/함수 개선 및 추가
src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java, src/main/java/konkuk/thip/room/adapter/out/persistence/function/RoomQueryFunction.java, src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomJpaRepository.java, src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepository.java, src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepositoryImpl.java, src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java
ISBN 기준 모집방 조회를 위한 쿼리/메서드/함수/JPQL 추가 및 기존 함수 시그니처 일부 변경.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant BookQueryController
    participant BookRecruitingRoomsUseCase
    participant BookRecruitingRoomsService
    participant RoomQueryPort
    participant BookQueryMapper

    Client->>BookQueryController: GET /books/{isbn}/recruiting-rooms?cursor=...
    BookQueryController->>BookRecruitingRoomsUseCase: getRecruitingRoomsWithBook(isbn, cursor)
    BookRecruitingRoomsUseCase->>BookRecruitingRoomsService: getRecruitingRoomsWithBook(isbn, cursor)
    BookRecruitingRoomsService->>RoomQueryPort: findRoomsByIsbnOrderByDeadline(isbn, cursor)
    RoomQueryPort-->>BookRecruitingRoomsService: CursorBasedList<RoomQueryDto>
    BookRecruitingRoomsService->>BookQueryMapper: toRecruitingRoomDtoList(roomDtos)
    BookQueryMapper-->>BookRecruitingRoomsService: List<RecruitingRoomDto>
    BookRecruitingRoomsService-->>BookRecruitingRoomsUseCase: BookRecruitingRoomsResponse
    BookRecruitingRoomsUseCase-->>BookQueryController: BookRecruitingRoomsResponse
    BookQueryController-->>Client: BaseResponse<BookRecruitingRoomsResponse>
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Assessment against linked issues

Objective Addressed Explanation
책으로 모집중인 모임방 조회 기능 구현 (#140)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes detected.

Possibly related PRs

  • THIP-TextHip/THIP-Server#44: 기존에 book saved 상태 변경 API 및 관련 DTO/컨트롤러를 최초로 도입한 PR로, 이번 PR의 DTO 네이밍 및 컨트롤러 시그니처 변경과 직접적으로 연관됨.
  • THIP-TextHip/THIP-Server#109: changeSavedBook 메서드에 Swagger 문서 주석을 추가한 PR로, 이번 PR과 동일 메서드를 다루지만 코드 레벨 변경은 겹치지 않음.

Suggested reviewers

  • hd0rable
  • seongjunnoh

Poem

🐰
새 이름 입은 책 DTO,
모집방도 찾아줄게요!
Optional로 책을 찾고,
예외 처리도 잊지 않죠.
테스트도 꼼꼼하게,
토끼는 오늘도 열심히,
코드밭에 당근 심어요! 🥕


📜 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 2bbee07 and 244b6f9.

📒 Files selected for processing (2)
  • src/main/java/konkuk/thip/book/application/service/BookSearchService.java (2 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepositoryImpl.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepositoryImpl.java
  • src/main/java/konkuk/thip/book/application/service/BookSearchService.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
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#140-recruiting-room-with-book

🪧 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.
  • 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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate unit tests to generate unit tests for 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: 2

🧹 Nitpick comments (5)
src/main/java/konkuk/thip/book/application/port/in/BookRecruitingRoomsUseCase.java (1)

7-7: 매개변수 검증 고려 필요

isbncursor 매개변수에 대한 검증 로직이나 문서화를 고려해보세요. 특히 ISBN 형식 검증이나 null 처리에 대한 명세가 있으면 좋을 것 같습니다.

다음과 같이 JavaDoc 추가를 고려해보세요:

+    /**
+     * 특정 책으로 모집중인 모임방을 조회합니다.
+     * 
+     * @param isbn 책의 ISBN (필수)
+     * @param cursor 페이지네이션을 위한 커서 (null 가능)
+     * @return 모집중인 모임방 목록과 페이지네이션 정보
+     */
     BookRecruitingRoomsResponse getRecruitingRoomsWithBook(String isbn, String cursor);
src/main/java/konkuk/thip/book/adapter/in/web/response/BookIsSavedResponse.java (1)

11-13: 정적 팩토리 메서드의 코드 포맷팅을 개선하세요.

레코드 설계와 정적 팩토리 메서드 패턴은 적절하지만, 생성자 호출 시 매개변수 사이의 공백이 누락되었습니다.

다음과 같이 수정하세요:

-        return new BookIsSavedResponse(bookIsSavedResult.isbn(),bookIsSavedResult.isSaved());
+        return new BookIsSavedResponse(bookIsSavedResult.isbn(), bookIsSavedResult.isSaved());
src/test/java/konkuk/thip/book/adapter/in/web/BookRecruitingRoomApiTest.java (2)

66-75: 테스트 데이터 생성 방식을 개선할 수 있습니다.

테스트 데이터 생성 시 TestEntityFactory를 활용하는 것을 고려해보세요. 현재는 인라인으로 빌더를 사용하고 있지만, 팩토리 메서드를 사용하면 코드 중복을 줄이고 유지보수성을 향상시킬 수 있습니다.

다음과 같이 리팩토링할 수 있습니다:

-        BookJpaEntity book = bookJpaRepository.save(BookJpaEntity.builder()
-                .isbn("1234567890123")
-                .title("모집책")
-                .authorName("저자")
-                .publisher("출판사")
-                .pageCount(300)
-                .description("설명")
-                .imageUrl("http://image.com")
-                .bestSeller(false)
-                .build());
+        BookJpaEntity book = bookJpaRepository.save(TestEntityFactory.createBookWithISBN("1234567890123"));

114-122: API 응답 검증이 충분하지 않을 수 있습니다.

현재는 기본적인 필드들만 검증하고 있습니다. 응답 DTO의 다른 중요한 필드들(예: 카테고리, 모집 인원, 마감일 등)도 검증하는 것을 고려해보세요.

다음과 같은 검증을 추가할 수 있습니다:

                .andExpect(jsonPath("$.data.recruitingRoomList[0].roomId").value(recruitingRoom.getRoomId()))
                .andExpect(jsonPath("$.data.recruitingRoomList[0].roomName").value("모집 중 방"))
+                .andExpect(jsonPath("$.data.recruitingRoomList[0].recruitCount").value(5))
+                .andExpect(jsonPath("$.data.recruitingRoomList[0].isPublic").value(true))
                .andExpect(jsonPath("$.data.recruitingRoomList.length()").value(1));
src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java (1)

14-17: 편의 메소드 추가가 유용하지만 네이밍 개선을 고려해보세요.

getByIsbnOrThrow 디폴트 메소드는 편의성을 제공하는 좋은 추가입니다. 다만 메소드명을 getByIsbn으로 단순화하거나 findByIsbnOrThrow로 일관성을 맞추는 것을 고려해보세요.

-    default Book getByIsbnOrThrow(String isbn){
+    default Book findByIsbnOrThrow(String isbn){
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7a6948f and 7c283d1.

📒 Files selected for processing (31)
  • src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java (2 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java (4 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/request/BookIsSavedRequest.java (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookDetailSearchResponse.java (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookIsSavedResponse.java (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookMostSearchResponse.java (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookSearchListResponse.java (3 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/GetBookMostSearchResponse.java (0 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/PostBookIsSavedResponse.java (0 hunks)
  • src/main/java/konkuk/thip/book/adapter/out/persistence/BookCommandPersistenceAdapter.java (2 hunks)
  • src/main/java/konkuk/thip/book/application/mapper/BookQueryMapper.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/port/in/BookRecruitingRoomsUseCase.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/port/in/dto/BookDetailSearchResult.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/port/in/dto/BookMostSearchResult.java (0 hunks)
  • src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/service/BookMostSearchRankService.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/service/BookRecruitingRoomsService.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/service/BookSavedService.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/service/BookSearchService.java (3 hunks)
  • src/main/java/konkuk/thip/feed/application/service/FeedCreateService.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (3 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/function/RoomQueryFunction.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomJpaRepository.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepository.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepositoryImpl.java (1 hunks)
  • src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java (2 hunks)
  • src/main/java/konkuk/thip/room/application/service/RoomCreateService.java (1 hunks)
  • src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java (7 hunks)
  • src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java (2 hunks)
  • src/test/java/konkuk/thip/book/adapter/in/web/BookRecruitingRoomApiTest.java (1 hunks)
💤 Files with no reviewable changes (3)
  • src/main/java/konkuk/thip/book/application/port/in/dto/BookMostSearchResult.java
  • src/main/java/konkuk/thip/book/adapter/in/web/response/GetBookMostSearchResponse.java
  • src/main/java/konkuk/thip/book/adapter/in/web/response/PostBookIsSavedResponse.java
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java (1)
src/main/java/konkuk/thip/common/exception/EntityNotFoundException.java (1)
  • EntityNotFoundException (5-10)
src/main/java/konkuk/thip/book/application/mapper/BookQueryMapper.java (1)
src/main/java/konkuk/thip/common/util/DateUtil.java (1)
  • DateUtil (12-62)
src/test/java/konkuk/thip/book/adapter/in/web/BookRecruitingRoomApiTest.java (1)
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (1)
  • TestEntityFactory (33-304)
🔇 Additional comments (54)
src/main/java/konkuk/thip/book/application/port/in/BookRecruitingRoomsUseCase.java (1)

5-8: 인터페이스 설계가 깔끔합니다!

헥사고날 아키텍처의 포트 패턴을 잘 따르고 있으며, 커서 기반 페이지네이션을 지원하는 메서드 시그니처가 적절합니다.

src/main/java/konkuk/thip/book/adapter/in/web/request/BookIsSavedRequest.java (1)

7-11: 네이밍 일관성 개선이 좋습니다!

PostBookIsSavedRequest에서 BookIsSavedRequest로의 네이밍 변경이 더 직관적이고 일관성 있습니다. 검증 어노테이션과 스키마 문서화도 적절하게 유지되었습니다.

src/main/java/konkuk/thip/book/application/service/BookSavedService.java (1)

37-37: 메서드 변경이 코드 가독성을 향상시킵니다!

findByIsbn(isbn)에서 getByIsbnOrThrow(isbn)로의 변경이 코드의 의도를 더 명확하게 표현합니다. 기존의 EntityNotFoundException 처리 로직과 완벽하게 호환되며, Optional 처리 부분을 제거하여 코드가 더 간결해졌습니다.

src/main/java/konkuk/thip/book/application/service/BookMostSearchRankService.java (1)

59-59: 일관된 리팩토링으로 코드베이스 통일성 확보

다른 서비스와 동일한 패턴으로 getByIsbnOrThrow 메서드를 사용하여 코드베이스 전반의 일관성을 유지했습니다. 기존의 예외 처리 로직과 네이버 API 폴백 동작도 그대로 유지되어 기능상 변화가 없습니다.

src/main/java/konkuk/thip/book/application/port/in/dto/BookDetailSearchResult.java (1)

9-9: 필드명 개선이 명확성을 높입니다

recruitingReadCount에서 readCount로의 네이밍 변경이 더 간결하고 의미가 명확합니다.

src/main/java/konkuk/thip/feed/application/service/FeedCreateService.java (1)

72-72: 메서드 호출 변경이 적절합니다.

findByIsbn에서 getByIsbnOrThrow로 변경하여 코드 의도가 더 명확해졌습니다. 기존의 예외 처리 로직도 그대로 유지되어 기능상 문제가 없습니다.

src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java (2)

143-143: 테스트가 DTO 필드명 변경에 맞게 올바르게 업데이트되었습니다.

recruitingReadCount()에서 readCount()로 변경하여 리네이밍된 DTO 필드와 일치합니다.


188-188: 테스트가 DTO 필드명 변경에 맞게 올바르게 업데이트되었습니다.

다른 테스트 메서드와 일관성을 유지하며 readCount() 필드를 올바르게 검증하고 있습니다.

src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java (2)

4-4: DTO 클래스명 변경이 일관성 있게 적용되었습니다.

PostBookIsSavedRequest에서 BookIsSavedRequest로 리네이밍된 클래스를 올바르게 import하고 있습니다.


110-110: 모든 테스트 메서드에서 DTO 클래스명이 일관성 있게 업데이트되었습니다.

PostBookIsSavedRequest에서 BookIsSavedRequest로의 변경이 모든 테스트 케이스에 올바르게 적용되어 컨트롤러 변경사항과 일치합니다.

Also applies to: 135-135, 167-167, 193-193, 216-216, 234-234

src/main/java/konkuk/thip/room/application/service/RoomCreateService.java (1)

54-54: 인터페이스 변경에 따른 메서드 호출 업데이트가 적절합니다.

getByIsbnOrThrow 사용으로 코드 의도가 명확해지고, 기존 예외 처리 로직과 잘 맞아떨어집니다.

src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepository.java (1)

34-34: 새로운 Repository 메서드가 적절하게 추가되었습니다.

ISBN 기반 모집방 조회 기능을 위한 메서드로, 기존 패턴을 따르며 커서 기반 페이지네이션을 올바르게 지원합니다. 메서드명도 의도를 명확하게 표현합니다.

src/main/java/konkuk/thip/room/adapter/out/persistence/function/RoomQueryFunction.java (1)

10-10: 메서드 시그니처 변경이 적절합니다.

userId 매개변수를 제거하고 람다 캡처를 통해 동적으로 전달하는 방식으로 변경한 것은 코드 중복을 줄이는 좋은 접근법입니다. PR 목표에서 언급한 공통 함수형 인터페이스 도입 취지와 일치합니다.

src/main/java/konkuk/thip/book/adapter/out/persistence/BookCommandPersistenceAdapter.java (1)

27-30: Optional 반환 패턴으로 개선된 설계입니다.

예외 처리 로직을 제거하고 Optional<Book>을 반환하도록 변경한 것은 관심사 분리 측면에서 좋은 개선입니다. 영속성 계층에서는 데이터 존재 여부만 표현하고, 예외 처리는 상위 계층(getByIsbnOrThrow)에서 담당하는 것이 더 적절합니다.

src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java (1)

35-35: 새로운 쿼리 메서드가 기존 패턴과 일관성 있게 추가되었습니다.

findRoomsByIsbnOrderByDeadline 메서드는 기존 인터페이스의 명명 규칙과 반환 타입을 잘 따르고 있으며, 커서 기반 페이지네이션을 지원하여 일관된 API를 제공합니다.

src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomJpaRepository.java (1)

12-16: ACTIVE 상태 필터링이 추가된 쿼리 메서드가 올바르게 구현되었습니다.

비즈니스 로직에 맞게 ACTIVE 상태의 방만 카운트하도록 필터링이 추가되었고, 명명된 매개변수를 사용하여 가독성과 보안성을 높였습니다. JPQL 쿼리 구조도 적절합니다.

src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java (4)

5-8: 새로운 import 추가가 적절합니다

Optional 반환 타입과 예외 처리를 위한 import들이 올바르게 추가되었습니다.


12-12: Optional 반환 타입으로 변경이 좋은 설계입니다

메서드 시그니처를 Optional<Book>으로 변경한 것은 null 처리를 명시적으로 만들어 좋은 개선입니다.


14-17: ErrorCode.BOOK_NOT_FOUND 정의 확인 완료

getByIsbnOrThrow 편의성 메서드에 사용된 ErrorCode.BOOK_NOT_FOUND
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java
에서 다음과 같이 정의되어 있음을 확인했습니다:

BOOK_NOT_FOUND(HttpStatus.NOT_FOUND, 80010, "존재하지 않는 BOOK 입니다."),

따라서 해당 편의성 메서드 추가는 유효하며, 별도 조치 없이 머지하셔도 좋습니다.


12-12: Optional 반환 타입으로의 변경이 적절합니다.

findByIsbn 메소드가 Optional<Book>을 반환하도록 변경된 것은 null 안전성을 높이는 좋은 개선입니다. 존재하지 않을 수 있는 엔티티에 대한 명시적인 처리가 가능해졌습니다.

src/main/java/konkuk/thip/book/adapter/in/web/response/BookSearchListResponse.java (4)

9-17: 네이밍 컨벤션 개선이 좋습니다

GetBookSearchListResponse에서 BookSearchListResponse로 변경하여 "Get" 접두사를 제거한 것은 더 간결하고 일관된 네이밍입니다.


18-37: 팩토리 메서드가 올바르게 업데이트되었습니다

새로운 레코드 타입을 반환하도록 팩토리 메서드가 정확히 수정되었고, 내부 로직은 그대로 유지되어 안전한 리팩토링입니다.


9-17: DTO 네이밍 규칙 표준화가 적절합니다.

GetBookSearchListResponse에서 BookSearchListResponse로의 클래스명 변경은 더 간결하고 일관된 네이밍을 제공합니다. Get 접두사 제거가 코드베이스의 일관성을 향상시킵니다.


18-37: 정적 팩토리 메소드 업데이트가 올바릅니다.

of 메소드의 반환 타입이 새로운 클래스명에 맞게 적절히 업데이트되었습니다. 내부 로직은 변경 없이 유지되어 안정성을 보장합니다.

src/main/java/konkuk/thip/book/application/service/BookSearchService.java (6)

96-96: 새로운 인터페이스 메서드 사용이 적절합니다

findByIsbn에서 getByIsbnOrThrow로 변경하여 새로운 BookCommandPort 인터페이스를 올바르게 사용하고 있습니다.


110-118: 변수명 변경이 더 명확합니다

recruitingReadCount에서 readCount로 변경하여 의미가 더 명확해졌습니다. 실제로는 모집중인 독자 수가 아니라 전체 읽기 참여자 수를 나타내므로 적절한 네이밍입니다.


127-127: 메서드명 변경이 일관성 있습니다

변수명 변경에 맞춰 메서드명도 getRecruitingReadCount에서 getReadCount로 변경하여 일관성을 유지했습니다.


96-96: 예외 처리 방식 개선이 적절합니다.

findByIsbn에서 getByIsbnOrThrow로 변경하여 예외 처리가 더 명시적이고 일관성 있게 되었습니다. 새로운 포트 인터페이스와 잘 연동됩니다.


110-110: 변수명 개선이 의미를 더 명확하게 합니다.

recruitingReadCount에서 readCount로의 변경이 변수의 의미를 더 명확하고 간결하게 표현합니다. 네이밍 일관성 향상에 기여합니다.

Also applies to: 117-117


127-127: 메소드명 변경이 일관성을 향상시킵니다.

getRecruitingReadCount에서 getReadCount로의 메소드명 변경이 변수명 변경과 일치하여 코드의 일관성을 높입니다.

src/main/java/konkuk/thip/book/adapter/in/web/response/BookDetailSearchResponse.java (4)

7-17: 레코드 클래스명과 필드명 개선이 좋습니다

GetBookDetailSearchResponse에서 BookDetailSearchResponse로 변경하고, recruitingReadCountreadCount로 변경한 것이 더 간결하고 정확한 네이밍입니다.


18-30: 팩토리 메서드가 일관되게 업데이트되었습니다

새로운 레코드 타입을 반환하도록 하고, 변경된 필드명 readCount를 올바르게 사용하여 서비스 레이어 변경사항과 일치합니다.


7-7: Response DTO 네이밍 표준화가 일관성을 향상시킵니다.

GetBookDetailSearchResponse에서 BookDetailSearchResponse로의 클래스명 변경과 정적 팩토리 메소드 업데이트가 코드베이스의 네이밍 일관성을 크게 향상시킵니다.

Also applies to: 18-20


15-15: 필드명 변경이 의미를 더 명확하게 합니다.

recruitingReadCountreadCount로 변경한 것이 필드의 의미를 더 간결하고 명확하게 표현합니다. 애플리케이션 레이어의 변경사항과 일치하여 일관성을 유지합니다.

Also applies to: 28-28

src/main/java/konkuk/thip/book/adapter/in/web/response/BookMostSearchResponse.java (2)

1-13: 새로운 응답 DTO가 일관된 패턴을 따릅니다

BookMostSearchResponse 클래스는 다른 응답 DTO들과 일관된 네이밍 컨벤션과 구조를 따르고 있습니다. 간단한 래퍼 역할을 하는 팩토리 메서드도 적절합니다.


1-13: 새로운 Response 클래스가 네이밍 일관성을 완성합니다.

BookMostSearchResponse 클래스가 다른 Response 클래스들과 일관된 네이밍 패턴을 따르며, 정적 팩토리 메소드가 적절히 구현되었습니다. 코드베이스의 네이밍 표준화를 완성하는 좋은 추가입니다.

src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java (1)

8-9: DTO 네이밍 표준화가 잘 되었습니다.

PostBookIsSavedRequestPostBookIsSavedResponse를 각각 BookIsSavedRequestBookIsSavedResponse로 변경하여 네이밍 일관성을 개선했습니다. 메서드 로직은 동일하게 유지되면서 새로운 static factory method를 올바르게 사용하고 있습니다.

Also applies to: 37-37, 40-40, 43-43

src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomQueryRepositoryImpl.java (1)

379-406: 새로운 ISBN 기반 방 조회 메서드가 잘 구현되었습니다.

커서 기반 페이지네이션을 올바르게 구현했으며, 복합 커서 조건(dateCursor와 roomIdCursor)을 통해 일관된 정렬을 보장합니다. 활성 상태이면서 모집 중인 방만 필터링하는 조건도 적절합니다.

src/main/java/konkuk/thip/book/application/service/BookRecruitingRoomsService.java (1)

15-31: 서비스 로직이 깔끔하게 구현되었습니다.

의존성 주입, 커서 기반 페이지네이션 처리, DTO 매핑이 모두 올바르게 구현되어 있습니다. 상수로 정의된 DEFAULT_PAGE_SIZE도 적절하며, 메서드의 책임이 명확하게 분리되어 있습니다.

src/main/java/konkuk/thip/book/application/mapper/BookQueryMapper.java (1)

12-26: MapStruct 매퍼가 올바르게 구성되었습니다.

DateUtil을 활용한 날짜 포맷팅, 스프링 컴포넌트 모델 설정, 그리고 단일 객체와 리스트 변환 메서드가 모두 적절하게 구현되어 있습니다. unmappedTargetPolicy = IGNORE 설정도 명시적이어서 좋습니다.

src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java (1)

5-26: 응답 DTO 구조가 명확하고 잘 설계되었습니다.

Java record를 활용하여 불변 객체로 구현했으며, 페이지네이션에 필요한 메타데이터(nextCursor, isLast)와 실제 데이터를 적절히 분리했습니다. 중첩된 RecruitingRoomDto와 각각의 static factory method도 일관성 있게 구현되어 있습니다.

src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (4)

51-52: 람다 캡처를 활용한 리팩토링이 잘 구현되었습니다.

RoomQueryFunction 인터페이스를 활용하여 userId 매개변수를 람다 캡처로 처리하는 방식이 코드 중복을 효과적으로 줄였습니다. 함수형 인터페이스의 활용으로 가독성과 유지보수성이 향상되었습니다.

Also applies to: 57-58, 63-64, 69-70


73-77: 새로운 메서드 구현이 기존 패턴과 일관성 있게 작성되었습니다.

ISBN으로 방을 조회하는 새로운 메서드가 기존 패턴과 동일하게 구현되어 일관성을 유지하고 있습니다. 메서드명도 비즈니스 의도를 명확히 표현하고 있습니다.


79-79: 메서드 시그니처 단순화가 적절합니다.

findRooms 메서드에서 userId 매개변수를 제거하고 RoomQueryFunction만 받도록 변경한 것이 함수형 인터페이스의 활용 목적에 부합합니다. 람다 캡처를 통해 필요한 매개변수들을 동적으로 전달할 수 있게 되었습니다.

Also applies to: 84-84


30-30: 메서드명 변경 의도 확인 완료
countActiveRoomsByBookIdAndStartDateAfter는 내부 JPA 쿼리의 status = 'ACTIVE' 필터를 명확하게 반영하기 위해 네이밍된 것이며,
포트(RoomQueryPort.countRecruitingRoomsByBookAndStartDateAfter)와 어댑터(RoomQueryPersistenceAdapter)에서 해당 메서드를 정상적으로 위임하고 있어 기능상 문제나 일관성 깨짐은 없습니다.

• src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java – countRecruitingRoomsByBookAndStartDateAfter → 내부 countActiveRoomsByBookIdAndStartDateAfter 위임
• src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomJpaRepository.java – @Query에서 status = 'ACTIVE' 필터 사용

src/test/java/konkuk/thip/book/adapter/in/web/BookRecruitingRoomApiTest.java (5)

34-39: 테스트 설정이 적절하게 구성되었습니다.

Spring Boot 통합 테스트에 필요한 어노테이션들이 올바르게 설정되어 있습니다. @AutoConfigureMockMvc(addFilters = false)@Transactional을 통해 보안 필터를 비활성화하고 테스트 간 데이터 격리를 보장하고 있습니다.


89-111: 테스트 시나리오가 비즈니스 로직을 정확히 검증합니다.

모집 중인 방과 마감된 방을 모두 생성하여 필터링 로직이 올바르게 동작하는지 확인하고 있습니다. 시작일과 종료일 설정을 통해 방의 상태를 명확히 구분한 것이 좋습니다.


126-134: 예외 상황 테스트가 적절합니다.

존재하지 않는 ISBN에 대한 처리를 테스트하여 엣지 케이스를 잘 커버하고 있습니다. 빈 리스트 반환을 확인하는 것이 적절합니다.


138-176: 커서 기반 페이징 테스트가 포괄적입니다.

첫 번째 페이지와 두 번째 페이지의 동작을 모두 검증하고, nextCursor 추출 및 isLast 플래그 확인까지 포함하여 완전한 페이징 시나리오를 테스트하고 있습니다.


145-152: 테스트 데이터 생성에서 팩토리 메서드 활용이 우수합니다.

TestEntityFactory.createCustomRoom을 사용하여 15개의 방을 생성하는 방식이 깔끔하고 유지보수하기 좋습니다. 시작일을 다르게 설정하여 정렬 테스트도 할 수 있게 구성한 것이 좋습니다.

src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java (4)

7-10: 응답 DTO 네이밍 개선이 일관성 있게 적용되었습니다.

기존의 Get 접두사를 제거한 DTO 네이밍 변경이 전체적으로 일관성 있게 적용되어 코드 가독성이 향상되었습니다.

Also applies to: 12-12


42-42: 메서드 네이밍 컨벤션 변경이 적절합니다.

REST API 컨트롤러에서 get 접두사를 show로 변경한 것이 RESTful한 네이밍 컨벤션에 더 부합합니다. 일관성 있게 적용되어 좋습니다.

Also applies to: 56-56, 71-71


34-34: 새로운 의존성 주입이 적절합니다.

BookRecruitingRoomsUseCase 의존성이 새로운 기능 구현을 위해 올바르게 추가되었습니다.


76-88: 새로운 엔드포인트 구현이 잘 설계되었습니다.

ISBN 경로 변수와 커서 쿼리 파라미터를 사용한 RESTful API 설계가 적절합니다. Swagger 문서화도 충분히 되어 있고, ISBN 형식 검증을 위한 정규식 패턴도 올바르게 적용되었습니다.

hd0rable
hd0rable previously approved these changes Aug 6, 2025
Copy link
Member

@hd0rable hd0rable left a comment

Choose a reason for hiding this comment

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

수고하셨습니닷!! 현준님은 람다 진짜 잘 활용하시네여 람다 캡쳐 사용하는 방식으로 리펙토링하신거 좋은것같습니다~~ 붐업 붐업👍🏻

String description,
int recruitingRoomCount,
int recruitingReadCount,
int readCount,
Copy link
Member

Choose a reason for hiding this comment

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

붐업~~!!

@@ -4,7 +4,7 @@
import jakarta.validation.constraints.NotNull;

@Schema(description = "책 저장 상태 변경 요청 DTO")
public record PostBookIsSavedRequest(
Copy link
Member

Choose a reason for hiding this comment

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

커컼.. 이게 아마 dto 컨벤션 바뀌기 전에 다 구현된것들이라.. 메서드명 다 붙어있던거 야무지게 빼주셧네요 감사합니다람쥐~~👍🏻

BookJpaEntity bookJpaEntity = bookJpaRepository.findByIsbn(isbn).orElseThrow(
() -> new EntityNotFoundException(BOOK_NOT_FOUND));
return bookMapper.toDomainEntity(bookJpaEntity);
public Optional<Book> findByIsbn(String isbn) {
Copy link
Member

Choose a reason for hiding this comment

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

LGTM

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: 0

🧹 Nitpick comments (2)
src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java (2)

11-13: 정적 팩토리 메서드가 불필요합니다.

Java record는 이미 모든 필드를 받는 생성자를 자동으로 제공하므로, 단순히 생성자를 호출하는 정적 팩토리 메서드는 코드 중복입니다.

다음과 같이 정적 팩토리 메서드를 제거하는 것을 권장합니다:

-    public static BookRecruitingRoomsResponse of(List<RecruitingRoomDto> recruitingRoomList, Integer totalRoomCount, String nextCursor, boolean isLast) {
-        return new BookRecruitingRoomsResponse(recruitingRoomList, totalRoomCount, nextCursor, isLast);
-    }

23-25: 중첩 record의 정적 팩토리 메서드도 불필요합니다.

외부 record와 마찬가지로 Java record의 기본 생성자로 충분합니다.

다음과 같이 정적 팩토리 메서드를 제거하는 것을 권장합니다:

-        public static RecruitingRoomDto of(Long roomId, String bookImageUrl, String roomName, int memberCount, int recruitCount, String deadlineEndDate) {
-            return new RecruitingRoomDto(roomId, bookImageUrl, roomName, memberCount, recruitCount, deadlineEndDate);
-        }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 78c87cf and 774075a.

📒 Files selected for processing (6)
  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/service/BookRecruitingRoomsService.java (1 hunks)
  • src/main/java/konkuk/thip/book/application/service/BookSearchService.java (2 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (3 hunks)
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomJpaRepository.java (1 hunks)
  • src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/java/konkuk/thip/book/application/service/BookRecruitingRoomsService.java
  • src/main/java/konkuk/thip/room/adapter/out/persistence/repository/RoomJpaRepository.java
  • src/main/java/konkuk/thip/book/application/service/BookSearchService.java
  • src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java
  • src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: thip 프로젝트에서는 query api(조회 api)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response dto를 직접 ...
Learnt from: buzz0331
PR: THIP-TextHip/THIP-Server#78
File: src/main/java/konkuk/thip/user/application/port/out/FollowingQueryPort.java:3-3
Timestamp: 2025-07-14T18:22:56.538Z
Learning: THIP 프로젝트에서는 Query API(조회 API)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response DTO를 직접 참조하는 것을 허용함. 이는 CQRS 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.

Applied to files:

  • src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.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
🔇 Additional comments (3)
src/main/java/konkuk/thip/book/adapter/in/web/response/BookRecruitingRoomsResponse.java (3)

1-3: 패키지 구조와 import가 적절합니다.

응답 DTO가 올바른 패키지에 위치하고 있으며, 필요한 import만 포함되어 있습니다.


5-10: 페이지네이션 필드 구조가 일관성 있게 설계되었습니다.

커서 기반 페이지네이션을 위한 nextCursor, isLast 필드와 함께 총 개수를 나타내는 totalRoomCount 필드가 포함되어 있어 클라이언트에서 페이지네이션을 효과적으로 구현할 수 있습니다.


15-22: 중첩 DTO의 필드 구조가 적절합니다.

모집방 정보를 나타내는 필드들이 명확하고 일관성 있게 명명되어 있습니다. memberCountrecruitCount 필드를 통해 현재 참여 인원과 모집 정원을 구분하여 표현한 것이 좋습니다.

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.

고생하셨습니다! 간단한 궁금증 리뷰로 남겼습니다!

Comment on lines +28 to +29
Integer totalRoomCount = (cursorStr == null || cursorStr.isBlank()) ? // 첫 요청 여부 판단
roomQueryPort.countRecruitingRoomsByBookAndStartDateAfter(isbn, LocalDate.now()) : null;
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 +12 to +17
Optional<Book> findByIsbn(String isbn);

default Book getByIsbnOrThrow(String isbn){
return findByIsbn(isbn)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.BOOK_NOT_FOUND));
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

굳굳 서비스에서 try catch 를 하나 더 없앨 수 있겠네요

roomJpaRepository.findRoomsByIsbnOrderByStartDateAsc(isbn, lastLocalDate, lastId, pageSize));
}

private CursorBasedList<RoomQueryDto> findRooms(Cursor cursor, RoomQueryFunction queryFunction) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

p3 : 메서드 재 사용성을 위해 파라미터에서 userId를 제거하신 건가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

넵 기존 조회에서는 userId로 방을 조회하고 있었고, 이번 api의 요구사항은 책의 isbn으로 모임방을 조회하는 것이였습니다. 이때, 두 요구사항 모두 startDate와 roomId를 커서 필드로 잡고 복합 커서로 잡고 있어서 Cursor를 만드는 것과 인코딩하는 로직이 공통으로 쓰이는 것을 확인했습니다! 따라서 userId와 isbn 같은 식별자는 람다 캡처를 통해 동적으로 넘기도록 하고 공통된 로직만 함수형 인터페이스를 사용하도록 했습니다.

Comment on lines +379 to +380
@Override
public List<RoomQueryDto> findRoomsByIsbnOrderByStartDateAsc(String isbn, LocalDate dateCursor, Long roomIdCursor, int pageSize) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Comment on lines +34 to +39
@SpringBootTest
@ActiveProfiles("test")
@DisplayName("[통합] 특정 책으로 모집중인 모임방을 조회하는 api 통합 테스트")
@AutoConfigureMockMvc(addFilters = false)
@Transactional
class BookRecruitingRoomApiTest {
Copy link
Collaborator

Choose a reason for hiding this comment

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

LGTM

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-204] [feat] 책으로 모집중인 모임방 조회

3 participants