Skip to content

[FEAT] 푸드트럭 메뉴 조회 API 구현#38

Merged
ksg1227 merged 8 commits intodevelopfrom
feat/#36-get-food-truck-menus
Oct 5, 2025
Merged

[FEAT] 푸드트럭 메뉴 조회 API 구현#38
ksg1227 merged 8 commits intodevelopfrom
feat/#36-get-food-truck-menus

Conversation

@ksg1227
Copy link
Contributor

@ksg1227 ksg1227 commented Oct 2, 2025

#️⃣연관된 이슈

closes #36

📝작업 내용

푸드트럭 메뉴 조회 API 를 구현하였습니다.

사장님 - 나의 푸드트럭 메뉴 조회 API 와 로직이 사실상 동일해서 별 이슈는 없었습니다.
다만 한 가지 고려해야할 점이 있었는데, 사장님이 만약 메뉴들을 비공개 처리해두었다면, 해당 메뉴들은 다른 고객, 혹은 사용자들에게 보여져서는 안됩니다.
따라서 MenuViewedStatus 를 기반으로 'ON' (표시) 상태인 메뉴들만 화면에 보여질 수 있도록 구현하였습니다.

스크린샷 2025-10-02 오후 11 17 47 스크린샷 2025-10-02 오후 11 18 02

위 예시는 2번 푸드트럭의 메뉴를 조회한 상황인데, 현재 DB의 데이터를 확인해보면, 2번 푸드트럭에 대해서 menuId = 7 (하와이안 피자) 가 존재하는 것을 볼 수 있습니다.
하지만 menuViewedStatus 가 'OFF' 로 설정되어있어서, 실제 조회시에는 해당 데이터가 조회되지 않는 모습을 확인할 수 있습니다.

워낙 간단해서 가볍게 훑고만 넘어가도 될 것 같슴다

스크린샷 (선택)

💬리뷰 요구사항(선택)

Summary by CodeRabbit

  • 신기능
    • 푸드트럭 메뉴 목록 조회 API 추가: GET /{foodTruckId}/menus (커서 페이징, 정렬: 최신/오래된). 메뉴 ID·이름·가격·설명·이미지 제공.
    • 푸드트럭 목록에 '저장됨(isSaved)' 표기 추가.
  • 문서
    • 메뉴 조회 요청/응답 및 오류(USER_NOT_FOUND, USER_FORBIDDEN, FOOD_TRUCK_NOT_FOUND) Swagger 반영.
  • 변경
    • 검색 키워드 필터 제거로 검색 요청 파라미터 축소(키워드 필드 삭제).
    • 승인 상태 예시 값 수정(ON → OFF).
  • 작업
    • 사장님용 메뉴 조회 DTO 명칭 정리 및 저장된 푸드트럭 조회 지원 추가.

@ksg1227 ksg1227 requested a review from buzz0331 October 2, 2025 14:21
@ksg1227 ksg1227 linked an issue Oct 2, 2025 that may be closed by this pull request
1 task
@coderabbitai
Copy link

coderabbitai bot commented Oct 2, 2025

Walkthrough

푸드트럭 메뉴 조회 API가 추가되었습니다. 컨트롤러에 GET /{foodTruckId}/menus 엔드포인트가 생성되고, FoodTruckMenuService가 도입되어 FoodTruckService가 위임합니다. 메뉴 가시성(ON) 기준의 커서 기반 페이징 쿼리와 관련 DTO, Swagger 응답 설명 및 일부 요청/응답 시그니처 변경이 포함됩니다.

Changes

Cohort / File(s) Change Summary
Public 메뉴 조회 API (Controller / Service / DTO)
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java, src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java, src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java, src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckMenuRequest.java, src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java
GET /{foodTruckId}/menus 엔드포인트 추가; FoodTruckMenuService 신규 도입 및 FoodTruckService에 의존성/위임 메서드 추가; 요청/응답 DTO 및 Menu→DTO 매핑 구현
Repository (메뉴 커서 페이징 / 가시성)
src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java
메뉴 가시성(ON) 기준 커서 페이징용 메서드 2종 추가: findVisibleMenusDesc(내림차순), findVisibleMenusAsc(오름차순)
Response 설명 (Swagger)
src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java
GET_FOOD_TRUCK_MENUS 응답 설명 항목 추가(관련 에러코드: USER_NOT_FOUND, USER_FORBIDDEN, FOOD_TRUCK_NOT_FOUND)
오너 메뉴 조회 DTO/시그니처 명칭 변경
src/main/java/konkuk/chacall/domain/owner/presentation/OwnerController.java, src/main/java/konkuk/chacall/domain/owner/application/OwnerService.java, src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java, src/main/java/konkuk/chacall/domain/owner/presentation/dto/request/MyFoodTruckMenuRequest.java
요청 레코드명 MyFoodTruckMenuListRequestMyFoodTruckMenuRequest로 변경 및 관련 메서드 시그니처 갱신
Saved 상태 반영 (FoodTruck 목록)
src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java, src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java, src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java
FoodTruckResponseisSaved 필드 추가; FoodTruckCommandServicememberId 인자 추가 및 저장된 트럭 ID 조회 후 isSaved 플래그 포함; SavedFoodTruckRepositoryfindSavedTruckIdsIn 추가
검색 키워드 제거
src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java, src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java
푸드트럭 검색에서 keyword 필드 및 키워드 기반 필터링 로직 제거
사소한 변경 (Swagger 예시)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/ApproveFoodTruckStatusRequest.java
Swagger 예시값 변경: status 필드 예시를 "ON""OFF"로 수정

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant FC as FoodTruckController
  participant FS as FoodTruckService
  participant FMS as FoodTruckMenuService
  participant MR as MenuRepository

  C->>FC: GET /foodtrucks/{foodTruckId}/menus?sort&cursor...
  FC->>FS: getFoodTruckMenus(memberId, foodTruckId, request)
  FS->>FS: 회원 검증(필요 시)
  FS->>FMS: getFoodTruckMenus(foodTruckId, request)
  alt sort = NEWEST
    FMS->>MR: findVisibleMenusDesc(foodTruckId, lastCursor, pageable)
  else sort = OLDEST
    FMS->>MR: findVisibleMenusAsc(foodTruckId, lastCursor, pageable)
  end
  MR-->>FMS: Slice<Menu>
  FMS->>FMS: Menu → FoodTruckMenuResponse 매핑, hasNext 계산
  FMS-->>FS: CursorPagingResponse<FoodTruckMenuResponse>
  FS-->>FC: CursorPagingResponse 래핑
  FC-->>C: BaseResponse<CursorPagingResponse<...>>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • buzz0331

Poem

"새 메뉴에 깡충, 토끼가 방긋🐇
컨트롤러 부르면 서비스가 달려와,
레포는 보이는 것만 골라주고,
커서가 굴러 페이지를 이어가며,
저장된 트럭도 찰칵, 내 리스트에 반짝🥕"

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning PR에는 메뉴 조회 API 구현과 직접 관련 없는 푸드트럭 검색 기능 수정, 키워드 필터링 제거, 즐겨찾기 상태 추가, 저장소 쿼리 메서드 도입 등의 변경이 포함되어 있어 주 이슈 범위를 벗어납니다. 특히 FoodTruckSearchRequest와 SearchRepositoryImpl 변경, FoodTruckResponse isSaved 필드 추가 및 SavedFoodTruckRepository 도입은 메뉴 조회 기능과 무관합니다. 이러한 변경은 별도 기능 향상 PR에서 다루는 것이 바람직합니다. 현재 PR에서는 관련 없는 수정 사항을 분리하여 관리할 것을 권장합니다. 메뉴 조회 API 구현과 무관한 변경은 별도 PR로 분리하거나 제거해 주시기 바랍니다.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed PR 제목 “[FEAT] 푸드트럭 메뉴 조회 API 구현”은 변경된 주요 기능인 메뉴 조회 API 구현을 간결하고 명확하게 요약하고 있어 파일 목록이나 불필요한 구문 없이 핵심을 잘 전달합니다. 접두어 [FEAT]로 새 기능임을 분명히 표시하며 주요 변경 사항을 정확히 반영합니다. 제목이 명확하여 히스토리 검색 시에도 한눈에 파악할 수 있습니다.
Linked Issues Check ✅ Passed 이 PR은 #36 이슈에서 요구한 푸드트럭 메뉴 조회 API를 서비스, 컨트롤러, 레포지토리, DTO 레이어에 걸쳐 완전하게 구현하고 있습니다. 메뉴ViewedStatus=ON 필터링, 커서 기반 페이징 및 정렬 처리, 엔티티 조회 예외 처리 로직이 모두 포함되어 있습니다. 스웨거 주석과 유효성 검증도 적절히 적용되어 API 사양을 준수합니다. 따라서 이슈의 구현 과제를 모두 충족합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#36-get-food-truck-menus

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

🧹 Nitpick comments (8)
src/main/java/konkuk/chacall/domain/owner/presentation/OwnerController.java (1)

14-15: 미사용 import 문 확인 필요

OwnerControllerfoodtruck.presentation.dto 패키지의 타입들이 import되어 있으나, 실제 코드에서 사용되지 않는 것으로 보입니다. 이 controller는 owner.presentation.dto의 타입들만 사용해야 합니다.

미사용 import는 코드 가독성을 저해하므로 제거를 권장합니다.

src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (2)

14-15: 미사용 import 문 제거 권장

FoodTruckController에서 owner.presentation.dto 패키지의 타입들이 import되어 있으나 사용되지 않습니다. Food truck controller는 자체 도메인의 DTO만 사용해야 합니다.

불필요한 import는 제거해주세요.


14-15: 사용하지 않는 import 제거 권장

MyFoodTruckMenuRequestMyFoodTruckMenuResponse는 오너 전용 DTO이며, 이 컨트롤러에서는 사용되지 않습니다. 불필요한 import를 제거하세요.

-import konkuk.chacall.domain.owner.presentation.dto.request.MyFoodTruckMenuRequest;
-import konkuk.chacall.domain.owner.presentation.dto.response.MyFoodTruckMenuResponse;
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (2)

4-9: 사용하지 않는 import 제거 권장

다음 import들이 코드에서 사용되지 않는 것으로 보입니다:

  • FoodTruckRepository (Line 4)
  • FoodTruckStatus (Line 6)
  • MyFoodTruckMenuResponse (Line 9)

다음 diff를 적용하여 사용하지 않는 import를 제거하세요:

-import konkuk.chacall.domain.foodtruck.domain.repository.FoodTruckRepository;
-import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckStatus;
-import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckMenuResponse;
-import konkuk.chacall.domain.owner.presentation.dto.response.MyFoodTruckMenuResponse;
+import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckMenuResponse;

4-4: 선택적: 사용하지 않는 import 제거 고려

다음 import들이 코드에서 사용되지 않는 것으로 보입니다:

  • FoodTruckRepository (line 4)
  • FoodTruckStatus (line 6)
  • MyFoodTruckMenuResponse (line 9)
  • BusinessException, ErrorCode (lines 13-14)

코드 가독성 향상을 위해 제거를 고려해보세요.

Also applies to: 6-6, 9-9, 13-14

src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)

42-46: 푸드트럭 존재 여부 검증 로직 추가 고려
getFoodTruckMenus에서 foodTruckId 유효성/존재 여부를 확인하지 않아, 잘못된 ID 호출 시 빈 결과만 반환됩니다. 404 에러 응답 또는 명시적 에러 핸들링 로직 도입을 검토하세요.

src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckMenuRequest.java (1)

10-27: 코드 중복: MyFoodTruckMenuRequest와 동일한 구조

FoodTruckMenuRequestMyFoodTruckMenuRequest(오너용)와 필드 구조, 어노테이션, 검증 로직이 완전히 동일합니다. 이는 코드 중복입니다.

옵션 1 (권장): 두 DTO를 공통 모듈로 통합하여 중복을 제거하세요. 예: MenuListRequestglobal.common.dto 패키지에 배치하고 오너와 고객 API 모두에서 재사용합니다.

옵션 2: 향후 오너용과 고객용 요청이 달라질 가능성이 있다면, 현재의 분리를 유지하되 이 결정을 문서화하세요.

옵션 1 적용 예시:

global.common.dto 패키지에 공통 요청 타입을 생성:

package konkuk.chacall.global.common.dto;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;

@Schema(description = "메뉴 목록 조회 요청")
public record MenuListRequest(
        @Parameter(
                description = "정렬 기준",
                example = "최신순",
                required = false,
                allowEmptyValue = true,
                schema = @Schema(
                        type = "string",
                        allowableValues = {"최신순", "오래된순"},
                        defaultValue = "최신순"
                )
        )
        SortType sort,

        @Valid
        CursorPagingRequest cursorPagingRequest
) implements HasPaging {}

그런 다음 오너와 푸드트럭 컨트롤러/서비스에서 이 공통 타입을 사용하세요.

src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java (1)

42-64: 선택적: 파라미터 바인딩 사용 고려

새로 추가된 visible 메뉴 조회 쿼리들이 올바르게 구현되었습니다. menuViewedStatus = ON 필터링이 정확하게 적용되어 비공개 메뉴를 제외합니다.

다만, JPQL에서 enum을 완전한 경로(konkuk.chacall.domain.foodtruck.domain.value.MenuViewedStatus.ON)로 직접 참조하는 대신, 파라미터 바인딩을 사용하면 가독성이 향상됩니다:

@Query("""
    select m
    from Menu m
    where m.foodTruck.foodTruckId = :foodTruckId
      and m.menuViewedStatus = :status
      and m.menuId < :lastCursor
    order by m.menuId desc
    """)
Slice<Menu> findVisibleMenusDesc(@Param("foodTruckId") Long foodTruckId,
                                 @Param("status") MenuViewedStatus status,
                                 @Param("lastCursor") Long lastCursor,
                                 Pageable pageable);

호출 시: findVisibleMenusDesc(foodTruckId, MenuViewedStatus.ON, lastCursor, pageable)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73ff8d6 and a4566fb.

📒 Files selected for processing (11)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (3 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckMenuRequest.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/owner/application/OwnerService.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/owner/presentation/OwnerController.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/owner/presentation/dto/request/MyFoodTruckMenuRequest.java (1 hunks)
  • src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
  • RequiredArgsConstructor (18-49)
🔇 Additional comments (19)
src/main/java/konkuk/chacall/domain/owner/presentation/dto/request/MyFoodTruckMenuRequest.java (2)

11-27: LGTM!

레코드명 변경이 깔끔하게 적용되었습니다. MyFoodTruckMenuRequest로 단순화된 이름이 FoodTruckMenuRequest와 일관성을 유지하며 더 명확합니다.


11-11: LGTM! 명명 개선

MyFoodTruckMenuListRequest에서 MyFoodTruckMenuRequest로의 이름 변경이 더 간결하고 명확합니다.

src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java (3)

8-8: LGTM!

import 문이 변경된 DTO명과 일치하도록 올바르게 업데이트되었습니다.


32-32: LGTM!

메서드 시그니처가 변경된 요청 타입을 정확하게 반영하고 있습니다.


8-8: LGTM! 시그니처 업데이트 일관성 유지

MyFoodTruckMenuRequest를 사용하도록 import와 메서드 시그니처가 올바르게 업데이트되었습니다.

Also applies to: 32-32

src/main/java/konkuk/chacall/domain/owner/presentation/OwnerController.java (2)

207-207: LGTM!

파라미터 타입이 변경된 DTO와 일치하도록 올바르게 업데이트되었습니다.


207-207: LGTM! 파라미터 타입 업데이트

컨트롤러가 새로운 MyFoodTruckMenuRequest 타입을 올바르게 사용하도록 업데이트되었습니다.

src/main/java/konkuk/chacall/domain/owner/application/OwnerService.java (3)

4-4: LGTM!

import 문이 변경된 DTO명에 맞게 정확히 업데이트되었습니다.


141-141: LGTM!

메서드 시그니처가 변경된 요청 타입을 올바르게 반영하고 있으며, 서비스 위임 로직도 유지되고 있습니다.


4-4: LGTM! 서비스 레이어 일관성

MyFoodTruckMenuRequest를 사용하도록 import와 메서드 시그니처가 일관되게 업데이트되었습니다.

Also applies to: 141-141

src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java (2)

7-28: LGTM!

응답 DTO의 구조가 명확하고 잘 설계되었습니다. Swagger 어노테이션을 통한 API 문서화도 적절하며, 팩토리 메서드를 통한 도메인 → DTO 변환 로직도 깔끔합니다.


1-29: LGTM! 응답 DTO 구조 적절

메뉴 응답 DTO가 명확한 필드 구조와 팩토리 메서드를 갖추고 있으며, Swagger 문서화도 잘 작성되었습니다.

src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (2)

62-73: 서비스 계층에서 OFF 메뉴가 올바르게 필터링됩니다
MenuRepositoryfindVisibleMenusDesc/findVisibleMenusAsc 쿼리에 m.menuViewedStatus = MenuViewedStatus.ON 조건이 포함되어 있어 OFF 상태 메뉴는 응답에서 제외됩니다.


62-73: LGTM! 푸드트럭 메뉴 조회 엔드포인트 구현

새로운 고객용 메뉴 조회 엔드포인트가 적절하게 구현되었습니다. 커서 기반 페이징과 Swagger 문서화가 포함되어 있습니다.

src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java (1)

46-46: JPQL에서 enum 하드코딩 패턴 확인

JPQL 쿼리에서 MenuViewedStatus.ON을 하드코딩하는 것은 유효하지만, 향후 다른 상태 필터링이 필요한 경우 파라미터화를 고려할 수 있습니다.

현재 구현은 "공개된 메뉴만 조회"라는 고정된 요구사항에 적합하므로 하드코딩이 합리적입니다.

src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (2)

23-46: 구현 패턴 승인

FoodTruckMenuService로의 위임 패턴이 기존 메서드들과 일관성 있게 구현되었습니다. 멤버 검증 후 전문 서비스로 위임하는 구조가 명확합니다.


42-46: LGTM!

새로운 getFoodTruckMenus 메서드가 기존 서비스 패턴과 일관되게 구현되었습니다:

  • 회원 검증 후 비즈니스 로직 수행
  • FoodTruckMenuService로의 명확한 책임 위임
  • 일관된 응답 타입 사용
src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1)

185-188: LGTM! Swagger 문서화 추가

새로운 푸드트럭 메뉴 조회 엔드포인트에 대한 에러 코드 문서화가 적절하게 추가되었습니다.

src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1)

29-44: 검증 필요: 푸드트럭 존재 여부 확인

현재 구현은 foodTruckId의 존재 여부를 검증하지 않고 바로 메뉴를 조회합니다. 존재하지 않는 푸드트럭 ID가 전달되면 빈 리스트를 반환하게 되는데, 이는 "메뉴가 없음"과 "푸드트럭이 존재하지 않음"을 구분할 수 없게 만듭니다.

일반적인 REST API 관행상 존재하지 않는 리소스에 대해서는 404를 반환하는 것이 좋습니다. 푸드트럭 존재 여부 검증이 필요한지 확인해주세요.

참고: 오너의 "내 푸드트럭 메뉴 조회" API와 동일한 로직이라고 하셨는데, 해당 API도 동일한 방식으로 동작하는지 확인이 필요합니다.

그 외 커서 페이징 로직, 정렬 처리, 응답 매핑은 올바르게 구현되었습니다.

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/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1)

8-8: 미사용 import를 제거하세요.

User import가 이 파일에서 사용되지 않습니다.

다음 diff를 적용하여 미사용 import를 제거하세요:

-import konkuk.chacall.domain.user.domain.model.User;
src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java (1)

38-45: IN 절 및 페이지 크기 제한 검토

  • IN 절에 너무 많은 foodTruckIds 전달 시 성능 저하 우려: 최대 개수 제한 또는 배치 처리 고려
  • CursorPagingRequest.size에 상한(@max) 검증 없음: 대량 조회 방지를 위해 상한값 설정 권장
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4566fb and e736dc4.

📒 Files selected for processing (6)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (3 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java (0 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java (0 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java (2 hunks)
💤 Files with no reviewable changes (2)
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
  • RequiredArgsConstructor (19-50)
🔇 Additional comments (2)
src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1)

27-38: LGTM! isSaved 상태 판단 로직이 효율적입니다.

변경 사항이 올바르게 구현되었습니다:

  • 페이지 내 모든 트럭에 대해 단일 쿼리로 저장 상태를 조회하여 N+1 문제를 방지합니다.
  • 빈 리스트에 대한 가드 조건(foodTruckIds.isEmpty())을 통해 불필요한 쿼리를 방지합니다.
  • Set.contains()를 사용하여 O(1) 시간 복잡도로 isSaved를 판단합니다.
src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java (1)

18-20: LGTM! isSaved 필드가 일관되게 추가되었습니다.

변경 사항이 정확하고 일관성 있게 구현되었습니다:

  • Swagger 스키마 어노테이션이 적절하게 추가되어 API 문서화가 명확합니다.
  • 팩토리 메서드 시그니처가 새 파라미터를 포함하도록 올바르게 업데이트되었습니다.
  • 생성자 호출이 isSaved 값을 전달하도록 일관되게 수정되었습니다.

Also applies to: 23-23, 30-31

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

♻️ Duplicate comments (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1)

31-50: 이전 리뷰의 null 커서 처리 이슈 재확인 필요

이전 리뷰에서 지적된 null 커서 처리 문제가 여전히 존재하는 것으로 보입니다. pagingRequest.cursor()가 null일 때 (첫 페이지 요청), repository의 JPQL 쿼리에서 m.menuId > :lastCursor 또는 m.menuId < :lastCursor 비교가 항상 false를 반환하여 결과가 조회되지 않습니다.

다음 중 하나의 방법으로 해결이 필요합니다:

  1. FoodTruckMenuRequest.pagingOrDefault() 메서드에서 cursor를 OLDEST의 경우 0으로, NEWEST의 경우 Long.MAX_VALUE로 초기화
  2. Repository의 JPQL에서 COALESCE(:lastCursor, 0) 또는 COALESCE(:lastCursor, 9223372036854775807) 사용

다음 스크립트로 FoodTruckMenuRequest.pagingOrDefault() 구현을 확인하세요:

#!/bin/bash
# FoodTruckMenuRequest의 pagingOrDefault 메서드가 null 커서를 처리하는지 확인
rg -nP --type=java -A10 "pagingOrDefault" src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckMenuRequest.java
🧹 Nitpick comments (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1)

6-6: 사용하지 않는 import 제거 필요

다음 import들이 코드에서 사용되지 않습니다:

  • Line 6: FoodTruckStatus
  • Line 9: MyFoodTruckMenuResponse
  • Line 13: BusinessException

다음 diff를 적용하여 사용하지 않는 import를 제거하세요:

-import konkuk.chacall.domain.foodtruck.domain.value.FoodTruckStatus;
 import konkuk.chacall.domain.foodtruck.presentation.dto.request.FoodTruckMenuRequest;
 import konkuk.chacall.domain.foodtruck.presentation.dto.response.FoodTruckMenuResponse;
-import konkuk.chacall.domain.owner.presentation.dto.response.MyFoodTruckMenuResponse;
 import konkuk.chacall.global.common.dto.CursorPagingRequest;
 import konkuk.chacall.global.common.dto.CursorPagingResponse;
 import konkuk.chacall.global.common.dto.SortType;
-import konkuk.chacall.global.common.exception.BusinessException;
 import konkuk.chacall.global.common.exception.EntityNotFoundException;

Also applies to: 9-9, 13-13

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e736dc4 and e57b2de.

📒 Files selected for processing (2)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1 hunks)
  • src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (2)
src/main/java/konkuk/chacall/global/common/exception/EntityNotFoundException.java (1)
  • EntityNotFoundException (6-11)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
  • RequiredArgsConstructor (19-50)
🔇 Additional comments (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1)

24-29: LGTM!

서비스 클래스 구조와 의존성 주입이 올바르게 구성되어 있습니다. Lombok의 @RequiredArgsConstructor를 활용한 생성자 주입 패턴을 적절하게 사용하고 있습니다.

buzz0331
buzz0331 previously approved these changes Oct 4, 2025
Copy link
Contributor

@buzz0331 buzz0331 left a comment

Choose a reason for hiding this comment

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

확인했습니다~ 로직은 워낙 깔끔해서 건드릴게 없어보이네요 ㅎ

다만, 한가지 궁금한 점이 사장님이 메뉴를 on/off 상태를 변경할때 조회하는 api는 따로 구현하실 생각이신가요?? 그 api에서는 off된 메뉴도 보여져야할 것 같아서요!

Comment on lines +27 to +37
List<FoodTruck> content = foodTruckSlice.getContent();

// 이 페이지의 트럭 ID 목록
List<Long> foodTruckIds = content.stream()
.map(FoodTruck::getFoodTruckId)
.toList();

Set<Long> savedFoodTruckIds = foodTruckIds.isEmpty() ? Set.of() : savedFoodTruckRepository.findSavedTruckIdsIn(memberId, foodTruckIds);

List<FoodTruckResponse> foodTrucks = content.stream()
.map(ft -> FoodTruckResponse.of(ft, savedFoodTruckIds.contains(ft.getFoodTruckId())))
Copy link
Contributor

Choose a reason for hiding this comment

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

배치쿼리 굿입니다

Comment on lines +31 to +49
public CursorPagingResponse<FoodTruckMenuResponse> getFoodTruckMenus(Long foodTruckId, FoodTruckMenuRequest request) {
SortType sort = SortType.fromNullable(request.sort());
CursorPagingRequest pagingRequest = request.pagingOrDefault(sort);
Pageable pageable = PageRequest.of(0, pagingRequest.size());

if(!foodTruckRepository.existsById(foodTruckId)) {
throw new EntityNotFoundException(ErrorCode.FOOD_TRUCK_NOT_FOUND);
}

Slice<Menu> menuSlice = switch (sort) {
case NEWEST -> menuRepository.findVisibleMenusDesc(foodTruckId, pagingRequest.cursor(), pageable);
case OLDEST -> menuRepository.findVisibleMenusAsc(foodTruckId, pagingRequest.cursor(), pageable);
};

List<FoodTruckMenuResponse> content = menuSlice.getContent().stream()
.map(FoodTruckMenuResponse::from)
.toList();

return CursorPagingResponse.of(content, FoodTruckMenuResponse::menuId, menuSlice.hasNext());
Copy link
Contributor

Choose a reason for hiding this comment

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

lgtm

@ksg1227
Copy link
Contributor Author

ksg1227 commented Oct 4, 2025

확인했습니다~ 로직은 워낙 깔끔해서 건드릴게 없어보이네요 ㅎ

다만, 한가지 궁금한 점이 사장님이 메뉴를 on/off 상태를 변경할때 조회하는 api는 따로 구현하실 생각이신가요?? 그 api에서는 off된 메뉴도 보여져야할 것 같아서요!

이 부분은 사장님이 나의 푸드트럭 관리 -> 퓨드트럭 메뉴 조회를 할 경우에 off 된 메뉴까지 보여질 수 있도록 구현해두었습니다!

@buzz0331
Copy link
Contributor

buzz0331 commented Oct 4, 2025

확인했습니다~ 로직은 워낙 깔끔해서 건드릴게 없어보이네요 ㅎ
다만, 한가지 궁금한 점이 사장님이 메뉴를 on/off 상태를 변경할때 조회하는 api는 따로 구현하실 생각이신가요?? 그 api에서는 off된 메뉴도 보여져야할 것 같아서요!

이 부분은 사장님이 나의 푸드트럭 관리 -> 퓨드트럭 메뉴 조회를 할 경우에 off 된 메뉴까지 보여질 수 있도록 구현해두었습니다!

아하 확인했습니다

buzz0331
buzz0331 previously approved these changes Oct 4, 2025
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca1f551 and 87505d6.

📒 Files selected for processing (17)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (4 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java (0 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckMenuRequest.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java (0 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/owner/application/OwnerService.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java (2 hunks)
  • src/main/java/konkuk/chacall/domain/owner/presentation/OwnerController.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/owner/presentation/dto/request/MyFoodTruckMenuRequest.java (1 hunks)
  • src/main/java/konkuk/chacall/domain/user/presentation/dto/request/ApproveFoodTruckStatusRequest.java (1 hunks)
  • src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1 hunks)
💤 Files with no reviewable changes (2)
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/infra/FoodTruckSearchRepositoryImpl.java
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckSearchRequest.java
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java
  • src/main/java/konkuk/chacall/domain/owner/application/OwnerService.java
  • src/main/java/konkuk/chacall/domain/owner/application/myfoodtruckmenu/MyFoodTruckMenuService.java
  • src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java
  • src/main/java/konkuk/chacall/domain/owner/presentation/dto/request/MyFoodTruckMenuRequest.java
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckMenuResponse.java
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/request/FoodTruckMenuRequest.java
  • src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
  • RequiredArgsConstructor (22-69)
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (2)
src/main/java/konkuk/chacall/global/common/exception/EntityNotFoundException.java (1)
  • EntityNotFoundException (6-11)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
  • RequiredArgsConstructor (22-69)
🔇 Additional comments (6)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/ApproveFoodTruckStatusRequest.java (1)

8-8: Swagger 예시 값 변경이 의도적인지 확인 필요

이 파일의 변경사항은 Swagger 문서의 예시 값을 "ON"에서 "OFF"로 수정한 것입니다. 이 변경은 PR의 주요 목적(푸드트럭 메뉴 조회 API 구현)과 직접적인 연관이 없어 보입니다.

FoodTruckStatus의 예시 값으로 "OFF"를 사용하는 것이 의도적인 변경인지, 아니면 개발 중 실수로 수정된 것인지 확인해 주세요. 일반적으로 승인 상태 변경의 예시는 "ON"(승인)이 더 일반적인 케이스일 수 있습니다.

src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckResponse.java (1)

18-20: LGTM! isSaved 필드 추가가 깔끔합니다.

저장 상태 표시를 위한 isSaved 필드가 올바르게 추가되었고, Swagger 문서화도 적절히 작성되었습니다. 팩토리 메서드도 새 파라미터를 정확히 처리하고 있습니다.

Also applies to: 23-23, 30-31

src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)

48-52: memberId 파라미터의 사용 목적을 확인하세요.

Line 49에서 memberId를 검증하지만, Line 51의 위임 호출에서는 사용하지 않습니다. 공개 메뉴 조회는 가시성 상태만 필터링하므로 의도적일 수 있으나, 검증만 하고 사용하지 않는 파라미터는 혼란을 줄 수 있습니다.

향후 확장을 위한 것이라면 괜찮지만, 현재 사용되지 않는다면 제거하는 것을 고려해보세요.

src/main/java/konkuk/chacall/domain/foodtruck/application/command/FoodTruckCommandService.java (1)

27-37: LGTM! 배치 쿼리로 N+1 문제를 효과적으로 방지했습니다.

저장 상태를 조회하기 위해 배치 쿼리를 사용한 점이 좋습니다. Line 34의 빈 리스트 체크로 불필요한 DB 호출도 방지하고 있습니다.

src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java (1)

31-50: LGTM! 메뉴 조회 로직이 명확하고 깔끔합니다.

커서 기반 페이징 구현이 적절하며, 다음 요소들이 잘 처리되고 있습니다:

  • Line 32-34: 정렬 타입 및 페이징 파라미터 기본값 처리
  • Line 36-38: 푸드트럭 존재 여부 검증
  • Line 40-43: 정렬 방향에 따른 적절한 저장소 메서드 호출
  • Line 45-49: 응답 매핑 및 페이징 메타데이터 구성

전반적인 구조가 명확하고 가독성이 좋습니다.

src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1)

196-200: 변경 사항 반영 및 검증 완료

  • FOOD_TRUCK_NOT_FOUND 에러 코드가 추가되었습니다.
  • FoodTruckMenuService.getFoodTruckMenus 메서드에 푸드트럭 존재 여부 검증 로직이 구현되었습니다.

@ksg1227 ksg1227 merged commit 5017a80 into develop Oct 5, 2025
2 checks passed
@ksg1227 ksg1227 deleted the feat/#36-get-food-truck-menus branch October 5, 2025 15:37
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.

[FEAT] 푸드트럭 메뉴 조회 API 구현

2 participants