Conversation
Walkthrough회원 검증을 전제로 푸드트럭 상세조회와 메뉴 키워드 검색 기능이 추가되었습니다. 컨트롤러, 서비스, 도메인, 레포지토리, 응답 DTO, Swagger 및 오류 코드에 관련 엔드포인트와 메서드가 도입되었습니다. (≤50단어) Changes
Sequence Diagram(s)sequenceDiagram
participant C as 클라이언트
participant Ctrl as FoodTruckController
participant S as FoodTruckService
participant V as MemberValidator
participant Info as FoodTruckInfoService
participant MenuS as FoodTruckMenuService
participant Repo as Repositories
C->>Ctrl: GET /{foodTruckId} (UserId)
Ctrl->>S: getFoodTruckDetails(memberId, foodTruckId)
S->>V: validateAndGetMember(memberId)
V-->>S: Member
S->>Info: getFoodTruckDetails(member, foodTruckId)
Info->>Repo: find FoodTruck, serviceAreas, availableDates, saved 여부
Repo-->>Info: domain 데이터
Info->>Info: validateViewableStatus(...) / assemble DTO
Info-->>S: FoodTruckDetailResponse
S-->>Ctrl: FoodTruckDetailResponse
Ctrl-->>C: BaseResponse<FoodTruckDetailResponse>
C->>Ctrl: GET /{foodTruckId}/menus/search?keyword=...
Ctrl->>S: searchFoodTruckMenus(foodTruckId, keyword, memberId)
S->>V: validateAndGetMember(memberId)
V-->>S: Member
S->>MenuS: searchFoodTruckMenus(foodTruckId, keyword, member)
MenuS->>Repo: MenuRepository.searchByKeyword(foodTruckId, keyword)
Repo-->>MenuS: List<Menu>
MenuS->>MenuS: map to FoodTruckMenuResponse
MenuS-->>S: List<FoodTruckMenuResponse>
S-->>Ctrl: List<FoodTruckMenuResponse>
Ctrl-->>C: BaseResponse<List<FoodTruckMenuResponse>>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 검토 시 주의할 파일/영역:
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/AvailableDateRepository.java (1)
17-18: Spring Data JPA 메서드 네이밍 규칙을 활용할 수 있습니다.현재 명시적인 @query를 사용하고 있지만, 메서드 이름이 이미 Spring Data JPA의 네이밍 규칙을 따르고 있어 @query 없이도 자동으로 쿼리가 생성됩니다. @query 어노테이션을 제거해도 동일하게 동작합니다.
- @Query("SELECT ad FROM AvailableDate ad WHERE ad.foodTruck.foodTruckId = :foodTruckId") List<AvailableDate> findAllByFoodTruckId(Long foodTruckId);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java(1 hunks)src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java(2 hunks)src/main/java/konkuk/chacall/domain/foodtruck/domain/model/AvailableDate.java(1 hunks)src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java(2 hunks)src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/AvailableDateRepository.java(1 hunks)src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java(1 hunks)src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckDetailResponse.java(1 hunks)src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java(1 hunks)src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java(1 hunks)src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java(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
🔇 Additional comments (10)
src/main/java/konkuk/chacall/domain/foodtruck/domain/model/AvailableDate.java (1)
40-42: 날짜 형식 확인이 필요합니다.LocalDate의 기본 toString()을 사용하면 ISO-8601 형식(yyyy-MM-dd)으로 출력됩니다. 사용자에게 표시되는 날짜 형식이 이것으로 충분한지 확인해 주세요. 만약 다른 형식(예: yyyy년 MM월 dd일)이 필요하다면 DateTimeFormatter를 사용하여 포맷팅하는 것을 고려해 보세요.
src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java (1)
86-86: LGTM!새로운 에러 코드가 기존 패턴을 잘 따르고 있으며, 푸드트럭 관련 에러 코드 체계에 적절히 추가되었습니다.
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
82-86: LGTM!서비스 계층의 위임 패턴이 적절하게 구현되었습니다. 멤버 검증 후 Info 서비스로 위임하는 구조가 기존 패턴과 일관성 있게 작성되었습니다.
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (1)
133-144: LGTM!새로운 엔드포인트가 기존 컨트롤러 패턴을 잘 따르고 있으며, Swagger 문서화도 적절히 작성되었습니다.
src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1)
249-255: LGTM!새로운 API 엔드포인트에 대한 Swagger 응답 설명이 적절히 추가되었습니다. 필요한 모든 에러 코드가 포함되어 있습니다.
src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java (1)
138-154: 역할 기반 접근 제어 로직이 잘 구현되었습니다.위에서 지적한 오타와 리포지토리 버그를 수정하면, 역할별(일반 유저, 사장님, 관리자) 검증 로직이 PR 목표에 부합하게 잘 구현되었습니다. Switch 표현식을 사용하여 각 역할에 맞는 검증을 명확하게 분리한 점이 좋습니다.
src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java (2)
146-151: 구현이 잘 되어 있습니다.
AvailableDate::formatDate를 활용하여 날짜 리스트를 포맷팅하는 로직이 깔끔하고 명확합니다.
166-170: 일반 유저 검증 로직이 올바르게 구현되었습니다.푸드트럭 노출 상태가 ON이 아닐 때 예외를 발생시키는 로직이 PR 목표와 일치합니다.
src/main/java/konkuk/chacall/domain/foodtruck/presentation/dto/response/FoodTruckDetailResponse.java (2)
11-46: DTO 구조가 잘 설계되었습니다.모든 필드가 적절한 타입으로 정의되어 있고, Swagger 스키마 어노테이션도 명확하게 작성되어 있습니다. 푸드트럭 상세 정보를 표현하기에 충분한 필드들이 포함되어 있습니다.
47-68: 팩토리 메서드가 올바르게 구현되었습니다.도메인 모델로부터 DTO를 생성하는 로직이 명확하고,
getServiceAreas와getAvailableDates같은 도메인 메서드를 적절히 활용하고 있습니다. 모든 필드 매핑이 정확합니다.
src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java
Show resolved
Hide resolved
| List<FoodTruckServiceArea> foodTruckServiceAreas = foodTruckServiceAreaRepository.findAllByFoodTruckId(foodTruckId); | ||
| List<AvailableDate> availableDates = availableDateRepository.findAllByFoodTruckId(foodTruckId); | ||
|
|
||
| boolean isSaved = savedFoodTruckRepository.existsByMemberIdAndFoodTruckId(member.getUserId(), foodTruckId); |
There was a problem hiding this comment.
SavedFoodTruckRepository의 버그로 인해 이 코드가 실패합니다.
existsByMemberIdAndFoodTruckId 메서드에 파라미터 이름 불일치 버그가 있어, 이 줄이 실행될 때 런타임 오류가 발생합니다. SavedFoodTruckRepository.java 파일의 해당 메서드를 먼저 수정해야 합니다.
🤖 Prompt for AI Agents
In
src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java
around line 151, the call to
savedFoodTruckRepository.existsByMemberIdAndFoodTruckId(member.getUserId(),
foodTruckId) fails at runtime because SavedFoodTruckRepository has a
parameter-name mismatch bug; open
src/main/java/konkuk/chacall/domain/foodtruck/repository/SavedFoodTruckRepository.java,
fix the method signature/parameter names to match memberId and foodTruckId (and
any @Param annotations if using JPQL/Query), rebuild so the
existsByMemberIdAndFoodTruckId method accepts the correct parameters and the
runtime error is resolved.
src/main/java/konkuk/chacall/domain/foodtruck/domain/model/FoodTruck.java
Outdated
Show resolved
Hide resolved
src/main/java/konkuk/chacall/domain/member/domain/repository/SavedFoodTruckRepository.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java (2)
146-146: 메서드 이름에 오타가 있습니다.Line 146의
vaildateViewableStatusForOwner는validateViewableStatusForOwner의 오타입니다. 이는 컴파일 오류를 발생시킵니다.- case OWNER -> foodTruck.vaildateViewableStatusForOwner(member.getUserId()); + case OWNER -> foodTruck.validateViewableStatusForOwner(member.getUserId());
153-153: SavedFoodTruckRepository의 버그로 인해 런타임 오류가 발생할 수 있습니다.
existsByMemberIdAndFoodTruckId메서드에 파라미터 이름 불일치 문제가 있어 런타임 오류가 발생할 수 있습니다. SavedFoodTruckRepository의 해당 메서드를 먼저 수정해야 합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java(2 hunks)src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java(2 hunks)src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java(2 hunks)src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java(2 hunks)src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java(4 hunks)src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java(1 hunks)
🔇 Additional comments (7)
src/main/java/konkuk/chacall/domain/foodtruck/application/FoodTruckService.java (1)
84-94: LGTM!두 메서드 모두 적절한 회원 검증 후 하위 서비스로 올바르게 위임하고 있습니다. 구현이 깔끔하고 명확합니다.
src/main/java/konkuk/chacall/domain/foodtruck/application/info/FoodTruckInfoService.java (1)
138-156: 역할별 검증 로직이 PR 목표에 맞게 잘 구현되었습니다.Line 146의 오타와 Line 153의 repository 이슈만 수정하면, 전반적인 로직 구조는 PR 목표에 명시된 역할별 유효성 검증 요구사항을 올바르게 구현하고 있습니다.
src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1)
249-261: LGTM!새로운 엔드포인트에 대한 Swagger 응답 설명이 적절한 에러 코드와 함께 올바르게 정의되었습니다.
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (4)
111-111: 경로 일관성 개선이 좋습니다.
@PutMapping에 leading slash를 추가하여 다른 엔드포인트와의 일관성이 향상되었습니다.
125-125: 경로 일관성 개선이 좋습니다.
@DeleteMapping에 leading slash를 추가하여 다른 엔드포인트와의 일관성이 향상되었습니다.
135-146: LGTM!푸드트럭 상세조회 엔드포인트가 적절한 Swagger 문서화 및 예외 처리와 함께 올바르게 구현되었습니다.
148-160: LGTM!메뉴 검색 엔드포인트가 적절한 파라미터 설명 및 Swagger 문서화와 함께 올바르게 구현되었습니다.
| public List<FoodTruckMenuResponse> searchFoodTruckMenus(Long foodTruckId, String keyword, User member) { | ||
| if(!foodTruckRepository.existsById(foodTruckId)) { | ||
| throw new EntityNotFoundException(ErrorCode.FOOD_TRUCK_NOT_FOUND); | ||
| } | ||
|
|
||
| List<Menu> menus = menuRepository.searchByKeyword(foodTruckId, keyword); | ||
|
|
||
| return menus.stream() | ||
| .map(FoodTruckMenuResponse::from) | ||
| .toList(); | ||
| } |
There was a problem hiding this comment.
PR 목표에 명시된 역할별 유효성 검증 로직이 누락되었습니다.
PR 설명에 따르면 다음과 같은 역할별 검증이 필요합니다:
- 일반 유저: 푸드트럭 노출 상태가 ON인 경우에만 조회 가능
- 사장님: 본인 소유 푸드트럭이면 노출 상태와 상관없이 조회 가능
- 관리자: 제한 없음
현재 구현은 member 파라미터를 받지만 전혀 사용하지 않으며, 푸드트럭 노출 상태 및 소유권 검증이 없습니다. getFoodTruckDetails 메서드와 유사한 역할별 검증 로직이 필요합니다.
다음과 같이 수정하세요:
public List<FoodTruckMenuResponse> searchFoodTruckMenus(Long foodTruckId, String keyword, User member) {
- if(!foodTruckRepository.existsById(foodTruckId)) {
- throw new EntityNotFoundException(ErrorCode.FOOD_TRUCK_NOT_FOUND);
- }
+ FoodTruck foodTruck = foodTruckRepository.findById(foodTruckId)
+ .orElseThrow(() -> new EntityNotFoundException(ErrorCode.FOOD_TRUCK_NOT_FOUND));
+
+ foodTruck.validateApprovedStatus();
+
+ switch(member.getRole()) {
+ case MEMBER -> foodTruck.validateViewableStatusForMember();
+ case OWNER -> foodTruck.validateViewableStatusForOwner(member.getUserId());
+ case ADMIN -> {}
+ }
List<Menu> menus = menuRepository.searchByKeyword(foodTruckId, keyword);
return menus.stream()
.map(FoodTruckMenuResponse::from)
.toList();
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In
src/main/java/konkuk/chacall/domain/foodtruck/application/menu/FoodTruckMenuService.java
around lines 51 to 61, the method ignores the member parameter and omits
role-based validation: load the FoodTruck entity by id (throw
FOOD_TRUCK_NOT_FOUND if absent), then apply the same role-based access rules as
getFoodTruckDetails — if member is ADMIN allow, if member is OWNER allow only
when member.id equals foodTruck.ownerId, otherwise (regular user) allow only
when foodTruck.displayStatus (or equivalent visibility flag) is ON; if access is
denied throw appropriate exception (e.g., ACCESS_DENIED or
FOOD_TRUCK_NOT_VISIBLE). After validation, query menuRepository.searchByKeyword
and map to responses as before.
| @Query(""" | ||
| select m | ||
| from Menu m | ||
| where m.foodTruck.foodTruckId = :foodTruckId | ||
| and m.name like concat('%', :keyword, '%') | ||
| and m.menuViewedStatus = konkuk.chacall.domain.foodtruck.domain.value.MenuViewedStatus.ON | ||
| """) | ||
| List<Menu> searchByKeyword(Long foodTruckId, String keyword); |
There was a problem hiding this comment.
검색 결과에 페이지네이션이 없어 성능 문제 가능성이 있습니다.
키워드 검색 결과에 제한이 없어 대량의 메뉴가 있는 푸드트럭의 경우 많은 데이터를 반환할 수 있습니다. 또한 키워드가 null이거나 빈 문자열일 때의 처리가 없습니다.
다음 개선사항을 고려해주세요:
- 결과 개수 제한 추가 (예: TOP 50)
- 키워드 검증 로직 추가 (null/empty 체크)
@Query("""
select m
from Menu m
where m.foodTruck.foodTruckId = :foodTruckId
and m.name like concat('%', :keyword, '%')
and m.menuViewedStatus = konkuk.chacall.domain.foodtruck.domain.value.MenuViewedStatus.ON
+ order by m.menuId desc
""")
-List<Menu> searchByKeyword(Long foodTruckId, String keyword);
+List<Menu> searchByKeyword(@Param("foodTruckId") Long foodTruckId, @Param("keyword") String keyword, Pageable pageable);또는 서비스 레이어에서 키워드 검증을 추가하세요.
🤖 Prompt for AI Agents
In
src/main/java/konkuk/chacall/domain/foodtruck/domain/repository/MenuRepository.java
around lines 74-81, the keyword search query returns unlimited results and does
not handle null/empty keywords; change the repository method to support
pagination (add a Pageable parameter and return Page<Menu> or List<Menu> with
Pageable) so callers can limit results (e.g., page size 50), and add keyword
validation in the service layer (or repository caller) to check for null/empty
and return an empty list or a controlled response instead of executing the query
when keyword is blank.
ksg1227
left a comment
There was a problem hiding this comment.
확인했습니다! 전체적으로 잘 구현해주셔서 건드릴 곳이 없네용
피드백 하나만 남겨두겠습니다~
| public void validateViewableStatusForMember() { | ||
| if (this.foodTruckViewedStatus != FoodTruckViewedStatus.ON) { | ||
| throw new DomainRuleException(ErrorCode.FOOD_TRUCK_NOT_VIEWABLE); | ||
| } | ||
| } | ||
|
|
||
| public void validateViewableStatusForOwner(Long userId) { | ||
| if(!isOwnedBy(userId)) { // 자신이 소유한 푸드트럭이 아니면 | ||
| validateViewableStatusForMember(); | ||
| } | ||
| } |
| description = "푸드트럭의 상세 정보를 조회합니다." | ||
| ) | ||
| @ExceptionDescription(SwaggerResponseDescription.GET_FOOD_TRUCK_DETAILS) | ||
| @GetMapping("/{foodTruckId}/details") |
There was a problem hiding this comment.
푸드트럭 상세 조회 API 의 경우 그냥 /food-trucks/{foodTruckId} 로 엔드포인트를 설정해둬 괜찮을 것 같다는 생각이 드는데 어떠신가요?
There was a problem hiding this comment.
넵 엔드포인트 간소화시키는게 추후에 더 좋을 것 같네요. 수정하겠습니다~
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (1)
135-146: 엔드포인트 순서 정리 제안기능상 문제는 없으나, 같은 경로(
/{foodTruckId})에 대한 GET 메서드가 PUT 메서드 이후에 위치해 있습니다.HTTP 메서드 순서(GET → PUT → DELETE)나 리소스 계층 구조에 따라 정렬하면 가독성이 향상될 수 있습니다. 예를 들어, 상세 조회(GET)를 수정(PUT) 앞에 배치하는 것을 고려해 보세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java(4 hunks)
🔇 Additional comments (3)
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java (3)
28-28: LGTM: 필요한 import 추가새로운 메뉴 검색 엔드포인트의
List<FoodTruckMenuResponse>반환 타입을 위해 필요한 import입니다.
111-111: LGTM: 경로 매핑 일관성 개선경로에 leading slash를 추가하여 Spring의 베스트 프랙티스를 따르고 있으며, 클래스 내 다른 엔드포인트들과의 일관성이 향상되었습니다.
Also applies to: 125-125
135-146: LGTM: 푸드트럭 상세조회 엔드포인트 구현엔드포인트가 RESTful 원칙을 따르며 기존 패턴과 일관성 있게 구현되었습니다. 이전 리뷰에서 논의된 대로 경로가
/food-trucks/{foodTruckId}로 간소화되어 더욱 명확합니다.
| @Operation( | ||
| summary = "푸드트럭 메뉴 검색", | ||
| description = "푸드트럭 메뉴를 이름으로 검색합니다." | ||
| ) | ||
| @ExceptionDescription(SwaggerResponseDescription.SEARCH_FOOD_TRUCK_MENUS) | ||
| @GetMapping("/{foodTruckId}/menus/search") | ||
| public BaseResponse<List<FoodTruckMenuResponse>> searchFoodTruckMenus( | ||
| @Parameter(description = "푸드트럭 ID", example = "1") @PathVariable final Long foodTruckId, | ||
| @Parameter(description = "검색 키워드", example = "치킨") @RequestParam("keyword") final String keyword, | ||
| @Parameter(hidden = true) @UserId final Long memberId | ||
| ) { | ||
| return BaseResponse.ok(foodTruckService.searchFoodTruckMenus(foodTruckId, keyword, memberId)); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
빈 문자열 검증 확인 필요
메뉴 검색 엔드포인트가 잘 구현되어 있으나, keyword 파라미터가 빈 문자열("")로 전달될 경우의 처리를 확인해 주세요.
빈 문자열로 검색 시 의도하지 않은 결과(예: 모든 메뉴 반환)가 발생할 수 있습니다. 필요시 @RequestParam 레벨 또는 서비스 레이어에서 @NotBlank 검증을 추가하는 것을 고려해 주세요.
검증 스크립트로 서비스 레이어에서 키워드 검증이 있는지 확인:
🏁 Script executed:
#!/bin/bash
# Description: Check if keyword validation exists in service layer
# Search for searchFoodTruckMenus method implementation
ast-grep --pattern $'searchFoodTruckMenus($$$) {
$$$
}'
# Also check for blank validation patterns
rg -nP --type=java -A10 'searchFoodTruckMenus.*keyword' -g '!**/test/**'Length of output: 2621
키워드 빈 문자열 검증 필요
코드 검토 결과, searchFoodTruckMenus 메서드에서 keyword 파라미터가 빈 문자열("")로 전달될 경우 SQL LIKE 쿼리가 모든 메뉴 레코드를 반환할 수 있습니다.
현재 구현:
- Controller (159줄): 검증 없이
keyword를 서비스로 전달 - FoodTruckService (90-94줄): memberId만 검증, 바로 위임
- FoodTruckMenuService (51-61줄):
menuRepository.searchByKeyword(foodTruckId, keyword)직접 호출
해결 방안
Controller의 @RequestParam에 @NotBlank 추가하거나 서비스 레이어에서 빈 문자열 체크를 구현하세요.
🤖 Prompt for AI Agents
In
src/main/java/konkuk/chacall/domain/foodtruck/presentation/FoodTruckController.java
around lines 148-160, the keyword RequestParam is not validated so an empty
string can lead to unintended SQL LIKE results; add validation to reject blank
keywords (e.g., annotate the controller method/parameter with @NotBlank and
ensure the controller class is @Validated) or perform a manual check (trim the
keyword, if blank throw a 400 BadRequest with a clear message) before calling
the service so only non-empty search terms are passed to FoodTruckService.
#️⃣연관된 이슈
📝작업 내용
단순 조회라서 딱히 특이사항이 없었습니다.
유효성 검증시에 사용자의 역할에 따라 다르게 검증하였습니다.
추가적으로 찬영님 요청에 따라 메뉴 검색 API를 구현하였습니다. 단순히 like 문을 사용해서 구현하였고, 반환 타입은 찬영님과의 합의하에 리스트 객체로 감싸지 않고 바로 리스트를 반환하도록 구현하였습니다.
스크린샷 (선택)
💬리뷰 요구사항(선택)
Summary by CodeRabbit
새로운 기능
문서