Skip to content

feat: 발주 기반 입고 조회 기능 구현#83

Merged
JoonKyoLee merged 4 commits intomainfrom
feat/get-receipt-from-order
Nov 23, 2025
Merged

feat: 발주 기반 입고 조회 기능 구현#83
JoonKyoLee merged 4 commits intomainfrom
feat/get-receipt-from-order

Conversation

@JoonKyoLee
Copy link
Contributor

@JoonKyoLee JoonKyoLee commented Nov 23, 2025

✨ 작업 내용

  • 발주 기반 입고 조회 기능 구현

📝 적용 범위

  • /receipt

📌 참고 사항

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 주문 ID 기반 입고 정보 조회 기능 추가: 특정 주문에 대한 입고 데이터를 직접 조회할 수 있습니다.
  • Tests

    • 주문 기반 입고 조회 관련 테스트 케이스 추가 (성공 케이스 및 다양한 예외 상황 포함)

✏️ 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

발주 ID를 기반으로 입고 정보를 조회하는 새로운 기능을 구현했습니다. 컨트롤러 엔드포인트, 서비스 로직, 리포지토리 쿼리, API 응답 메시지, 에러 코드 및 포괄적인 테스트 케이스를 추가했습니다.

Changes

Cohort / File(s) 요약
API 응답 및 에러 정의
src/main/java/com/almang/inventory/global/api/SuccessMessage.java, src/main/java/com/almang/inventory/global/exception/ErrorCode.java
SuccessMessage enum에 GET_RECEIPT_FROM_ORDER_SUCCESS 상수 추가, ErrorCode enum에 RECEIPT_NOT_FOUND 에러 코드 추가
저장소 계층
src/main/java/com/almang/inventory/receipt/repository/ReceiptRepository.java
발주 ID로 입고를 조회하는 findByOrder_Id(Long orderId) 메서드 추가
비즈니스 로직
src/main/java/com/almang/inventory/receipt/service/ReceiptService.java
사용자 검증 및 접근 제어를 포함한 getReceiptFromOrder(Long orderId, Long userId) 메서드 추가, 내부 헬퍼 메서드 추가
컨트롤러 엔드포인트
src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java
GET /from-order/{orderId} 엔드포인트 추가로 인증된 사용자의 입고 조회 기능 제공
테스트 커버리지
src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java, src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java
성공 케이스 및 5가지 예외 시나리오(사용자 미존재, 발주 미존재, 접근 거부, 입고 미존재)를 다루는 통합 테스트와 단위 테스트 추가

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as ReceiptController
    participant Service as ReceiptService
    participant Repo as ReceiptRepository
    participant DB as Database

    Client->>Controller: GET /from-order/{orderId}
    activate Controller
    Controller->>Service: getReceiptFromOrder(orderId, userId)
    deactivate Controller
    
    activate Service
    Service->>Service: findUserById(userId)
    alt User Not Found
        Service-->>Client: USER_NOT_FOUND Exception
    end
    
    Service->>Service: validateOrderAccessByUserId(orderId, userId)
    alt Order Not Found
        Service-->>Client: ORDER_NOT_FOUND Exception
    end
    
    alt Order Access Denied
        Service-->>Client: ORDER_ACCESS_DENIED Exception
    end
    
    Service->>Repo: findByOrder_Id(orderId)
    Repo->>DB: Query Receipt by Order ID
    DB-->>Repo: Receipt or Empty
    Repo-->>Service: Optional<Receipt>
    
    alt Receipt Not Found
        Service-->>Client: RECEIPT_NOT_FOUND Exception
    end
    
    Service->>Service: mapToResponse(receipt)
    Service-->>Client: ApiResponse<ReceiptResponse> (200 OK)
    deactivate Service
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 분

주의 깊게 검토할 영역:

  • 접근 제어 검증: validateOrderAccessByUserId() 호출 순서 확인 — 발주 조회 전에 사용자 및 스토어 검증이 올바르게 수행되는지 검증 필요
  • 테스트 커버리지의 일관성: 컨트롤러와 서비스 테스트에서 예외 시나리오가 동일하게 처리되고 있는지 확인
  • 리포지토리 쿼리: findByOrder_Id() 메서드가 JPA Derived Query로 제대로 해석되는지, 성능상 N+1 문제가 없는지 검증

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 코드 변경사항이 Issue #74의 요구 사항인 발주 기반 입고 조회 기능 구현을 완전히 만족합니다.
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-receipt-from-order

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 858f97e and 642f78f.

📒 Files selected for processing (7)
  • src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1 hunks)
  • src/main/java/com/almang/inventory/global/exception/ErrorCode.java (1 hunks)
  • src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java (2 hunks)
  • src/main/java/com/almang/inventory/receipt/repository/ReceiptRepository.java (1 hunks)
  • src/main/java/com/almang/inventory/receipt/service/ReceiptService.java (2 hunks)
  • src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java (2 hunks)
  • src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java (3 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/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.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/receipt/service/ReceiptServiceTest.java
🔇 Additional comments (8)
src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1)

52-52: LGTM! 성공 메시지 상수가 올바르게 추가되었습니다.

기존 패턴과 일관되게 구현되었고, RECEIPT 섹션에 적절히 배치되었습니다.

src/main/java/com/almang/inventory/global/exception/ErrorCode.java (1)

50-50: LGTM! 에러 코드가 적절하게 정의되었습니다.

404 NOT_FOUND 상태와 명확한 에러 메시지로 구성되어 있으며, 다른 에러 코드들과 일관된 패턴을 따르고 있습니다.

src/main/java/com/almang/inventory/receipt/repository/ReceiptRepository.java (1)

9-9: LGTM! Spring Data JPA 쿼리 메서드가 올바르게 구현되었습니다.

findByOrder_Id는 Spring Data JPA의 underscore 표기법을 사용하여 연관 엔티티의 필드(order.id)에 접근하는 derived query method입니다. 메서드 명명 규칙을 정확히 따르고 있으며, Optional 반환 타입도 적절합니다.

참고: Spring Data JPA에서 underscore는 nested property 접근을 명시적으로 표현합니다.

src/main/java/com/almang/inventory/receipt/service/ReceiptService.java (2)

56-69: LGTM! 입고 조회 로직이 견고하게 구현되었습니다.

사용자 검증 → 발주 접근 권한 검증 → 입고 조회의 흐름이 명확하며, @Transactional(readOnly = true)로 읽기 전용 트랜잭션을 적절히 설정했습니다. 로깅도 잘 되어 있어 추적이 용이합니다.

참고: 발주의 상점 소유권을 먼저 검증하므로, 해당 발주에 연결된 입고도 동일한 상점에 속한다는 것이 데이터 무결성에 의해 보장됩니다.


128-131: LGTM! 깔끔한 헬퍼 메서드입니다.

입고 조회 로직을 별도 메서드로 분리하여 가독성과 재사용성을 높였습니다. 새로 추가된 RECEIPT_NOT_FOUND 에러 코드를 적절히 사용하고 있습니다.

src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java (1)

42-54: LGTM! RESTful API 엔드포인트가 깔끔하게 구현되었습니다.

GET 메서드를 사용한 조회 엔드포인트가 REST 원칙에 부합하며, 기존 POST 엔드포인트와 일관된 구조를 유지하고 있습니다. 인증 처리와 로깅도 적절합니다.

위트: POST로 만들고 GET으로 조회하는 완벽한 CRUD의 균형! 👌

src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java (1)

227-321: LGTM! 서비스 계층 테스트가 매우 포괄적입니다.

4가지 시나리오를 모두 커버하고 있습니다:

  • ✅ 정상 조회 (입고 + 발주 아이템 검증)
  • ✅ 입고 미존재 예외 (RECEIPT_NOT_FOUND)
  • ✅ 접근 권한 검증 (ORDER_ACCESS_DENIED)
  • ✅ 사용자 검증 (USER_NOT_FOUND)

테스트 데이터 설정이 명확하고, 기존 테스트 패턴과도 일관성을 유지하고 있습니다. 특히 Line 246-254에서 OrderItem으로부터 ReceiptItem을 생성하는 로직이 실제 프로덕션 코드와 유사하여 통합 테스트로서의 가치가 높습니다.

src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java (1)

176-296: LGTM! 컨트롤러 테스트가 완벽하게 구성되었습니다.

5개의 테스트 케이스로 모든 응답 시나리오를 커버하고 있습니다:

  • ✅ 200 OK: 정상 조회 + 응답 구조 검증
  • ✅ 404 NOT_FOUND: 사용자/발주/입고 미존재
  • ✅ 403 FORBIDDEN: 접근 권한 없음

MockMvc를 활용한 통합 테스트 방식이 적절하며, JSON 응답의 각 필드를 세밀하게 검증하고 있습니다. 서비스 계층 테스트와 함께 엔드투엔드 테스트 커버리지가 우수합니다.

칭찬: 5개의 실패 시나리오까지 꼼꼼히 테스트하는 센스! 이 정도면 프로덕션 배포 준비 완료입니다. 🚀


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

@JoonKyoLee JoonKyoLee merged commit 35ded17 into main Nov 23, 2025
1 check passed
@JoonKyoLee JoonKyoLee deleted the feat/get-receipt-from-order branch November 24, 2025 14:58
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