Conversation
Walkthrough사용자 계정의 북마크된 콘텐츠 개수를 조회하는 새로운 API 엔드포인트를 추가합니다. 컨트롤러, 서비스, 저장소 계층과 DTO를 신규 생성하고 통합 테스트를 추가합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller as FavoriteContentController
participant Service as FavoriteContentService
participant Repository as FavoriteContentRepository
participant DB as Database
Client->>Controller: GET /api/v1/bookmarks/count
activate Controller
Controller->>Service: countByAccount(account)
activate Service
Service->>Repository: countByAccount(account)
activate Repository
Repository->>DB: COUNT favorite_content WHERE account_id = ?
activate DB
DB-->>Repository: count: int
deactivate DB
deactivate Repository
Service->>Service: FavoriteContentCountResponse.from(count)
deactivate Service
Controller-->>Client: ResponseEntity<FavoriteContentCountResponse> (200 OK)
deactivate Controller
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 분 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (4)
backend/turip-app/src/test/java/turip/favorite/api/FavoriteContentApiTest.java (2)
348-384: 북마크가 0개일 때count: 0을 반환하는 엣지 케이스 테스트가 없습니다.현재 테스트는 3개 북마크의 정상 경로만 검증하며, 계정에 북마크가 없을 때
count: 0이 정상 반환되는지 확인하는 테스트가 없습니다. 초기 상태 검증에 유용합니다.✅ 추가 테스트 예시
`@DisplayName`("북마크가 없을 때 200 OK와 count 0을 반환한다") `@Test` void readBookmarkCount_empty() { // given Long accountId = testDataHelper.insertAccount(); jdbcTemplate.update("INSERT INTO guest (account_id, device_fid) VALUES (?, 'testDeviceFid')", accountId); // when & then RestAssured.given().port(port) .header("device-fid", "testDeviceFid") .when().get("/api/v1/bookmarks/count") .then() .statusCode(200) .body("count", is(0)); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/turip-app/src/test/java/turip/favorite/api/FavoriteContentApiTest.java` around lines 348 - 384, Add an edge-case test in the ReadBookmarkCount nested class to verify zero bookmarks returns count:0; create a new test method (e.g., readBookmarkCount_empty) that inserts an account and guest row (using testDataHelper.insertAccount() and the same guest insert), does not insert any favorite_content rows, then calls GET /api/v1/bookmarks/count with the same "device-fid" header and asserts statusCode 200 and body "count" is 0; place it alongside readBookmarkCount1 so it runs as part of the same test suite.
354-354: 테스트 메서드 이름에서 불필요한 숫자 접미사1제거를 권장합니다.기존 테스트 메서드들(
readMyFavoriteContents_success,removeFavorite등)은 숫자 접미사를 사용하지 않습니다.readBookmarkCount1→readBookmarkCount_success로 변경하는 것이 일관성 있습니다.♻️ 제안 수정
- void readBookmarkCount1() { + void readBookmarkCount_success() {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/turip-app/src/test/java/turip/favorite/api/FavoriteContentApiTest.java` at line 354, Rename the test method readBookmarkCount1 to readBookmarkCount_success to match existing naming convention; update the method declaration in FavoriteContentApiTest (readBookmarkCount1) and any references/calls or annotations that mention the old name (e.g., `@Test`, `@DisplayName` or reflective references) so the test still runs and compiles, and run the tests to verify no further references remain.backend/turip-app/src/main/java/turip/favorite/service/FavoriteContentService.java (1)
68-71: 읽기 전용 트랜잭션 어노테이션 추가를 권장합니다.
countByAccount()는 순수 조회 메서드이므로@Transactional(readOnly = true)를 추가하면 불필요한 dirty checking을 방지하고 DB 드라이버 레벨 최적화 힌트를 활성화할 수 있습니다. 동일 서비스의findMyFavoriteContents와existsByAccount도 같은 이유로 추가를 고려해 볼 수 있습니다.♻️ 제안 수정
+ `@Transactional`(readOnly = true) public FavoriteContentCountResponse countByAccount(Account account) { int count = favoriteContentRepository.countByAccount(account); return FavoriteContentCountResponse.from(count); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/turip-app/src/main/java/turip/favorite/service/FavoriteContentService.java` around lines 68 - 71, Add read-only transaction annotations to the read-only methods in FavoriteContentService: annotate countByAccount(Account), findMyFavoriteContents(...), and existsByAccount(...) with `@Transactional`(readOnly = true) on their method declarations (or at class level with explicit overrides if needed) to prevent unnecessary dirty checking and enable DB-level read optimizations; ensure you import org.springframework.transaction.annotation.Transactional and only apply it to methods that perform pure reads.backend/turip-app/src/main/java/turip/favorite/repository/FavoriteContentRepository.java (1)
59-59:countBy파생 쿼리의 반환 타입은 관례적으로long입니다.Spring Data JPA의
countBy파생 쿼리는 내부적으로Long을 반환하며, 공식 문서에서도countBy메서드의 반환 타입을long으로 정의합니다.int를 사용하면 Spring Data가 묵시적 축소 변환을 수행하며, 실용적으로는 대부분의 경우 문제가 없지만 표준 규칙에서 벗어나며 충분히 큰 숫자의 경우 오버플로우 위험이 있습니다.♻️ 제안 수정
- int countByAccount(Account account); + long countByAccount(Account account);이에 맞춰
FavoriteContentCountResponse의count필드 타입과FavoriteContentService.countByAccount()메서드의 지역 변수 타입도 함께long으로 변경이 필요합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/turip-app/src/main/java/turip/favorite/repository/FavoriteContentRepository.java` at line 59, The repository method FavoriteContentRepository.countByAccount(Account account) currently returns int; change its return type to long to match Spring Data JPA conventions and avoid overflow, then update the FavoriteContentCountResponse DTO's count field from int to long and adjust the local variable type(s) in FavoriteContentService.countByAccount() accordingly so the service uses long throughout (update any mappings/constructors that set the DTO.count).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@backend/turip-app/src/main/java/turip/favorite/repository/FavoriteContentRepository.java`:
- Line 59: The repository method
FavoriteContentRepository.countByAccount(Account account) currently returns int;
change its return type to long to match Spring Data JPA conventions and avoid
overflow, then update the FavoriteContentCountResponse DTO's count field from
int to long and adjust the local variable type(s) in
FavoriteContentService.countByAccount() accordingly so the service uses long
throughout (update any mappings/constructors that set the DTO.count).
In
`@backend/turip-app/src/main/java/turip/favorite/service/FavoriteContentService.java`:
- Around line 68-71: Add read-only transaction annotations to the read-only
methods in FavoriteContentService: annotate countByAccount(Account),
findMyFavoriteContents(...), and existsByAccount(...) with
`@Transactional`(readOnly = true) on their method declarations (or at class level
with explicit overrides if needed) to prevent unnecessary dirty checking and
enable DB-level read optimizations; ensure you import
org.springframework.transaction.annotation.Transactional and only apply it to
methods that perform pure reads.
In
`@backend/turip-app/src/test/java/turip/favorite/api/FavoriteContentApiTest.java`:
- Around line 348-384: Add an edge-case test in the ReadBookmarkCount nested
class to verify zero bookmarks returns count:0; create a new test method (e.g.,
readBookmarkCount_empty) that inserts an account and guest row (using
testDataHelper.insertAccount() and the same guest insert), does not insert any
favorite_content rows, then calls GET /api/v1/bookmarks/count with the same
"device-fid" header and asserts statusCode 200 and body "count" is 0; place it
alongside readBookmarkCount1 so it runs as part of the same test suite.
- Line 354: Rename the test method readBookmarkCount1 to
readBookmarkCount_success to match existing naming convention; update the method
declaration in FavoriteContentApiTest (readBookmarkCount1) and any
references/calls or annotations that mention the old name (e.g., `@Test`,
`@DisplayName` or reflective references) so the test still runs and compiles, and
run the tests to verify no further references remain.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
backend/turip-app/src/main/java/turip/favorite/controller/FavoriteContentController.javabackend/turip-app/src/main/java/turip/favorite/controller/dto/response/FavoriteContentCountResponse.javabackend/turip-app/src/main/java/turip/favorite/repository/FavoriteContentRepository.javabackend/turip-app/src/main/java/turip/favorite/service/FavoriteContentService.javabackend/turip-app/src/test/java/turip/favorite/api/FavoriteContentApiTest.java
Issues
✔️ Check-list
🗒️ Work Description
📷 Screenshot
📚 Reference
Summary by CodeRabbit
릴리스 노트