Skip to content

Test#84

Open
kjh0718 wants to merge 14 commits intomainfrom
test
Open

Test#84
kjh0718 wants to merge 14 commits intomainfrom
test

Conversation

@kjh0718
Copy link
Contributor

@kjh0718 kjh0718 commented Feb 6, 2026

✨ 변경 사항


✅ 테스트


  • 수동 테스트 완료
  • 테스트 코드 완료

Summary by CodeRabbit

  • 새로운 기능

    • 카페테리아별 인기 메뉴 Top 3 조회 추가(레디스 기반)
    • 메뉴 이미지 업로드 기능 추가
    • 개별 메뉴 조회 및 카페테리아별 전체 메뉴 조회 API 추가
    • 메뉴 응답에 cafeteriaId 필드 추가
  • 문서

    • 인기 메뉴 조회 API 설명(스웨거) 추가
  • 기타

    • 주문 기반 순위 집계용 레디스 연동 스캐폴딩 추가(해당 집계 로직은 비활성화 상태)

@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

Warning

Rate limit exceeded

@kjh0718 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 59 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

메뉴 관련 엔드포인트(단건 조회, 구내별 목록, 구내별 상위 3개, 이미지 업로드)와 TopMenuResponse DTO가 추가되었고, 메뉴 생성 및 상위 조회를 위한 Redis ZSet(ranking) 연동 및 관련 서비스 로직이 도입되었습니다. MenuResponse에 cafeteriaId 필드가 추가되었습니다.

Changes

Cohort / File(s) Summary
Menu Controller
src/main/java/com/campustable/be/domain/menu/controller/MenuController.java, src/main/java/com/campustable/be/domain/menu/controller/MenuControllerDocs.java
getMenuById, getAllMenusByCafeteriaId, getTop3MenusByCafeteriaId, uploadMenuImage 엔드포인트 및 Swagger 문서(TopMenuResponse 포함) 추가.
Menu DTOs
src/main/java/com/campustable/be/domain/menu/dto/MenuResponse.java, src/main/java/com/campustable/be/domain/menu/dto/TopMenuResponse.java, src/main/java/com/campustable/be/domain/menu/dto/MenuRequest.java
MenuResponsecafeteriaId 필드 추가 및 생성자 변경, TopMenuResponse 신규 DTO(순위 + MenuResponse) 추가, MenuRequest 포맷팅 미세 조정.
Menu Service
src/main/java/com/campustable/be/domain/menu/service/MenuService.java
메뉴 생성 시 Redis ZSet 초기화(cafeteria:{id}:menu:rank에 menuId score 0.0 추가) 및 Redis에서 상위 3개 조회해 TopMenuResponse 목록 반환하는 getTop3MenusByCafeteriaId 구현 추가.
Order Service (partial / scaffolding)
src/main/java/com/campustable/be/domain/order/service/OrderService.java
Redis 관련 필드 및 주석 처리된 랭킹 업데이트 스캐폴딩(트랜잭션 동기화 콜백 관련 코드 일부 주석).
Wiring / Dependencies
.../MenuController.java, .../MenuService.java, .../OrderService.java
StringRedisTemplate 주입 및 Redis 연산 사용, TopMenuResponse 타입 도입. 중앙 로직 변경은 Service 레이어와 DTO 교체에 집중됨.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as MenuController
    participant Service as MenuService
    participant Redis
    participant DB as Database

    Client->>Controller: GET /cafeteria/{id}/top-menus
    Controller->>Service: getTop3MenusByCafeteriaId(cafeteriaId)
    Service->>DB: verify cafeteria exists
    DB-->>Service: exists
    Service->>Redis: ZREVRANGE cafeteria:{id}:menu:rank 0 2
    Redis-->>Service: list of menuIds
    Service->>DB: fetch menus by IDs
    DB-->>Service: Menu entities
    Service->>Service: convert Menu -> MenuResponse -> TopMenuResponse
    Service-->>Controller: List<TopMenuResponse>
    Controller-->>Client: 200 OK
Loading
sequenceDiagram
    participant Client
    participant OrderSvc as OrderService
    participant DB as Database
    participant TxSync as TransactionSynchronization
    participant MenuSvc as MenuService
    participant Redis

    Client->>OrderSvc: create order request
    OrderSvc->>DB: save order (transaction)
    OrderSvc->>TxSync: register afterCommit callback (ranking payload)
    DB-->>OrderSvc: commit
    TxSync->>MenuSvc: updateMenuRanking(rankingDtos)
    MenuSvc->>Redis: ZINCRBY cafeteria:{id}:menu:rank quantity menuId
    Redis-->>MenuSvc: score updated
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

feat

Poem

🐰 깡충, 메뉴가 순위로 줄 서네,
당근으로 박수 쳐요, Redis 위 점수 춤추네.
상위 셋 불러왔더니 주방이 활짝 웃고,
작은 랭킹이 큰 맛의 이야길 하네.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning PR 제목 'Test'는 실제 변경사항을 설명하지 못하며, 메뉴 API 엔드포인트 추가, Redis 기반 순위 시스템, 새로운 DTO 클래스 등 광범위한 변경사항을 반영하지 않습니다. PR 제목을 '메뉴 API 엔드포인트 추가 및 Redis 기반 순위 시스템 구현' 또는 유사하게 실제 주요 변경사항을 구체적으로 설명하는 내용으로 변경하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test

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

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/campustable/be/domain/menu/service/MenuService.java (1)

197-213: ⚠️ Potential issue | 🟠 Major

메뉴 삭제 시 Redis 랭킹 데이터 미정리

deleteMenu에서 DB의 메뉴는 삭제하지만 Redis sorted set(cafeteria:<id>:menu:rank)의 해당 멤버는 제거하지 않습니다. 삭제된 메뉴가 상위 랭킹을 차지하고 있으면, getTop3MenusByCafeteriaId에서 null 체크로 건너뛰게 되어 3개 미만의 결과가 반환될 수 있습니다.

🛠️ 수정 제안
   public void deleteMenu(Long menuId) {

     Optional<Menu> menu = menuRepository.findById(menuId);
     if (menu.isEmpty()) {
       log.error("menuId not found {}", menuId);
       throw new CustomException(ErrorCode.MENU_NOT_FOUND);
     }
+    // Redis 랭킹에서 제거
+    try {
+      Long cafeteriaId = menu.get().getCategory().getCafeteria().getCafeteriaId();
+      String key = "cafeteria:" + cafeteriaId + ":menu:rank";
+      stringRedisTemplate.opsForZSet().remove(key, String.valueOf(menuId));
+    } catch (Exception e) {
+      log.warn("deleteMenu: Redis 랭킹 제거 실패. menuId={}", menuId, e);
+    }
     if (menu.get().getMenuUrl() != null && !menu.get().getMenuUrl().isBlank()) {
🤖 Fix all issues with AI agents
In `@src/main/java/com/campustable/be/domain/order/service/OrderService.java`:
- Around line 74-79: The afterCommit callback registered via
TransactionSynchronizationManager.registerSynchronization calls
updateMenuRanking and accesses lazy associations
(menu.getCategory().getCafeteria()) outside the transaction causing
LazyInitializationException; fix by collecting the needed primitives inside the
transaction (e.g., cafeteriaId, menuId, quantity) while still in the
transactional method in OrderService (before
TransactionSynchronizationManager.registerSynchronization) and pass that
collection (List/DTO of ids and counts) into the
TransactionSynchronization.afterCommit so updateMenuRanking consumes only those
IDs/quantities instead of dereferencing menu.getCategory()/Category.cafeteria
after the session is closed.
🧹 Nitpick comments (3)
src/main/java/com/campustable/be/domain/menu/service/MenuService.java (2)

216-217: @Transactional(readOnly = true)로 변경 권장

이 메서드는 DB에 쓰기 작업이 없으므로 readOnly = true를 설정하여 Hibernate 플러시 모드 최적화 및 읽기 전용 커넥션 라우팅 혜택을 받을 수 있습니다.

♻️ 수정 제안
-  `@Transactional`
+  `@Transactional`(readOnly = true)
   public List<TopMenuResponse> getTop3MenusByCafeteriaId(Long cafeteriaId) {

223-239: reverseRange의 반환 타입 Set<String>은 순서 보장이 명시적이지 않음

reverseRange는 내부적으로 LinkedHashSet을 반환하여 순서가 유지되지만, API 시그니처상 Set<String>이므로 이 동작에 의존하는 것은 다소 취약합니다. reverseRangeWithScores를 사용하면 순서와 점수를 동시에 얻을 수 있어 더 안전하고, 실제 점수 기반 랭킹도 가능합니다.

src/main/java/com/campustable/be/domain/menu/controller/MenuController.java (1)

60-67: REST 경로가 리소스 의미와 불일치

GET /api/cafeteria/{cafeteria-id}List<MenuResponse>를 반환하지만, URL만 보면 식당 상세 정보를 반환할 것처럼 보입니다. 리소스를 명확히 나타내기 위해 /cafeteria/{cafeteria-id}/menus로 변경하는 것을 권장합니다.

♻️ 수정 제안
-  `@GetMapping`("/cafeteria/{cafeteria-id}")
+  `@GetMapping`("/cafeteria/{cafeteria-id}/menus")

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

🤖 Fix all issues with AI agents
In `@src/main/java/com/campustable/be/domain/order/service/OrderService.java`:
- Line 40: OrderService currently has an unused dependency field
stringRedisTemplate injected via `@RequiredArgsConstructor`; remove the private
final StringRedisTemplate stringRedisTemplate field (and any related
commented-out usages) so Spring won't require a StringRedisTemplate bean at
startup, and reintroduce the field only when the commented functionality is
re-enabled; ensure the class-level `@RequiredArgsConstructor` remains correct
after removing the field.
🧹 Nitpick comments (1)
src/main/java/com/campustable/be/domain/order/service/OrderService.java (1)

42-104: 주석 처리된 코드 블록 제거 권장

createOrder, updateMenuRanking, RankingDto 등 약 60줄의 코드가 주석 처리되어 있습니다. 이 코드는 Git 히스토리에서 추적할 수 있으므로, 소스 파일에 남겨둘 필요가 없습니다. 주석 처리된 코드는 가독성을 떨어뜨리고, 사용하지 않는 import/필드 의존성을 유발합니다.

기능이 준비되지 않았다면 feature branch에서 개발 후 병합하거나, 필요한 경우 TODO/이슈로 추적하는 것이 좋습니다.

}

public void updateCategoryToReady(Long orderId,Long categoryId) {
private final StringRedisTemplate stringRedisTemplate;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

사용되지 않는 stringRedisTemplate 의존성이 생성자 주입됨

@RequiredArgsConstructor로 인해 stringRedisTemplate이 생성자 매개변수로 주입됩니다. 현재 이 필드를 사용하는 코드가 모두 주석 처리되어 있으므로, Spring 컨텍스트에 StringRedisTemplate 빈이 반드시 존재해야 하는 불필요한 의존성이 생깁니다. 빈이 없으면 애플리케이션 시작 시 실패하고, 있더라도 사용되지 않는 의존성을 강제합니다.

주석 처리된 코드와 함께 이 필드도 제거하고, 기능 활성화 시 다시 추가하는 것을 권장합니다.

🔧 수정 제안
-  private final StringRedisTemplate stringRedisTemplate;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private final StringRedisTemplate stringRedisTemplate;
🤖 Prompt for AI Agents
In `@src/main/java/com/campustable/be/domain/order/service/OrderService.java` at
line 40, OrderService currently has an unused dependency field
stringRedisTemplate injected via `@RequiredArgsConstructor`; remove the private
final StringRedisTemplate stringRedisTemplate field (and any related
commented-out usages) so Spring won't require a StringRedisTemplate bean at
startup, and reintroduce the field only when the commented functionality is
re-enabled; ensure the class-level `@RequiredArgsConstructor` remains correct
after removing the field.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant