-
Notifications
You must be signed in to change notification settings - Fork 1
feat: 독서기록 목록조회 컬럼추가 #62
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
Conversation
📝 WalkthroughWalkthrough독서기록 목록 조회 API의 응답에 도서 썸네일, 제목, 출판사 컬럼이 추가되었습니다. 이를 위해 DTO, VO, 도메인 서비스, 저장소 인터페이스 및 구현체가 확장되었고, 도서 커버 이미지는 외부 API 요청 시 "Big" 사이즈로 명시적으로 요청하도록 변경되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API
participant DomainService
participant UserBookRepo
participant DB
Client->>API: 독서기록 목록 조회 요청
API->>DomainService: findReadingRecordsByDynamicCondition()
DomainService->>UserBookRepo: findById(userBookId)
UserBookRepo->>DB: SELECT * FROM user_book WHERE id=?
DB-->>UserBookRepo: UserBook
UserBookRepo-->>DomainService: UserBook
DomainService->>DB: SELECT * FROM reading_record WHERE userBookId=?
DB-->>DomainService: ReadingRecord 목록
DomainService->>DomainService: 각 ReadingRecord + UserBook 정보로 ReadingRecordInfoVO 생성
DomainService-->>API: Page<ReadingRecordInfoVO>
API-->>Client: ReadingRecordResponse (bookTitle, bookPublisher, bookCoverImageUrl 포함)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes(해당 변경사항 중 범위를 벗어난 기능적 코드 변경은 발견되지 않았습니다.) Possibly related PRs
Suggested labels
Suggested reviewers
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
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
Documentation and Community
|
|
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.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
apis/src/main/kotlin/org/yapp/apis/readingrecord/dto/response/ReadingRecordResponse.kt(2 hunks)domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt(3 hunks)domain/src/main/kotlin/org/yapp/domain/readingrecord/vo/ReadingRecordInfoVO.kt(3 hunks)domain/src/main/kotlin/org/yapp/domain/userbook/UserBookRepository.kt(1 hunks)infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt(1 hunks)infra/src/main/kotlin/org/yapp/infra/userbook/repository/impl/UserBookRepositoryImpl.kt(1 hunks)
⏰ 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-validation
🔇 Additional comments (10)
infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt (1)
25-26: 커버 이미지 품질 개선이 적절히 구현됨API 파라미터에
"Cover" = "Big"을 추가하여 고해상도 커버 이미지를 요청하도록 개선되었습니다. 불변 맵을 가변 맵으로 변환하여 파라미터를 추가하는 방식도 적절합니다.infra/src/main/kotlin/org/yapp/infra/userbook/repository/impl/UserBookRepositoryImpl.kt (1)
31-33: 구현은 올바르나 보안 취약점을 상속함JPA 리포지토리 패턴과 도메인 변환이 올바르게 구현되었습니다. 하지만 인터페이스에서 지적한 사용자 인증 우회 가능성을 그대로 구현하고 있습니다.
인터페이스 레벨에서 보안 이슈가 해결되면 이 구현도 함께 수정이 필요합니다.
apis/src/main/kotlin/org/yapp/apis/readingrecord/dto/response/ReadingRecordResponse.kt (2)
35-42: DTO 필드 확장이 적절히 구현됨도서 관련 필드들이 적절한 스키마 문서화와 함께 추가되었습니다. nullable 타입 사용도 도서 정보가 항상 사용 가능하지 않을 수 있다는 점을 고려할 때 적절합니다.
56-59: 매핑 로직이 올바르게 구현됨ReadingRecordInfoVO에서 새로운 도서 관련 필드들을 올바르게 매핑하고 있습니다.
domain/src/main/kotlin/org/yapp/domain/readingrecord/vo/ReadingRecordInfoVO.kt (2)
15-17: 도메인 VO 확장이 적절함도서 관련 필드들이 nullable로 적절히 추가되었고, 기본값 null 설정도 합리적입니다.
29-32: 팩토리 메서드 업데이트가 올바름
newInstance메서드가 새로운 파라미터들을 선택적으로 받도록 올바르게 업데이트되었고, 생성자 호출에서도 적절히 매핑하고 있습니다.Also applies to: 42-45
domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt (4)
10-10: 새로운 의존성 추가가 적절합니다.
UserBookRepository의존성 추가가 도서 정보를 독서기록 응답에 포함시키기 위한 요구사항에 맞게 잘 구현되었습니다.Also applies to: 19-19
68-83: N+1 쿼리 문제 방지를 위한 최적화가 잘 구현되었습니다.코멘트에서 언급한 대로 UserBook을 한 번만 조회하여 모든 독서기록에 적용하는 방식이 성능상 효율적입니다. 다만
findReadingRecordsByDynamicCondition에서도createReadingRecord와 동일하게 UserBook이 null일 가능성에 대한 처리가 적절히 되어 있습니다.
76-82: 일관된 VO 생성 패턴 사용을 권장합니다.두 메서드 모두에서
ReadingRecordInfoVO.newInstance()호출 시 동일한 패턴으로 book 관련 정보를 전달하고 있어 코드 일관성이 좋습니다. 향후 유지보수를 위해 이 패턴을 유지하는 것을 권장합니다.⛔ Skipped due to learnings
Learnt from: hoonyworld PR: YAPP-Github/Reed-Server#39 File: apis/src/main/kotlin/org/yapp/apis/book/dto/response/BookSearchResponse.kt:45-45 Timestamp: 2025-07-17T15:09:36.267Z Learning: Response DTO 클래스에서는 불변성을 지키기 위해 프로퍼티를 val로 선언하고, 업데이트가 필요한 경우 copy() 메서드를 사용해야 합니다.
51-59: UserBook이 존재하지 않을 때 예외 처리 검증 필요
- domain/src/main/kotlin/org/yapp/domain/readingrecord/ReadingRecordDomainService.kt
• createReadingRecord() 메서드 내userBookRepository.findById(userBookId)호출부
• findReadingRecordsByDynamicCondition() 메서드 내 동일 호출부현재
findById()가 null을 반환해도 독서기록은 생성되며 VO에는 도서 정보가 누락됩니다.
비즈니스 요구사항상 UserBook이 없는 경우에도 기록 생성을 허용해야 하는지,
허용하지 않는다면 곧바로 예외를 던지거나 별도 검증 로직을 추가해야 합니다.
확인 부탁드립니다.
| fun findByUserIdAndBookIsbn(userId: UUID, isbn: String): UserBook? | ||
| fun findByBookIdAndUserId(bookId: UUID, userId: UUID): UserBook? | ||
| fun findByIdAndUserId(id: UUID, userId: UUID): UserBook? | ||
| fun findById(id: UUID): UserBook? |
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.
보안 취약점: 사용자 인증 우회 가능성
새로 추가된 findById(id: UUID) 메서드는 사용자 ID 검증을 생략하여 다른 사용자의 UserBook에 접근할 수 있는 보안 취약점을 생성합니다. 기존 메서드들(findByIdAndUserId, findByBookIdAndUserId 등)은 모두 userId를 통한 접근 제어를 수행하고 있습니다.
사용자 스코프를 유지하도록 다음과 같이 수정하는 것을 권장합니다:
- fun findById(id: UUID): UserBook?
+ // 이 메서드 대신 기존의 findByIdAndUserId를 사용하거나,
+ // 반드시 필요한 경우 명시적으로 internal용임을 표시🤖 Prompt for AI Agents
In domain/src/main/kotlin/org/yapp/domain/userbook/UserBookRepository.kt at line
13, the findById(id: UUID) method lacks user ID verification, allowing
unauthorized access to other users' UserBook data. Modify this method to include
userId as a parameter and enforce access control by querying with both id and
userId, similar to existing methods like findByIdAndUserId, to maintain user
scope and prevent authentication bypass.


🔗 관련 이슈
Close [BOOK-189/feat] 독서기록 목록조회 컬럼추가 #58
📘 작업 유형
✨ Feature (기능 추가)
🐞 Bugfix (버그 수정)
🔧 Refactor (코드 리팩토링)
⚙️ Chore (환경 설정)
📝 Docs (문서 작성 및 수정)
✅ Test (기능 테스트)
🎨 style (코드 스타일 수정)
📙 작업 내역
독서기록 생성 및 조회 API 응답에 관련 도서 정보를 포함하도록 기능을 추가했습니다.
응답에 추가된 정보는 도서 제목, 출판사, 도서 표지 이미지 URL입니다.
ReadingRecordDomainService에서 독서기록을 처리할 때,UserBookRepository를 통해 연관된UserBook엔티티를 조회하고 해당 도서 정보를ReadingRecordInfoVO에 담아 반환하도록 수정했습니다.추가적으로, 알라딘 API에서 책 정보를 조회할 때 더 큰 사이즈의 표지 이미지를 가져오도록 요청 파라미터를 수정하여 이미지 품질을 개선했습니다.
🧪 테스트 내역
브라우저/기기에서 동작 확인
엣지 케이스 테스트 완료
기존 기능 영향 없음
🎨 스크린샷 또는 시연 영상 (선택)
✅ PR 체크리스트
커밋 메시지가 명확합니다
PR 제목이 컨벤션에 맞습니다
관련 이슈 번호를 작성했습니다
기능이 정상적으로 작동합니다
불필요한 코드를 제거했습니다
💬 추가 설명 or 리뷰 포인트 (선택)
독서기록 목록 조회 시, N+1 문제를 방지하기 위해 개별 독서기록마다
UserBook을 조회하지 않습니다.대신, 해당 페이지의 모든 독서기록이 동일한
userBookId에 속하므로,UserBook을 한 번만 조회하여 모든 응답 DTO에 동일한 책 정보를 매핑해주었습니다.이 방식은 현재 요구사항에 효율적이며, 추후 여러 책의 독서기록을 한 번에 조회하는 기능이 생긴다면 추가적인 최적화가 필요할 수 있습니다.
Summary by CodeRabbit