Conversation
This reverts commit e559830.
Walkthrough이 PR은 REST API 기반 음식 배달 플랫폼의 식당, 메뉴, 주문 관리 기능을 구현합니다. 도메인 엔티티, DTO, 리포지토리, 서비스, 컨트롤러를 추가하고 Swagger/OpenAPI 문서화를 설정합니다. Changes식당-메뉴-주문 관리 API
Gradle 래퍼 업데이트
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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: 24
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
gradlew.bat (1)
54-68:⚠️ Potential issue | 🟠 Major | ⚡ Quick win치명 오류 경로가 배치 파일을 즉시 종료하지 못합니다.
54줄과 68줄의
"%COMSPEC%" /c exit 1은 자식cmd.exe프로세스만 종료하고 부모 배치 파일의 실행은 계속됩니다. JAVA_HOME이 설정되지 않은 경우 오류 메시지를 출력한 후에도 다음 라벨(:findJavaFromJavaHome,:execute)로 진행되어 잘못된 동작이 발생할 수 있습니다.수정 제안
-"%COMSPEC%" /c exit 1 +exit /b 154줄과 68줄 모두 동일하게 수정합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gradlew.bat` around lines 54 - 68, The two occurrences of "%COMSPEC%" /c exit 1 do not stop the parent batch and should be replaced so the batch file itself exits with failure; update both instances (the one before :findJavaFromJavaHome and the one after the invalid JAVA_HOME error near the :findJavaFromJavaHome/:execute logic) to use a batch-level exit such as "exit /b 1" or "goto :eof" to terminate the script immediately and return a non-zero status, ensuring the labels :findJavaFromJavaHome and :execute are not mistakenly executed afterward.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@build.gradle`:
- Around line 39-40: build.gradle에서 선언된 의존성
'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'을 최신 호환 릴리스로 업데이트하세요;
구체적으로 버전을 3.0.3으로 변경(또는 최소 2.8.x)하여 springdoc-openapi의 최신 보안/호환 패치를 적용하고, 변경 후
빌드/테스트(특히 Spring Framework 6.2+/Spring Boot 3.4+ 관련)를 실행하여 호환성 문제를 확인하세요.
In `@src/main/java/com/kuit/baemin/controller/OrderController.java`:
- Line 72: The method-level mapping `@GetMapping`("/users/{userId}/orders") in
OrderController conflicts with the class-level `@RequestMapping`("/orders")
producing a duplicated path; fix by either moving this endpoint into a new
UserOrderController annotated with `@RestController` and `@RequestMapping`("/users")
and change the method to `@GetMapping`("/{userId}/orders") (recommended), or keep
OrderController and remove/adjust the class-level `@RequestMapping`("/orders") and
change the method mapping to `@GetMapping`("/{userId}/orders") or
`@GetMapping`("/users/{userId}/orders") consistently so the final route becomes
/users/{userId}/orders; update references to the controller method
getOrdersByUser as needed.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Category.java`:
- Around line 29-31: Category currently only holds the restaurantCategories
collection which can lead to mismatched object graphs because
RestaurantCategory.category may not be set; add bidirectional convenience
methods (e.g., in Category addRestaurantCategory(RestaurantCategory rc) and
removeRestaurantCategory(RestaurantCategory rc)) that set/unset
rc.setCategory(this) and update the restaurantCategories list, and ensure any
code that modifies the collection uses these methods instead of manipulating the
list directly to keep both sides (Category.restaurantCategories and
RestaurantCategory.category) synchronized.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Menu.java`:
- Around line 39-45: The Menu entity has two bidirectional collections
(optionGroups and orderItems) that lack convenience mutators; add methods like
addOptionGroup(MenuOptionGroup group) and addOrderItem(OrderItem item) on Menu
that (1) add the child to the appropriate list (optionGroups or orderItems) only
if not already present and (2) set the child's back-reference (call
group.setMenu(this) and item.setMenu(this)); also add corresponding
removeOptionGroup/removeOrderItem methods to clear the back-reference (set to
null) when removing to keep both sides synchronized and prevent memory-state
inconsistencies.
- Around line 43-45: The orderItems collection in Menu uses CascadeType.ALL
which will propagate removes to OrderItem; update the `@OneToMany` on the
orderItems field in class Menu to remove REMOVE propagation by replacing cascade
= CascadeType.ALL with a limited set (e.g., cascade = {CascadeType.PERSIST,
CascadeType.MERGE}) so deletes of Menu do not cascade to OrderItem snapshots;
keep mappedBy = "menu" and fetch = FetchType.LAZY as-is.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/MenuOption.java`:
- Around line 32-34: The current mapping on MenuOption.orderItemOptions uses
CascadeType.ALL which will cascade REMOVE and delete OrderItemOption historical
records; change the cascade to only CascadeType.PERSIST and CascadeType.MERGE so
deletes of MenuOption do not remove OrderItemOption snapshots. Update the
`@OneToMany` annotation on the orderItemOptions field (in class MenuOption) to use
cascade = {CascadeType.PERSIST, CascadeType.MERGE} and leave fetch and mappedBy
unchanged.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/MenuOptionGroup.java`:
- Around line 29-30: The field optionType in MenuOptionGroup is currently an
Integer which allows invalid values; create a new enum (e.g., OptionType)
representing the allowed option kinds, change the MenuOptionGroup.optionType
type to that enum, annotate the field with `@Enumerated`(EnumType.STRING) to
persist names, and update any code that constructs or compares optionType
(factories, constructors, DTOs, repositories, and tests) to use OptionType
instead of raw integers.
- Around line 32-36: Add validation to enforce the invariant that minSelectCount
and maxSelectCount are non-negative and minSelectCount <= maxSelectCount in the
MenuOptionGroup entity: annotate the fields minSelectCount and maxSelectCount
with Jakarta Validation constraints (e.g., `@Min`(0)) and/or implement a lifecycle
check method (annotated with `@PrePersist` and `@PreUpdate`) inside MenuOptionGroup
that throws an IllegalStateException if minSelectCount is null/negative,
maxSelectCount is null/negative, or minSelectCount > maxSelectCount; ensure the
exception message clearly references minSelectCount and maxSelectCount so
persistence errors reveal the violated invariant.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Order.java`:
- Around line 41-43: Order 엔티티의 orderItems 양방향 연관관계에 편의 메서드가 없어 관계 동기화가 누락될 수
있습니다; Order 클래스에 addOrderItem(OrderItem item)과 removeOrderItem(OrderItem item)
메서드를 추가하여 각각 orderItems에 항목을 추가/제거하면서 item.setOrder(this)와 item.setOrder(null)을
호출해 양쪽(orderItems 리스트와 OrderItem.order 필드)을 동시에 갱신하도록 구현하세요(메서드 내부에서 중복 추가/제거 방지
로직도 포함).
- Around line 31-32: The Order entity currently stores deliveryAddressId as an
unchecked scalar which allows invalid or unauthorized IDs; update handling so
delivery addresses are validated before saving: either change the Order field to
a proper `@ManyToOne` association (e.g., map deliveryAddress -> UserAddress
entity) or, if keeping the scalar deliveryAddressId, add ownership and existence
checks in the createOrder() service flow by calling
UserAddressRepository.findByUserId(userId) (or findById and verify its userId)
and throw if not found or not owned; additionally add a DB foreign-key
constraint for delivery_address_id to enforce referential integrity at the
schema level.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/OrderItem.java`:
- Around line 39-40: OrderItem currently stores status as a raw String, making
validation inconsistent with Order's Enum usage; replace the String field in
OrderItem (field name: status) with a dedicated enum type (e.g.,
OrderItemStatus) and annotate it with `@Enumerated`(EnumType.STRING) on the status
field; add the new enum (defining allowed values), update constructors,
getters/setters and any places that read/write OrderItem.status to use the enum
type, and adjust persistence mapping/DB migration as needed so the column
remains VARCHAR but is type-safe in code.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Restaurant.java`:
- Around line 51-57: The Restaurant entity's bidirectional collections menus and
orders lack convenience methods, risking mismatched state; add methods
addMenu(Menu menu), removeMenu(Menu menu), addOrder(Order order), and
removeOrder(Order order) in the Restaurant class that update both sides (e.g.,
modify the menus/orders list and call menu.setRestaurant(this) or
menu.setRestaurant(null), and likewise
order.setRestaurant(this)/setRestaurant(null)) to keep the relationship
synchronized; ensure these methods handle nulls and avoid duplicate
additions/removals.
- Around line 55-57: The Restaurant entity currently uses CascadeType.ALL on the
orders and menus relationships which will propagate REMOVE and can delete
historical orders/menus; change the cascade on the fields orders and menus in
Restaurant to exclude REMOVE (e.g., use explicit cascade set without REMOVE such
as PERSIST, MERGE, REFRESH, DETACH or simply omit cascade for REMOVE) and add
bidirectional convenience methods addOrder(Order order), removeOrder(Order
order), addMenu(Menu menu), removeMenu(Menu menu) that set/unset the
back-reference (order.setRestaurant(this) / order.setRestaurant(null),
menu.setRestaurant(this) / menu.setRestaurant(null)) and update the local lists
to keep both sides consistent.
In `@src/main/java/com/kuit/baemin/dto/request/CategoryReq.java`:
- Around line 13-14: The CategoryReq DTO's name field currently only has
`@NotBlank` which allows over-long input to reach the DB; add a size constraint by
annotating the field with `@Size`(max = 100) (keeping the existing `@NotBlank`) so
validation fails at request time; locate the name field inside class CategoryReq
and apply `@Size`(max = 100) to it.
In `@src/main/java/com/kuit/baemin/dto/request/OrderReq.java`:
- Around line 23-24: The orderItems field on OrderReq is only annotated with
`@NotNull` so it allows empty lists and its elements aren't validated; update
OrderReq.orderItems to include `@NotEmpty` to forbid empty collections and add
`@Valid` so each OrderItemReq's constraints (e.g., `@NotNull`, `@Positive`) are
applied during validation; ensure import of javax.validation.Valid and the
appropriate NotEmpty annotation.
In `@src/main/java/com/kuit/baemin/dto/request/RestaurantReq.java`:
- Around line 35-41: Change the validation on RestaurantReq's numeric fields to
allow zero: keep `@NotNull` on minOrderAmount and deliveryFee but replace the
`@Positive` annotations with `@PositiveOrZero` so values of 0 are accepted (update
the annotations on the minOrderAmount and deliveryFee fields in the
RestaurantReq DTO).
In `@src/main/java/com/kuit/baemin/dto/response/OrderItemRes.java`:
- Around line 27-39: The mapping in OrderItemRes.from calls
orderItem.getOrder().getId() and orderItem.getMenu().getId(), causing N+1
queries because OrderItemRepository.findByOrderId does not eagerly load
associations; update findByOrderId in OrderItemRepository to eagerly fetch the
related entities (either annotate the repository method with
`@EntityGraph`(attributePaths = {"order","menu"}) or replace it with a `@Query` that
uses fetch join for order and menu) so OrderItem instances already contain order
and menu when OrderItemRes.from is invoked.
In `@src/main/java/com/kuit/baemin/dto/response/OrderRes.java`:
- Around line 30-41: OrderRes.from(Order) currently omits mapping orderItems
causing getOrdersByUser() to return empty lists while getOrderById() fills them
via OrderItemRepository; fix by populating orderItems in OrderRes.from(Order)
(or alternatively change getOrdersByUser() to query OrderItemRepository like
getOrderById())—retrieve order.getOrderItems() (or fetch via
OrderItemRepository) and map each item to the DTO representation before calling
OrderRes.builder().orderItems(...). Ensure this logic runs inside a
`@Transactional` context so lazy-loaded user/restaurant IDs and
order.getOrderItems() are available.
In `@src/main/java/com/kuit/baemin/repository/MenuOptionGroupRepository.java`:
- Around line 8-10: The repository method MenuOptionGroupRepository.findByMenuId
triggers N+1 because MenuOptionGroup has a LAZY collection of MenuOption; modify
the repository to eagerly fetch options by either adding a JPQL query with a
fetch join (select g from MenuOptionGroup g join fetch g.menuOptions where
g.menu.id = :menuId) or annotate the method with an `@EntityGraph`(attributePaths
= {"menuOptions"}) so MenuOption entities are loaded in the same query and avoid
repeated lazy loads.
In `@src/main/java/com/kuit/baemin/service/OrderService.java`:
- Around line 46-51: In OrderService, avoid calling
restaurantRepository.findById(req.getRestaurantId()) twice; fetch once, assign
the Optional's value to a local variable (e.g., restaurant) after orElseThrow,
and reuse that variable when building the Order (referencing
restaurantRepository.findById and Order.builder in the diff) so you remove the
duplicated DB query and use the same Restaurant instance for
order.setRestaurant.
- Line 70: Replace the hardcoded "CONFIRMED" literal used in OrderService (the
.status("CONFIRMED") call) with a typed constant or enum: add an OrderItemStatus
enum (e.g., CONFIRMED, PREPARING, COMPLETED, CANCELLED) or a constants holder,
then update the .status invocation in OrderService to use that enum/constant
(and convert to the expected type if the status field is a String, e.g., use the
enum's name()/toString() or change the field/type to the enum) so the status
value is no longer hardcoded.
In `@src/main/java/com/kuit/baemin/service/RestaurantService.java`:
- Line 48: Replace the string literal "ACTIVE" with the RestaurantStatus enum
when calling restaurantRepository.findByStatus in RestaurantService; update the
call to use RestaurantStatus.ACTIVE and, if the repository method currently
accepts a String, change the repository signature (e.g.,
findByStatus(RestaurantStatus status, Pageable pageable)) and any related query
definitions to accept RestaurantStatus to ensure type safety and prevent
mismatches.
- Around line 92-95: Replace the physical delete in
RestaurantService.deleteRestaurant with a soft-delete: add a DELETED (or
INACTIVE) constant to the RestaurantStatus enum, fetch the Restaurant as you
already do, set restaurant.setStatus(RestaurantStatus.DELETED) (or .INACTIVE),
and save the entity via restaurantRepository.save(restaurant) instead of calling
restaurantRepository.delete(...); ensure any business logic that relied on
find/delete uses repository queries that exclude DELETED (update repository
methods if needed) and keep the RestaurantService.deleteRestaurant,
RestaurantStatus, and restaurantRepository references consistent.
- Around line 69-82: The code recreates a Restaurant via Restaurant.builder(...)
which bypasses JPA's persistence context and dirty-checking; instead add an
instance method on the entity (e.g., Restaurant.updateInfo(...) as described) or
use existing setters to mutate the managed Restaurant instance, then call that
method from RestaurantService (replace the Restaurant.builder(...) block with a
call like restaurant.updateInfo(...) so menus/orders/status remain managed and
changes are flushed by JPA).
---
Outside diff comments:
In `@gradlew.bat`:
- Around line 54-68: The two occurrences of "%COMSPEC%" /c exit 1 do not stop
the parent batch and should be replaced so the batch file itself exits with
failure; update both instances (the one before :findJavaFromJavaHome and the one
after the invalid JAVA_HOME error near the :findJavaFromJavaHome/:execute logic)
to use a batch-level exit such as "exit /b 1" or "goto :eof" to terminate the
script immediately and return a non-zero status, ensuring the labels
:findJavaFromJavaHome and :execute are not mistakenly executed afterward.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 01f932fc-95e7-4ac0-abe8-5b1b0f2a5bb1
⛔ Files ignored due to path filters (1)
gradle/wrapper/gradle-wrapper.propertiesis excluded by!gradle/**
📒 Files selected for processing (44)
build.gradlegradlewgradlew.batsrc/main/java/com/kuit/baemin/config/SwaggerConfig.javasrc/main/java/com/kuit/baemin/controller/MenuController.javasrc/main/java/com/kuit/baemin/controller/OrderController.javasrc/main/java/com/kuit/baemin/controller/RestaurantController.javasrc/main/java/com/kuit/baemin/domain/Restaurant/Category.javasrc/main/java/com/kuit/baemin/domain/Restaurant/Menu.javasrc/main/java/com/kuit/baemin/domain/Restaurant/MenuOption.javasrc/main/java/com/kuit/baemin/domain/Restaurant/MenuOptionGroup.javasrc/main/java/com/kuit/baemin/domain/Restaurant/MenuStatus.javasrc/main/java/com/kuit/baemin/domain/Restaurant/Order.javasrc/main/java/com/kuit/baemin/domain/Restaurant/OrderItem.javasrc/main/java/com/kuit/baemin/domain/Restaurant/OrderItemOption.javasrc/main/java/com/kuit/baemin/domain/Restaurant/OrderStatus.javasrc/main/java/com/kuit/baemin/domain/Restaurant/Restaurant.javasrc/main/java/com/kuit/baemin/domain/Restaurant/RestaurantCategory.javasrc/main/java/com/kuit/baemin/domain/member/UserAddress.javasrc/main/java/com/kuit/baemin/dto/request/CategoryReq.javasrc/main/java/com/kuit/baemin/dto/request/MenuReq.javasrc/main/java/com/kuit/baemin/dto/request/OrderItemReq.javasrc/main/java/com/kuit/baemin/dto/request/OrderReq.javasrc/main/java/com/kuit/baemin/dto/request/RestaurantReq.javasrc/main/java/com/kuit/baemin/dto/response/CategoryRes.javasrc/main/java/com/kuit/baemin/dto/response/MenuRes.javasrc/main/java/com/kuit/baemin/dto/response/OrderItemRes.javasrc/main/java/com/kuit/baemin/dto/response/OrderRes.javasrc/main/java/com/kuit/baemin/dto/response/RestaurantRes.javasrc/main/java/com/kuit/baemin/exception/errorcode/ErrorStatus.javasrc/main/java/com/kuit/baemin/repository/CategoryRepository.javasrc/main/java/com/kuit/baemin/repository/MenuOptionGroupRepository.javasrc/main/java/com/kuit/baemin/repository/MenuOptionRepository.javasrc/main/java/com/kuit/baemin/repository/MenuRepository.javasrc/main/java/com/kuit/baemin/repository/OrderItemOptionRepository.javasrc/main/java/com/kuit/baemin/repository/OrderItemRepository.javasrc/main/java/com/kuit/baemin/repository/OrderRepository.javasrc/main/java/com/kuit/baemin/repository/RestaurantCategoryRepository.javasrc/main/java/com/kuit/baemin/repository/RestaurantRepository.javasrc/main/java/com/kuit/baemin/repository/UserAddressRepository.javasrc/main/java/com/kuit/baemin/service/MenuService.javasrc/main/java/com/kuit/baemin/service/OrderService.javasrc/main/java/com/kuit/baemin/service/RestaurantService.javasrc/main/resources/application.yml
| // Swagger/OpenAPI | ||
| implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
springdoc-openapi-starter-webmvc-ui latest version 2026
💡 Result:
As of May 15, 2026, the latest version of springdoc-openapi-starter-webmvc-ui is 3.0.3, which was released on April 11, 2026 [1][2].
Citations:
- 1: springdoc/springdoc-openapi@v3.0.2...v3.0.3
- 2: https://repo.maven.apache.org/maven2/org/springdoc/springdoc-openapi-starter-webmvc-ui/
🌐 Web query:
springdoc-openapi-starter-webmvc-ui 2.3.0 security vulnerabilities
💡 Result:
As of May 15, 2026, there are no specific CVEs (Common Vulnerabilities and Exposures) assigned directly to springdoc-openapi-starter-webmvc-ui version 2.3.0 [1][2]. However, using this version is strongly discouraged due to its age and the availability of significantly more secure and compatible releases [3][4]. Key considerations regarding version 2.3.0 include: 1. Outdated Dependencies: Version 2.3.0 was released in December 2023 [5][1]. Like many older libraries, it relies on older versions of transitive dependencies (such as Spring Boot and Swagger Core) that may contain known vulnerabilities [1][6]. Security scanners often flag these transitive dependencies even if the library itself does not have a direct vulnerability [1]. 2. Compatibility Issues: Version 2.3.0 is not compatible with newer versions of the Spring Framework (e.g., Spring Framework 6.2+ and Spring Boot 3.4+), which can lead to runtime errors such as NoSuchMethodError [7]. 3. Recommended Action: You should upgrade to the latest stable version of springdoc-openapi (currently 3.x or the latest 2.8.x release) [3][8][4]. The project maintainers explicitly recommend using the latest stable version to ensure compatibility with current Spring Boot releases and to receive the latest security patches for all underlying dependencies [3][4]. Always verify your project's dependency tree using tools like mvn dependency:tree or gradle dependencies to identify if any specific transitive dependencies used by version 2.3.0 are flagged by your organization's security policies.
Citations:
- 1: https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi/2.3.0
- 2: https://guide.sonatype.com/component/maven/org.springdoc%3Aspringdoc-openapi-starter-common/3.0.3/versions
- 3: http://springdoc.org/
- 4: https://springdoc.org/faq.html
- 5: https://central.sonatype.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui/2.0.3
- 6: Kindly request to update transitive dependency springdoc/springdoc-openapi#2306
- 7: NoSuchMethodError with springdoc-openapi 2.3.0 and Spring Boot 3.4.2 (ControllerAdviceBean constructor removed) OpenCDMP/OpenCDMP#4
- 8: https://newreleases.io/project/github/springdoc/springdoc-openapi/release/v3.0.2
springdoc-openapi-starter-webmvc-ui 버전을 최신으로 업그레이드하세요.
현재 버전 2.3.0 (2023년 12월 릴리스)은 2년 이상 오래된 버전입니다. 최신 버전 3.0.3 (2026년 4월 11일 릴리스)이 사용 가능하며, 이전 버전의 transitive dependency들에는 알려진 보안 취약점이 포함될 수 있습니다. 또한 2.3.0은 Spring Framework 6.2+ 및 Spring Boot 3.4+와의 호환성 문제도 있습니다. 3.0.3 또는 최소한 2.8.x로 업그레이드해주세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@build.gradle` around lines 39 - 40, build.gradle에서 선언된 의존성
'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'을 최신 호환 릴리스로 업데이트하세요;
구체적으로 버전을 3.0.3으로 변경(또는 최소 2.8.x)하여 springdoc-openapi의 최신 보안/호환 패치를 적용하고, 변경 후
빌드/테스트(특히 Spring Framework 6.2+/Spring Boot 3.4+ 관련)를 실행하여 호환성 문제를 확인하세요.
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "조회 성공"), | ||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음"), | ||
| }) | ||
| @GetMapping("/users/{userId}/orders") |
There was a problem hiding this comment.
중복된 경로 매핑을 수정하세요.
현재 @GetMapping("/users/{userId}/orders")는 클래스 레벨의 @RequestMapping("/orders")와 결합되어 /orders/users/{userId}/orders 경로를 생성합니다. 경로에 "orders"가 중복됩니다. RESTful 관례상 사용자의 주문 목록은 /users/{userId}/orders 경로가 더 적절합니다.
🔧 수정 제안
방법 1: 이 엔드포인트를 별도 컨트롤러로 분리 (권장)
새로운 UserOrderController를 생성하여 /users 경로 아래에 배치:
`@RestController`
`@RequestMapping`("/users")
public class UserOrderController {
`@GetMapping`("/{userId}/orders")
public ResponseEntity<ApiResponse<Page<OrderRes>>> getOrdersByUser(...) {
// ...
}
}방법 2: 현재 컨트롤러 유지 및 경로만 수정
- `@GetMapping`("/users/{userId}/orders")
+ `@GetMapping`("/../users/{userId}/orders") // 비권장: 경로가 불명확함또는 클래스 레벨 매핑 제거:
-@RequestMapping("/orders")
+@RequestMapping("")
public class OrderController {
+ `@PostMapping`("/orders")
+ `@GetMapping`("/orders/{orderId}")
+ `@GetMapping`("/users/{userId}/orders")
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/controller/OrderController.java` at line 72,
The method-level mapping `@GetMapping`("/users/{userId}/orders") in
OrderController conflicts with the class-level `@RequestMapping`("/orders")
producing a duplicated path; fix by either moving this endpoint into a new
UserOrderController annotated with `@RestController` and `@RequestMapping`("/users")
and change the method to `@GetMapping`("/{userId}/orders") (recommended), or keep
OrderController and remove/adjust the class-level `@RequestMapping`("/orders") and
change the method mapping to `@GetMapping`("/{userId}/orders") or
`@GetMapping`("/users/{userId}/orders") consistently so the final route becomes
/users/{userId}/orders; update references to the controller method
getOrdersByUser as needed.
| @OneToMany(mappedBy = "category", fetch = FetchType.LAZY, cascade = CascadeType.ALL) | ||
| @Builder.Default | ||
| private List<RestaurantCategory> restaurantCategories = new ArrayList<>(); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
find src/main/java -type f -name "Category.java" | head -20Repository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 132
🏁 Script executed:
find src/main/java -type f -name "RestaurantCategory.java" | head -20Repository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 142
🏁 Script executed:
cat -n src/main/java/com/kuit/baemin/domain/Restaurant/Category.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1109
🏁 Script executed:
cat -n src/main/java/com/kuit/baemin/domain/Restaurant/RestaurantCategory.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1064
양방향 연관관계 편의 메서드가 없어 객체 그래프 불일치 위험이 있습니다.
restaurantCategories 컬렉션만 보유하고 있어 RestaurantCategory의 category 필드와의 동기화가 호출부마다 누락될 수 있습니다. 연관관계 편의 메서드를 추가해 한 곳에서 양쪽 관계를 동시에 맞추는 것이 안전합니다.
🔧 제안 수정
// Category.java
+ public void addRestaurantCategory(RestaurantCategory restaurantCategory) {
+ this.restaurantCategories.add(restaurantCategory);
+ restaurantCategory.changeCategory(this);
+ }
+
+ public void removeRestaurantCategory(RestaurantCategory restaurantCategory) {
+ this.restaurantCategories.remove(restaurantCategory);
+ restaurantCategory.changeCategory(null);
+ }// RestaurantCategory.java
+ public void changeCategory(Category category) {
+ this.category = category;
+ }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Category.java` around lines
29 - 31, Category currently only holds the restaurantCategories collection which
can lead to mismatched object graphs because RestaurantCategory.category may not
be set; add bidirectional convenience methods (e.g., in Category
addRestaurantCategory(RestaurantCategory rc) and
removeRestaurantCategory(RestaurantCategory rc)) that set/unset
rc.setCategory(this) and update the restaurantCategories list, and ensure any
code that modifies the collection uses these methods instead of manipulating the
list directly to keep both sides (Category.restaurantCategories and
RestaurantCategory.category) synchronized.
| @OneToMany(mappedBy = "menu", fetch = FetchType.LAZY, cascade = CascadeType.ALL) | ||
| @Builder.Default | ||
| private List<MenuOptionGroup> optionGroups = new ArrayList<>(); | ||
|
|
||
| @OneToMany(mappedBy = "menu", fetch = FetchType.LAZY, cascade = CascadeType.ALL) | ||
| @Builder.Default | ||
| private List<OrderItem> orderItems = new ArrayList<>(); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, locate and examine the Menu.java file
find . -path "*/src/main/java/com/kuit/baemin/domain/Restaurant/Menu.java" -type fRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 130
🏁 Script executed:
# If the above doesn't find it, search more broadly
find . -name "Menu.java" -type f | grep -i domainRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 130
🏁 Script executed:
# Also search for MenuOptionGroup.java and OrderItem.java to verify bidirectionality
find . -name "MenuOptionGroup.java" -type f
find . -name "OrderItem.java" -type fRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 206
🏁 Script executed:
cat -n ./src/main/java/com/kuit/baemin/domain/Restaurant/Menu.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1591
🏁 Script executed:
cat -n ./src/main/java/com/kuit/baemin/domain/Restaurant/MenuOptionGroup.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1367
🏁 Script executed:
cat -n ./src/main/java/com/kuit/baemin/domain/Restaurant/OrderItem.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1526
양방향 연관관계 편의 메서드 추가가 필요합니다.
optionGroups와 orderItems는 양방향 연관관계이므로 동기화를 보장하는 편의 메서드가 필수입니다. 현재 코드에서는 menu.getOptionGroups().add(optionGroup) 같은 방식으로 추가할 경우, 반대쪽인 optionGroup.menu가 자동으로 설정되지 않아 트랜잭션 내 메모리 상태 불일치가 발생할 수 있습니다.
예시: addOptionGroup(MenuOptionGroup group) 메서드를 추가하여 양쪽 모두 동기화되도록 구현하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Menu.java` around lines 39 -
45, The Menu entity has two bidirectional collections (optionGroups and
orderItems) that lack convenience mutators; add methods like
addOptionGroup(MenuOptionGroup group) and addOrderItem(OrderItem item) on Menu
that (1) add the child to the appropriate list (optionGroups or orderItems) only
if not already present and (2) set the child's back-reference (call
group.setMenu(this) and item.setMenu(this)); also add corresponding
removeOptionGroup/removeOrderItem methods to clear the back-reference (set to
null) when removing to keep both sides synchronized and prevent memory-state
inconsistencies.
| @OneToMany(mappedBy = "menu", fetch = FetchType.LAZY, cascade = CascadeType.ALL) | ||
| @Builder.Default | ||
| private List<OrderItem> orderItems = new ArrayList<>(); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd /tmp && find . -name "Menu.java" -type f 2>/dev/null | head -5Repository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 52
🏁 Script executed:
find . -name "Menu.java" -type f 2>/dev/nullRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 130
🏁 Script executed:
find . -path "*domain*" -name "Menu.java" -type fRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 130
🏁 Script executed:
git ls-files | grep -i menu | grep -i javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 752
🏁 Script executed:
cat -n src/main/java/com/kuit/baemin/domain/Restaurant/Menu.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1591
🏁 Script executed:
find . -name "OrderItem.java" -type fRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 135
🏁 Script executed:
cat -n src/main/java/com/kuit/baemin/domain/Restaurant/OrderItem.javaRepository: Konkuk-KUIT/KUIT7_REST-API
Length of output: 1526
orderItems 컬렉션의 CascadeType.ALL은 주문 기록 손실 위험을 야기합니다.
OrderItem은 주문 시점의 메뉴 정보 스냅샷(menuNameSnapshot, menuPriceSnapshot)을 저장하는 주문 이력 데이터이며, Order 엔티티에 종속됩니다. 메뉴 삭제 시 과거 주문 항목까지 삭제되는 것을 방지하려면, orderItems에서 REMOVE 전파를 제외하세요. (예: cascade = {CascadeType.PERSIST, CascadeType.MERGE})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/domain/Restaurant/Menu.java` around lines 43 -
45, The orderItems collection in Menu uses CascadeType.ALL which will propagate
removes to OrderItem; update the `@OneToMany` on the orderItems field in class
Menu to remove REMOVE propagation by replacing cascade = CascadeType.ALL with a
limited set (e.g., cascade = {CascadeType.PERSIST, CascadeType.MERGE}) so
deletes of Menu do not cascade to OrderItem snapshots; keep mappedBy = "menu"
and fetch = FetchType.LAZY as-is.
| restaurantRepository.findById(req.getRestaurantId()) | ||
| .orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND)); | ||
|
|
||
| Order order = Order.builder() | ||
| .user(user) | ||
| .restaurant(restaurantRepository.findById(req.getRestaurantId()).get()) |
There was a problem hiding this comment.
중복 데이터베이스 조회를 제거하세요.
Restaurant를 Line 46-47에서 존재 여부 확인을 위해 조회한 후, Line 51에서 다시 조회하고 있습니다. 첫 번째 조회 결과를 변수에 저장하여 재사용하면 불필요한 데이터베이스 쿼리를 줄일 수 있습니다.
🔧 수정 제안
Member user = memberRepository.findById(userId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));
- restaurantRepository.findById(req.getRestaurantId())
+ Restaurant restaurant = restaurantRepository.findById(req.getRestaurantId())
.orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND));
Order order = Order.builder()
.user(user)
- .restaurant(restaurantRepository.findById(req.getRestaurantId()).get())
+ .restaurant(restaurant)
.deliveryAddressId(req.getDeliveryAddressId())
.orderStatus(OrderStatus.PENDING)
.requestMemo(req.getRequestMemo())
.build();📝 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.
| restaurantRepository.findById(req.getRestaurantId()) | |
| .orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND)); | |
| Order order = Order.builder() | |
| .user(user) | |
| .restaurant(restaurantRepository.findById(req.getRestaurantId()).get()) | |
| Member user = memberRepository.findById(userId) | |
| .orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND)); | |
| Restaurant restaurant = restaurantRepository.findById(req.getRestaurantId()) | |
| .orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND)); | |
| Order order = Order.builder() | |
| .user(user) | |
| .restaurant(restaurant) | |
| .deliveryAddressId(req.getDeliveryAddressId()) | |
| .orderStatus(OrderStatus.PENDING) | |
| .requestMemo(req.getRequestMemo()) | |
| .build(); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/service/OrderService.java` around lines 46 -
51, In OrderService, avoid calling
restaurantRepository.findById(req.getRestaurantId()) twice; fetch once, assign
the Optional's value to a local variable (e.g., restaurant) after orElseThrow,
and reuse that variable when building the Order (referencing
restaurantRepository.findById and Order.builder in the diff) so you remove the
duplicated DB query and use the same Restaurant instance for
order.setRestaurant.
| .menuNameSnapshot(menu.getName()) | ||
| .menuPriceSnapshot(menu.getPrice()) | ||
| .quantity(itemReq.getQuantity()) | ||
| .status("CONFIRMED") |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
하드코딩된 문자열 대신 상수 또는 enum을 사용하세요.
status("CONFIRMED")에서 문자열을 직접 사용하고 있습니다. 주문 아이템 상태를 나타내는 enum이나 상수를 정의하여 사용하면 타입 안전성과 유지보수성이 향상됩니다.
♻️ 개선 제안
방법 1: OrderItemStatus enum 생성
새 파일 src/main/java/com/kuit/baemin/domain/Restaurant/OrderItemStatus.java:
public enum OrderItemStatus {
CONFIRMED, PREPARING, COMPLETED, CANCELLED
}Service 수정:
OrderItem orderItem = OrderItem.builder()
.order(savedOrder)
.menu(menu)
.menuNameSnapshot(menu.getName())
.menuPriceSnapshot(menu.getPrice())
.quantity(itemReq.getQuantity())
- .status("CONFIRMED")
+ .status(OrderItemStatus.CONFIRMED.toString())
.build();방법 2: 상수 클래스 사용
public class OrderItemStatusConstants {
public static final String CONFIRMED = "CONFIRMED";
public static final String PREPARING = "PREPARING";
// ...
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/service/OrderService.java` at line 70, Replace
the hardcoded "CONFIRMED" literal used in OrderService (the .status("CONFIRMED")
call) with a typed constant or enum: add an OrderItemStatus enum (e.g.,
CONFIRMED, PREPARING, COMPLETED, CANCELLED) or a constants holder, then update
the .status invocation in OrderService to use that enum/constant (and convert to
the expected type if the status field is a String, e.g., use the enum's
name()/toString() or change the field/type to the enum) so the status value is
no longer hardcoded.
| * API 2: GET /restaurants — 식당 목록 조회 (페이징) | ||
| */ | ||
| public Page<RestaurantRes> getRestaurants(Pageable pageable) { | ||
| Page<Restaurant> restaurants = restaurantRepository.findByStatus("ACTIVE", pageable); |
There was a problem hiding this comment.
문자열 리터럴 대신 enum 상수를 사용하세요.
findByStatus("ACTIVE", pageable)에서 문자열 "ACTIVE"를 직접 사용하고 있습니다. RestaurantStatus.ACTIVE enum을 사용하는 것이 타입 안전성을 보장하고 오타를 방지할 수 있습니다.
✏️ 수정 제안
- Page<Restaurant> restaurants = restaurantRepository.findByStatus("ACTIVE", pageable);
+ Page<Restaurant> restaurants = restaurantRepository.findByStatus(RestaurantStatus.ACTIVE.toString(), pageable);또는 Repository 메서드를 RestaurantStatus 타입을 받도록 변경:
- Page<Restaurant> restaurants = restaurantRepository.findByStatus("ACTIVE", pageable);
+ Page<Restaurant> restaurants = restaurantRepository.findByStatus(RestaurantStatus.ACTIVE, pageable);📝 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.
| Page<Restaurant> restaurants = restaurantRepository.findByStatus("ACTIVE", pageable); | |
| Page<Restaurant> restaurants = restaurantRepository.findByStatus(RestaurantStatus.ACTIVE.toString(), pageable); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/service/RestaurantService.java` at line 48,
Replace the string literal "ACTIVE" with the RestaurantStatus enum when calling
restaurantRepository.findByStatus in RestaurantService; update the call to use
RestaurantStatus.ACTIVE and, if the repository method currently accepts a
String, change the repository signature (e.g., findByStatus(RestaurantStatus
status, Pageable pageable)) and any related query definitions to accept
RestaurantStatus to ensure type safety and prevent mismatches.
| Restaurant updated = Restaurant.builder() | ||
| .id(restaurant.getId()) | ||
| .name(req.getName()) | ||
| .phoneNumber(req.getPhoneNumber()) | ||
| .roadAddress(req.getRoadAddress()) | ||
| .detailAddress(req.getDetailAddress()) | ||
| .latitude(req.getLatitude()) | ||
| .longitude(req.getLongitude()) | ||
| .minOrderAmount(req.getMinOrderAmount()) | ||
| .deliveryFee(req.getDeliveryFee()) | ||
| .status(restaurant.getStatus()) | ||
| .menus(restaurant.getMenus()) | ||
| .orders(restaurant.getOrders()) | ||
| .build(); |
There was a problem hiding this comment.
JPA 엔티티 업데이트 방식을 변경하세요.
기존 엔티티를 빌더로 재생성하는 방식은 JPA의 영속성 컨텍스트와 변경 감지(dirty checking) 메커니즘을 우회합니다. 이는 연관관계 관리, 영속성 전이, 변경 이력 추적 등에서 예기치 않은 문제를 일으킬 수 있습니다. JPA 관리 엔티티의 setter 메서드를 사용하거나 엔티티 내부에 업데이트 메서드를 추가하는 것이 권장됩니다.
♻️ 수정 제안
방법 1: Setter 사용 (간단한 경우)
`@Transactional`
public RestaurantRes updateRestaurant(Long restaurantId, RestaurantReq req) {
Restaurant restaurant = restaurantRepository.findById(restaurantId)
.orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND));
- Restaurant updated = Restaurant.builder()
- .id(restaurant.getId())
- .name(req.getName())
- .phoneNumber(req.getPhoneNumber())
- .roadAddress(req.getRoadAddress())
- .detailAddress(req.getDetailAddress())
- .latitude(req.getLatitude())
- .longitude(req.getLongitude())
- .minOrderAmount(req.getMinOrderAmount())
- .deliveryFee(req.getDeliveryFee())
- .status(restaurant.getStatus())
- .menus(restaurant.getMenus())
- .orders(restaurant.getOrders())
- .build();
-
- restaurantRepository.save(updated);
- return RestaurantRes.from(updated);
+ restaurant.setName(req.getName());
+ restaurant.setPhoneNumber(req.getPhoneNumber());
+ restaurant.setRoadAddress(req.getRoadAddress());
+ restaurant.setDetailAddress(req.getDetailAddress());
+ restaurant.setLatitude(req.getLatitude());
+ restaurant.setLongitude(req.getLongitude());
+ restaurant.setMinOrderAmount(req.getMinOrderAmount());
+ restaurant.setDeliveryFee(req.getDeliveryFee());
+
+ return RestaurantRes.from(restaurant);
}방법 2: 엔티티에 업데이트 메서드 추가 (권장)
Restaurant 엔티티에 다음 메서드 추가:
public void updateInfo(String name, String phoneNumber, String roadAddress,
String detailAddress, Double latitude, Double longitude,
Integer minOrderAmount, Integer deliveryFee) {
this.name = name;
this.phoneNumber = phoneNumber;
this.roadAddress = roadAddress;
this.detailAddress = detailAddress;
this.latitude = latitude;
this.longitude = longitude;
this.minOrderAmount = minOrderAmount;
this.deliveryFee = deliveryFee;
}Service 메서드:
- Restaurant updated = Restaurant.builder()
- .id(restaurant.getId())
- .name(req.getName())
- ...
- .build();
-
- restaurantRepository.save(updated);
- return RestaurantRes.from(updated);
+ restaurant.updateInfo(
+ req.getName(),
+ req.getPhoneNumber(),
+ req.getRoadAddress(),
+ req.getDetailAddress(),
+ req.getLatitude(),
+ req.getLongitude(),
+ req.getMinOrderAmount(),
+ req.getDeliveryFee()
+ );
+ return RestaurantRes.from(restaurant);📝 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.
| Restaurant updated = Restaurant.builder() | |
| .id(restaurant.getId()) | |
| .name(req.getName()) | |
| .phoneNumber(req.getPhoneNumber()) | |
| .roadAddress(req.getRoadAddress()) | |
| .detailAddress(req.getDetailAddress()) | |
| .latitude(req.getLatitude()) | |
| .longitude(req.getLongitude()) | |
| .minOrderAmount(req.getMinOrderAmount()) | |
| .deliveryFee(req.getDeliveryFee()) | |
| .status(restaurant.getStatus()) | |
| .menus(restaurant.getMenus()) | |
| .orders(restaurant.getOrders()) | |
| .build(); | |
| restaurant.setName(req.getName()); | |
| restaurant.setPhoneNumber(req.getPhoneNumber()); | |
| restaurant.setRoadAddress(req.getRoadAddress()); | |
| restaurant.setDetailAddress(req.getDetailAddress()); | |
| restaurant.setLatitude(req.getLatitude()); | |
| restaurant.setLongitude(req.getLongitude()); | |
| restaurant.setMinOrderAmount(req.getMinOrderAmount()); | |
| restaurant.setDeliveryFee(req.getDeliveryFee()); | |
| return RestaurantRes.from(restaurant); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/service/RestaurantService.java` around lines 69
- 82, The code recreates a Restaurant via Restaurant.builder(...) which bypasses
JPA's persistence context and dirty-checking; instead add an instance method on
the entity (e.g., Restaurant.updateInfo(...) as described) or use existing
setters to mutate the managed Restaurant instance, then call that method from
RestaurantService (replace the Restaurant.builder(...) block with a call like
restaurant.updateInfo(...) so menus/orders/status remain managed and changes are
flushed by JPA).
| public void deleteRestaurant(Long restaurantId) { | ||
| Restaurant restaurant = restaurantRepository.findById(restaurantId) | ||
| .orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND)); | ||
| restaurantRepository.delete(restaurant); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
소프트 삭제(Soft Delete) 방식 고려를 권장합니다.
현재 delete() 메서드로 물리적 삭제를 수행하고 있습니다. RestaurantStatus enum이 존재하므로, 상태를 DELETED 또는 INACTIVE로 변경하는 소프트 삭제 방식을 고려해보세요. 이는 데이터 복구 가능성, 관련 주문/메뉴 데이터 보존, 감사 추적 등의 이점을 제공합니다.
♻️ 소프트 삭제 구현 예시
`@Transactional`
public void deleteRestaurant(Long restaurantId) {
Restaurant restaurant = restaurantRepository.findById(restaurantId)
.orElseThrow(() -> new GeneralException(ErrorStatus.RESTAURANT_NOT_FOUND));
- restaurantRepository.delete(restaurant);
+ restaurant.setStatus(RestaurantStatus.DELETED); // 또는 INACTIVE
}RestaurantStatus enum에 DELETED 상수 추가 필요:
public enum RestaurantStatus {
ACTIVE, INACTIVE, DELETED
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/kuit/baemin/service/RestaurantService.java` around lines 92
- 95, Replace the physical delete in RestaurantService.deleteRestaurant with a
soft-delete: add a DELETED (or INACTIVE) constant to the RestaurantStatus enum,
fetch the Restaurant as you already do, set
restaurant.setStatus(RestaurantStatus.DELETED) (or .INACTIVE), and save the
entity via restaurantRepository.save(restaurant) instead of calling
restaurantRepository.delete(...); ensure any business logic that relied on
find/delete uses repository queries that exclude DELETED (update repository
methods if needed) and keep the RestaurantService.deleteRestaurant,
RestaurantStatus, and restaurantRepository references consistent.
This reverts commit e559830.
Summary by CodeRabbit
릴리스 노트