[main ← Feature/top3] 좋아요 수 기준 랭킹 Top3 부스를 반환하는 API 작성#115
[main ← Feature/top3] 좋아요 수 기준 랭킹 Top3 부스를 반환하는 API 작성#115milk-stone merged 7 commits intoknu-80:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough상위 3개 부스 좋아요 랭킹을 반환하는 API와 이를 지원하는 서비스/레디스 조회 로직, 응답 DTO 및 Swagger 문서가 추가되었습니다. 컨트롤러는 서비스 호출로 결과를 반환합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API as "BoothApiController"
participant Query as "BoothQueryService"
participant LikeSvc as "BoothLikeService (Redis)"
participant Repo as "BoothRepository"
Client->>API: GET /ranking/top3
API->>Query: getTop3BoothRanking()
Query->>LikeSvc: getTopRanking(10)
LikeSvc-->>Query: ranking IDs + scores
Query->>Repo: findAllById(ranking IDs)
Repo-->>Query: Booth entities
Query->>Query: map -> BoothTop3ResponseDto, sort by likeCount desc, id asc, limit 3
Query-->>API: List<BoothTop3ResponseDto>
API-->>Client: 200 ApiResponse(List)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java (1)
100-123: 랭킹 변환/정렬 로직이 기존 메서드와 중복됩니다.
getBoothRanking()와getTop3BoothRanking()의 흐름이 거의 동일해서 이후 정렬 기준/필드 변경 시 동시 수정 누락 위험이 있습니다. 공통 private helper로 추출해 중복을 줄이는 편이 안전합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java` around lines 100 - 123, The getTop3BoothRanking() flow largely duplicates getBoothRanking(); extract a private helper (e.g., buildSortedBoothDtoList or toBoothTopResponses) that accepts the ranking source (either Set<ZSetOperations.TypedTuple<String>> rawRanking or a BoothRanking) plus an optional limit, does the null/empty checks, loads booths via boothRepository.findAllById, maps to BoothTop3ResponseDto using BoothRanking.getLikeCount, sorts by likeCount desc then boothId asc, and returns the resulting List; then replace the body of getTop3BoothRanking() and getBoothRanking() to call that helper with the appropriate ranking input and limit (3 for top3) to remove duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java`:
- Around line 101-122: The Top3 endpoint currently fetches the entire ranking
and all booth rows, causing unnecessary load; change BoothQueryService to call a
new limited Redis fetch (use boothLikeService.getTopRanking(3) instead of
getRanking()), construct BoothRanking from that limited set, collect only the
top N booth IDs, query the DB for only those IDs (use a repository method that
takes a List of IDs, e.g., boothRepository.findAllByIdIn or findByIdIn), then
map those results back to BoothTop3ResponseDto using
BoothRanking.getLikeCount(...) and preserve ordering by sorting according to the
limited ranking (or by using the ranking order) before returning the top 3.
Ensure any helper BoothRanking constructor/usage supports the reduced set and
keep mapping via BoothTop3ResponseDto(booth.getId(), booth.getName(),
boothRanking.getLikeCount(booth.getId())).
---
Nitpick comments:
In `@src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java`:
- Around line 100-123: The getTop3BoothRanking() flow largely duplicates
getBoothRanking(); extract a private helper (e.g., buildSortedBoothDtoList or
toBoothTopResponses) that accepts the ranking source (either
Set<ZSetOperations.TypedTuple<String>> rawRanking or a BoothRanking) plus an
optional limit, does the null/empty checks, loads booths via
boothRepository.findAllById, maps to BoothTop3ResponseDto using
BoothRanking.getLikeCount, sorts by likeCount desc then boothId asc, and returns
the resulting List; then replace the body of getTop3BoothRanking() and
getBoothRanking() to call that helper with the appropriate ranking input and
limit (3 for top3) to remove duplication.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 8fd0ace3-d345-445d-a7c6-685e87214064
📒 Files selected for processing (4)
src/main/java/kr/co/knuserver/application/booth/BoothQueryService.javasrc/main/java/kr/co/knuserver/presentation/booth/BoothApiController.javasrc/main/java/kr/co/knuserver/presentation/booth/docs/BoothApiControllerDocs.javasrc/main/java/kr/co/knuserver/presentation/booth/dto/BoothTop3ResponseDto.java
| Set<ZSetOperations.TypedTuple<String>> rawRanking = boothLikeService.getRanking(); | ||
| if (rawRanking == null || rawRanking.isEmpty()) { | ||
| return List.of(); | ||
| } | ||
|
|
||
| BoothRanking boothRanking = new BoothRanking(rawRanking); | ||
| if (boothRanking.isEmpty()) { | ||
| return List.of(); | ||
| } | ||
|
|
||
| List<Booth> booths = boothRepository.findAllById(boothRanking.boothIds()); | ||
|
|
||
| return booths.stream() | ||
| .map(booth -> new BoothTop3ResponseDto( | ||
| booth.getId(), | ||
| booth.getName(), | ||
| boothRanking.getLikeCount(booth.getId()) | ||
| )) | ||
| .sorted(Comparator.comparingLong(BoothTop3ResponseDto::likeCount).reversed() | ||
| .thenComparingLong(BoothTop3ResponseDto::boothId)) | ||
| .limit(3) | ||
| .toList(); |
There was a problem hiding this comment.
Top3 API가 전체 랭킹/전체 부스를 읽어 확장 시 병목이 됩니다.
Line [101]에서 전체 랭킹을 가져오고, Line [111]에서 전체 ID를 DB 조회한 뒤 마지막에 3개만 자르고 있습니다. Top3 전용 API라서 요청당 비용이 불필요하게 큽니다.
⚡ 제안 수정안 (Top N만 조회하도록 경로 축소)
- Set<ZSetOperations.TypedTuple<String>> rawRanking = boothLikeService.getRanking();
+ // 예: Redis에서 상위 후보만 조회 (여유 버퍼 포함)
+ Set<ZSetOperations.TypedTuple<String>> rawRanking = boothLikeService.getTopRanking(10);// BoothLikeService 쪽 예시 (별도 파일 변경)
public Set<ZSetOperations.TypedTuple<String>> getTopRanking(int limit) {
try {
return redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, limit - 1);
} catch (DataAccessException e) {
log.warn("[Ranking] Redis 조회 실패, 빈 셋 반환", e);
return Collections.emptySet();
}
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java`
around lines 101 - 122, The Top3 endpoint currently fetches the entire ranking
and all booth rows, causing unnecessary load; change BoothQueryService to call a
new limited Redis fetch (use boothLikeService.getTopRanking(3) instead of
getRanking()), construct BoothRanking from that limited set, collect only the
top N booth IDs, query the DB for only those IDs (use a repository method that
takes a List of IDs, e.g., boothRepository.findAllByIdIn or findByIdIn), then
map those results back to BoothTop3ResponseDto using
BoothRanking.getLikeCount(...) and preserve ordering by sorting according to the
limited ranking (or by using the ranking order) before returning the top 3.
Ensure any helper BoothRanking constructor/usage supports the reduced set and
keep mapping via BoothTop3ResponseDto(booth.getId(), booth.getName(),
boothRanking.getLikeCount(booth.getId())).
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/main/java/kr/co/knuserver/application/booth/BoothLikeService.java (1)
74-81:limit경계값 검증을 추가해 주세요.Line [76]에서
limit - 1을 바로 사용하고 있어,limit <= 0입력 시 의도하지 않은 범위 조회가 발생할 수 있습니다. 메서드 초입에서 방어 로직을 두는 편이 안전합니다.제안 코드
public Set<ZSetOperations.TypedTuple<String>> getTopRanking(int limit) { + if (limit <= 0) { + return Collections.emptySet(); + } try { return redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, limit - 1); } catch (DataAccessException e) { log.warn("[Ranking] Redis 조회 실패, 빈 셋 반환", e); return Collections.emptySet(); } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/kr/co/knuserver/application/booth/BoothLikeService.java` around lines 74 - 81, The getTopRanking method uses limit - 1 directly which yields incorrect ranges for limit <= 0; add a defensive check at the start of getTopRanking to handle non-positive limits (e.g., if limit <= 0 return Collections.emptySet()) and only call redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, limit - 1) when limit is positive, preserving the existing DataAccessException catch and log.src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java (1)
101-101: 후보 버퍼 값10은 상수로 분리하는 것을 권장합니다.Line [101] 매직넘버를 상수화하면 의도 전달과 운영 튜닝이 쉬워집니다.
제안 코드
public class BoothQueryService { + private static final int TOP3_CANDIDATE_LIMIT = 10; private final BoothRepository boothRepository; private final BoothImageRepository boothImageRepository; private final BoothLikeService boothLikeService; @@ public List<BoothTop3ResponseDto> getTop3BoothRanking() { - Set<ZSetOperations.TypedTuple<String>> rawRanking = boothLikeService.getTopRanking(10); + Set<ZSetOperations.TypedTuple<String>> rawRanking = boothLikeService.getTopRanking(TOP3_CANDIDATE_LIMIT); if (rawRanking == null || rawRanking.isEmpty()) { return List.of(); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java` at line 101, The literal 10 passed to boothLikeService.getTopRanking(...) is a magic number; introduce a descriptive constant (e.g., TOP_RANKING_LIMIT) in BoothQueryService and replace the literal with that constant when calling getTopRanking to improve readability and make tuning easier; optionally consider making it a configurable property if runtime adjustment is needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/main/java/kr/co/knuserver/application/booth/BoothLikeService.java`:
- Around line 74-81: The getTopRanking method uses limit - 1 directly which
yields incorrect ranges for limit <= 0; add a defensive check at the start of
getTopRanking to handle non-positive limits (e.g., if limit <= 0 return
Collections.emptySet()) and only call
redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, limit - 1)
when limit is positive, preserving the existing DataAccessException catch and
log.
In `@src/main/java/kr/co/knuserver/application/booth/BoothQueryService.java`:
- Line 101: The literal 10 passed to boothLikeService.getTopRanking(...) is a
magic number; introduce a descriptive constant (e.g., TOP_RANKING_LIMIT) in
BoothQueryService and replace the literal with that constant when calling
getTopRanking to improve readability and make tuning easier; optionally consider
making it a configurable property if runtime adjustment is needed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 6e9f09f6-8320-4bd1-8b4c-67241ecf3cb5
📒 Files selected for processing (2)
src/main/java/kr/co/knuserver/application/booth/BoothLikeService.javasrc/main/java/kr/co/knuserver/application/booth/BoothQueryService.java
# Conflicts: # src/main/java/kr/co/knuserver/application/booth/BoothLikeService.java
✨ 구현한 기능
📢 논의하고 싶은 내용
🎸 기타
Summary by CodeRabbit