Skip to content

feat: 발주 아이템 조회 기능 구현#70

Merged
JoonKyoLee merged 6 commits intomainfrom
feat/get-order-item
Nov 23, 2025
Merged

feat: 발주 아이템 조회 기능 구현#70
JoonKyoLee merged 6 commits intomainfrom
feat/get-order-item

Conversation

@JoonKyoLee
Copy link
Contributor

@JoonKyoLee JoonKyoLee commented Nov 23, 2025

✨ 작업 내용

  • 발주 아이템 조회 기능 구현

📝 적용 범위

  • /order

📌 참고 사항

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • 발주 항목의 상세 정보를 조회할 수 있는 기능이 추가되었습니다.
    • 발주 항목 조회 시 항목별 메모 정보가 포함되어 반환됩니다.
    • 권한 검증을 통해 본인의 발주 항목만 조회 가능합니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@JoonKyoLee JoonKyoLee self-assigned this Nov 23, 2025
@JoonKyoLee JoonKyoLee added the enhancement New feature or request label Nov 23, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 23, 2025

Walkthrough

발주 상세 조회 기능을 구현합니다. 컨트롤러에 /api/v1/order/item/{orderItemId} 엔드포인트를 추가하고, 서비스 레이어에 인가 검증 로직을 포함한 조회 메서드를 구현했습니다. DTO에 note 필드를 추가하고 성공 메시지 상수를 정의했으며, 전 계층에 걸쳐 단위 테스트를 작성했습니다.

Changes

칙합 / 파일(들) 변경 요약
성공 메시지 확장
src/main/java/com/almang/inventory/global/api/SuccessMessage.java
GET_ORDER_ITEM_SUCCESS("발주 아이템 조회 성공") 상수 추가
컨트롤러 엔드포인트
src/main/java/com/almang/inventory/order/controller/OrderController.java
GET /api/v1/order/item/{orderItemId} 엔드포인트 추가, 사용자 인증 및 서비스 위임 구현
응답 DTO 개선
src/main/java/com/almang/inventory/order/dto/response/OrderItemResponse.java
note 필드 추가, 매퍼 업데이트 (from 메서드)
서비스 비즈니스 로직
src/main/java/com/almang/inventory/order/service/OrderService.java
getOrderItem(Long, Long) 메서드 추가, findOrderItemById()validateOrderItemAccess() 헬퍼 메서드 구현, 접근 제어 검증 포함
컨트롤러 테스트
src/test/java/com/almang/inventory/order/controller/OrderControllerTest.java
정상 조회, 미존재(404), 접근 거부 시나리오 테스트 3건 추가
서비스 테스트
src/test/java/com/almang/inventory/order/service/OrderServiceTest.java
성공 조회(발주_상세_조회에_성공한다), 미존재 예외, 접근 거부 예외 테스트 3건 추가

Sequence Diagram

sequenceDiagram
    participant Client
    participant Controller as OrderController
    participant Service as OrderService
    participant Repo as Repository
    participant DB as Database

    Client->>Controller: GET /api/v1/order/item/{orderItemId}
    Controller->>Controller: Extract userId from principal
    Controller->>Service: getOrderItem(orderItemId, userId)
    
    Service->>Repo: findOrderItemById(orderItemId)
    Repo->>DB: Query OrderItem
    DB-->>Repo: OrderItem or empty
    
    alt Item not found
        Repo-->>Service: empty
        Service-->>Controller: throw ORDER_ITEM_NOT_FOUND
        Controller-->>Client: 404 Not Found
    else Item found
        Repo-->>Service: OrderItem
        Service->>Repo: findStoreByUserId(userId)
        Repo->>DB: Query Store
        DB-->>Repo: Store
        Service->>Service: validateOrderItemAccess(orderItem, store)
        
        alt Access denied
            Service-->>Controller: throw ORDER_ITEM_ACCESS_DENIED
            Controller-->>Client: 403 Forbidden
        else Access granted
            Service->>Service: OrderItemResponse.from(orderItem)
            Service-->>Controller: OrderItemResponse
            Controller-->>Client: 200 OK + GET_ORDER_ITEM_SUCCESS
        end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

주요 검토 포인트:

  • 접근 제어 로직: validateOrderItemAccess() 메서드에서 사용자 상점과 발주 항목의 상점을 정확히 비교하는지 확인 필요. 데이터베이스 쿼리 최적화 관점에서 N+1 문제 여부 검토 권장
  • DTO 확장: OrderItemResponsenote 필드 추가 시 기존 API 호출자에 미치는 영향 검토 (backward compatibility)
  • 테스트 커버리지: 세 가지 시나리오(성공, 404, 403)가 잘 커버되어 있으나, 엣지 케이스(null 주문 항목, 존재하지 않는 사용자) 추가 고려

Possibly related PRs

Poem

📦 한 발주의 상세함이
조회 엔드포인트 위에 피어나고,
접근 제어의 울타리가
각 상점의 경계를 지킨다네.
테스트 삼총사와 함께
완성된 기능의 춤! 🎭

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
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 (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 PR의 주요 변경사항을 명확하게 요약하고 있으며, 발주 아이템 조회 기능 구현이라는 핵심 목표를 효과적으로 전달합니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르고 있으며, 작업 내용, 적용 범위, 참고 사항을 모두 포함하고 있습니다.
Linked Issues check ✅ Passed PR의 변경사항들이 issue #63의 '발주 상세 조회 기능 구현' 요구사항을 완벽하게 충족하고 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 발주 아이템 조회 기능과 직접 관련되어 있으며, 범위를 벗어난 변경사항이 없습니다.
✨ 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/get-order-item

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

🧹 Nitpick comments (4)
src/main/java/com/almang/inventory/order/controller/OrderController.java (1)

10-10: 발주 아이템 조회 엔드포인트가 기존 패턴과 잘 맞습니다

  • 인증 정보에서 userId 추출 → 서비스 위임 → ApiResponse.success로 감싸는 흐름이 기존 getOrder/getOrderList와 동일해서 유지보수성이 좋습니다.
  • SuccessMessage.GET_ORDER_ITEM_SUCCESS를 바로 사용한 것도 응답 일관성 측면에서 좋습니다.

Swagger 메타데이터만 살짝 다듬으면 더 읽기 좋아집니다:

-    @Operation(summary = "발주 아이템 조회", description = "발주 아이템 조회합니다.")
+    @Operation(summary = "발주 아이템 조회", description = "발주 아이템을 조회합니다.")

크게 중요한 부분은 아니므로, 문구가 마음에 들 때 반영하시면 됩니다.

Also applies to: 107-120

src/main/java/com/almang/inventory/order/service/OrderService.java (1)

14-14: 발주 아이템 조회 서비스 플로우가 안정적으로 설계되었습니다

좋은 점부터 정리하면:

  • getOrderItem에서 공통 패턴(사용자 조회 → store 획득 → 접근 검증 → DTO 매핑)을 그대로 따라가서, 다른 메서드들과 읽는 경험이 통일되어 있습니다.
  • ORDER_ITEM_NOT_FOUND / ORDER_ITEM_ACCESS_DENIED를 명확히 분리해서 예외를 던지고 있고, 테스트와도 정확히 매칭됩니다.
  • OrderItemResponse.from(orderItem)으로 DTO 매핑을 위임한 것도 응집도 측면에서 좋습니다.

다만, 몇 가지 작은 리팩터를 고려해 볼 수 있습니다.

  1. 로그 메시지 용어를 엔드포인트와 맞추기
    현재 로그는 "발주 상세 조회"인데, 컨트롤러/성공 메시지는 "발주 아이템 조회"를 쓰고 있습니다. 나중에 로그만 보고 추적할 때 용어가 통일되어 있는 편이 이해가 더 빠릅니다.
-        log.info("[OrderService] 발주 상세 조회 요청 - userId: {}, storeId: {}", userId, store.getId());
+        log.info("[OrderService] 발주 아이템 조회 요청 - userId: {}, storeId: {}", userId, store.getId());
...
-        log.info("[OrderService] 발주 상세 조회 성공 - orderItemId: {}", orderItem.getId());
+        log.info("[OrderService] 발주 아이템 조회 성공 - orderItemId: {}", orderItem.getId());
  1. ORDER_ITEM 조회/검증 로직 중복을 살짝 줄이기
    이미 findOrderItemByIdAndValidateAccess(Long orderItemId, Order order)가 있고, 새로 findOrderItemById + validateOrderItemAccess가 추가되어 두 군데에서 비슷한 검증을 하게 됩니다.
    필수는 아니지만, 아래처럼 기존 메서드가 새 헬퍼를 재사용하게 하면 규칙 변경 시 수정 지점이 줄어듭니다.
-    private OrderItem findOrderItemByIdAndValidateAccess(Long orderItemId, Order order) {
-        OrderItem orderItem = orderItemRepository.findById(orderItemId)
-                .orElseThrow(() -> new BaseException(ErrorCode.ORDER_ITEM_NOT_FOUND));
-
-        if (!orderItem.getOrder().getId().equals(order.getId())) {
-            throw new BaseException(ErrorCode.ORDER_ITEM_ACCESS_DENIED);
-        }
-        return orderItem;
-    }
+    private OrderItem findOrderItemByIdAndValidateAccess(Long orderItemId, Order order) {
+        OrderItem orderItem = findOrderItemById(orderItemId);
+        if (!orderItem.getOrder().getId().equals(order.getId())) {
+            throw new BaseException(ErrorCode.ORDER_ITEM_ACCESS_DENIED);
+        }
+        return orderItem;
+    }

이 두 가지는 전부 가독성과 유지보수성을 위한 선택 사항이라, 팀 코딩 스타일에 맞춰 여유 있을 때 적용하셔도 좋겠습니다.

Also applies to: 119-130, 288-297

src/test/java/com/almang/inventory/order/service/OrderServiceTest.java (1)

16-16: getOrderItem 서비스 테스트 커버리지가 깔끔합니다

  • 발주_상세_조회에_성공한다에서 orderItemId, productId, quantity, unitPrice, amount, note까지 모두 검증하고 있어 DTO 매핑 이상 여부를 잘 잡아낼 수 있습니다.
  • 존재하지 않는 ID와, 다른 상점에 속한 아이템에 대한 ORDER_ITEM_NOT_FOUND / ORDER_ITEM_ACCESS_DENIED 예외 플로우도 각각 분리해서 테스트한 점이 좋습니다.

작은 개선 아이디어 한 가지 정도만 제안드리면:

  • 컨트롤러/성공 메시지에서 쓰는 용어는 “발주 아이템 조회”인데, 테스트 메서드 이름은 “발주_상세_조회…”로 되어 있습니다. 나중에 검색/정리할 때 혼선을 줄이려면 예를 들어 다음처럼 통일하는 것도 고려해볼 수 있습니다.
-    void 발주_상세_조회에_성공한다() {
+    void 발주_아이템_상세_조회에_성공한다() {

테스트 자체는 이미 충분히 견고하니, 네이밍은 팀 내 용어 정책에 맞춰 여유 있을 때 정리하셔도 됩니다.

Also applies to: 893-973

src/test/java/com/almang/inventory/order/controller/OrderControllerTest.java (1)

23-23: 발주 아이템 조회 컨트롤러 테스트 구성이 적절합니다

  • 성공/존재하지 않음/다른 상점 아이템 접근 거부까지 세 가지 플로우를 모두 검증해서, HTTP 상태 코드와 ErrorCode 매핑이 잘 보호되고 있습니다.
  • SuccessMessage.GET_ORDER_ITEM_SUCCESS 메시지까지 검증해 둔 점도 응답 규격 변경을 잘 탐지할 수 있어서 좋습니다.

조금 더 방어적으로 가고 싶다면, 성공 케이스에서 amount, note까지도 한 줄씩만 추가로 확인해 두면 직렬화 레벨에서의 필드 누락/타이포도 잡아낼 수 있습니다.

-                .andExpect(jsonPath("$.data.productId").value(10L));
+                .andExpect(jsonPath("$.data.productId").value(10L))
+                .andExpect(jsonPath("$.data.amount").value(5000))
+                .andExpect(jsonPath("$.data.note").value("비고입니다"));

이미 서비스 테스트에서 값 검증을 하고 있어 필수는 아니고, 컨트롤러 단에서 어디까지 검증할지에 대한 팀 기준에 따라 선택하시면 되겠습니다.

Also applies to: 568-634

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 238fe88 and 5ed2cb5.

📒 Files selected for processing (6)
  • src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1 hunks)
  • src/main/java/com/almang/inventory/order/controller/OrderController.java (2 hunks)
  • src/main/java/com/almang/inventory/order/dto/response/OrderItemResponse.java (2 hunks)
  • src/main/java/com/almang/inventory/order/service/OrderService.java (3 hunks)
  • src/test/java/com/almang/inventory/order/controller/OrderControllerTest.java (2 hunks)
  • src/test/java/com/almang/inventory/order/service/OrderServiceTest.java (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-22T18:12:13.161Z
Learnt from: JoonKyoLee
Repo: almang2/inventory-server PR: 66
File: src/main/java/com/almang/inventory/order/domain/OrderItem.java:41-53
Timestamp: 2025-11-22T18:12:13.161Z
Learning: In the almang2/inventory-server repository, OrderItem entity update methods (updateQuantity, updatePrice in src/main/java/com/almang/inventory/order/domain/OrderItem.java) do not require null checks because OrderService will validate parameters before calling these update methods, following the same pattern as Product entity updates.
<!--

Applied to files:

  • src/main/java/com/almang/inventory/order/dto/response/OrderItemResponse.java
  • src/main/java/com/almang/inventory/order/service/OrderService.java
  • src/test/java/com/almang/inventory/order/controller/OrderControllerTest.java
  • src/test/java/com/almang/inventory/order/service/OrderServiceTest.java
  • src/main/java/com/almang/inventory/order/controller/OrderController.java
📚 Learning: 2025-11-20T10:43:47.489Z
Learnt from: JoonKyoLee
Repo: almang2/inventory-server PR: 33
File: src/main/java/com/almang/inventory/product/domain/Product.java:62-66
Timestamp: 2025-11-20T10:43:47.489Z
Learning: In the almang2/inventory-server repository, Product entity update methods (e.g., updateVendor in src/main/java/com/almang/inventory/product/domain/Product.java) do not require null checks on vendor parameters because ProductService validates vendor existence via findVendorByIdAndValidateAccess before calling update methods, and the vendor field has nullable=false constraint ensuring this.vendor is never null for persisted entities.

Applied to files:

  • src/test/java/com/almang/inventory/order/service/OrderServiceTest.java
🔇 Additional comments (2)
src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1)

46-46: 발주 아이템 성공 메시지 추가 적절합니다

GET_ORDER_ITEM_SUCCESS 네이밍과 한글 메시지가 기존 ORDER 관련 상수들과 일관되고, 컨트롤러 응답에도 잘 매핑될 수 있는 형태입니다. 별도 수정 필요 없어 보입니다.

src/main/java/com/almang/inventory/order/dto/response/OrderItemResponse.java (1)

13-15: OrderItem 응답 DTO 확장이 자연스럽게 잘 되었습니다

  • amountnote를 record 컴포넌트로 추가하고, from(OrderItem)에서 엔티티의 getAmount(), getNote()를 그대로 매핑한 구조가 명확합니다.
  • ORDER/PRODUCT 널 방어 로직도 그대로 유지되어 있어, 매핑 시 불변 조건을 잘 지키고 있습니다.

현재 형태만으로도 도메인 모델과 응답 스키마가 잘 동기화되어 있어서, 추가 수정이 필요해 보이지 않습니다.

Also applies to: 26-27

@JoonKyoLee JoonKyoLee merged commit 6bc7cc3 into main Nov 23, 2025
1 check passed
@JoonKyoLee JoonKyoLee deleted the feat/get-order-item branch November 23, 2025 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 발주 상세 조회 기능 구현

1 participant