Skip to content

feat: 입고 아이템 조회 기능 구현#91

Merged
JoonKyoLee merged 4 commits intomainfrom
feat/get-receipt-item
Nov 24, 2025
Merged

feat: 입고 아이템 조회 기능 구현#91
JoonKyoLee merged 4 commits intomainfrom
feat/get-receipt-item

Conversation

@JoonKyoLee
Copy link
Contributor

@JoonKyoLee JoonKyoLee commented Nov 24, 2025

✨ 작업 내용

  • 입고 아이템 조회 기능 구현

📝 적용 범위

  • /receipt

📌 참고 사항

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 입고 아이템 개별 조회 기능 추가됨
    • 조회 시 사용자의 권한 검증 기능 포함
  • 개선 사항

    • 접근 권한 관련 오류 메시지 명확화됨
  • 테스트

    • 아이템 조회 성공/실패 시나리오에 대한 테스트 케이스 추가됨
    • 권한 검증 및 오류 처리에 대한 테스트 확대됨

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

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

coderabbitai bot commented Nov 24, 2025

Walkthrough

입고 아이템 조회 기능을 구현했습니다. 새로운 GET 엔드포인트, 서비스 메서드, 성공 메시지를 추가하고 에러 메시지를 개선했으며, 성공/실패 시나리오에 대한 테스트를 작성했습니다.

Changes

Cohort / File(s) 변경 요약
API 응답 설정
src/main/java/com/almang/inventory/global/api/SuccessMessage.java
새로운 enum 상수 GET_RECEIPT_ITEM_SUCCESS("입고 아이템 조회 성공") 추가
ErrorCode 업데이트
src/main/java/com/almang/inventory/global/exception/ErrorCode.java
입고 아이템 조회 기능 구현
src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java
GET /receipt/{receiptItemId} 엔드포인트 추가, 사용자 인증 확인 후 서비스 호출 및 ReceiptItemResponse 반환
ReceiptService 기능 확장
src/main/java/com/almang/inventory/receipt/service/ReceiptService.java
테스트 커버리지
src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java, src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java
성공 케이스(정상 조회), 실패 케이스(사용자 없음, 아이템 없음, 접근 거부) 등 총 4개 테스트 시나리오 추가

Sequence Diagram

sequenceDiagram
    participant Client
    participant Controller as ReceiptController
    participant Service as ReceiptService
    participant Repo as ReceiptItemRepository

    Client->>Controller: GET /receipt/{receiptItemId}
    activate Controller
    Note over Controller: 사용자 인증 확인
    Controller->>Service: getReceiptItem(receiptItemId, userId)
    activate Service
    
    Service->>Service: 사용자 조회
    Service->>Service: 상점 파생
    Service->>Service: 상점별 아이템 접근 권한 검증
    Service->>Repo: findReceiptItemByIdAndValidateStoreAccess()
    activate Repo
    Repo-->>Service: ReceiptItem
    deactivate Repo
    
    Service->>Service: ReceiptItemResponse로 변환
    Service-->>Controller: ReceiptItemResponse
    deactivate Service
    
    Controller-->>Client: ApiResponse<ReceiptItemResponse>
    deactivate Controller
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

추가 검토 항목:

  • ReceiptService.findReceiptItemByIdAndValidateStoreAccess() 메서드의 예외 처리 로직 — 접근 거부 시 RECEIPT_ITEM_ACCESS_DENIED 예외가 올바르게 발생하는지 확인
  • ReceiptControllerTest의 중복된 테스트 블록 — 요약에 "two places (duplicate blocks)"라고 표기되어 있으니 정리 필요
  • ReceiptServiceTest의 테스트 메서드 명명 규칙이 한영 혼용되어 있으니 일관성 검토 추천

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 변경사항이 이슈 #77의 목표인 '입고 아이템 조회 기능 구현'을 완전히 충족합니다. 엔드포인트, 서비스, 테스트 케이스가 모두 구현되었습니다.
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-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/receipt/service/ReceiptService.java (1)

148-158: 입고 아이템 조회 로직은 적절하고, 로그 메시지만 약간 손보면 좋겠습니다

  • getReceiptItem / findReceiptItemByIdAndValidateStoreAccess 구조는 기존 findReceiptByIdAndValidateAccess 패턴과 일관되고, Store 기준 접근 제어도 올바르게 구현되어 있습니다. 도메인/권한 관점에서 큰 문제는 없습니다.
  • 다만 Line 156에서 성공 로그 메시지가
    "[ReceiptService] 입고 아이템 조회 요청 - receiptId: {}" 로 되어 있고, 실제로는 receiptItem.getId()를 찍고 있어서 운영 로그에서 혼동이 생길 수 있습니다. 성공 로그 문구와 필드명을 receipt item 기준으로 맞추는 편이 좋겠습니다.

예시 수정안입니다:

-        log.info("[ReceiptService] 입고 아이템 조회 요청 - receiptId: {}", receiptItem.getId());
+        log.info("[ReceiptService] 입고 아이템 조회 성공 - receiptItemId: {}", receiptItem.getId());

이렇게 하면 요청/성공 로그가 각각 무엇을 의미하는지, 어떤 ID를 남기는지 한눈에 구분되기 때문에 운영 중 트러블슈팅이 훨씬 수월해집니다.

Also applies to: 311-319

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

21-22: 입고 아이템 조회 서비스 테스트 커버리지는 충분하며, 중복만 추후에 정리해도 좋겠습니다

  • 성공/실패 4가지 시나리오가 모두 잘 분리되어 있고, 특히 성공 케이스에서 실제 Receipt/ReceiptItem를 영속화한 뒤 ReceiptItemResponse의 각 필드를 검증하는 점이 좋습니다. 서비스 로직과 DTO 매핑 양쪽을 동시에 검증하고 있습니다.
  • 실패 케이스에서 각각 USER_NOT_FOUND, RECEIPT_ITEM_NOT_FOUND, RECEIPT_ITEM_ACCESS_DENIED를 명시적으로 기대하는 것도 ErrorCode 계약을 잘 고정해 줍니다.

다만 이 파일 전체가 그렇듯이, 이번에 추가된 테스트도 Store/User/Vendor/Order/Receipt/ReceiptItem 생성 코드가 반복되는 편입니다. 당장은 유지보수에 큰 부담은 아니지만, 나중에라도 다음처럼 헬퍼를 한 단계 추상화하면 테스트 가독성이 꽤 좋아질 것 같습니다.

  • 예: Receipt newReceiptWithItems(Store store, Vendor vendor) 같은 팩토리 메서드 추가
  • 또는 createReceiptWithItemsFor(Store store, String username) 정도의 상위 수준 DSL 메서드 도입

현재 PR 범위를 고려하면 필수는 아니고, 추후 리팩터링 후보로만 봐도 충분해 보입니다.

Also applies to: 982-1088

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

782-869: 입고 아이템 조회 컨트롤러 테스트는 계약을 잘 고정하고 있으며, 엔드포인트 네이밍만 한 번 고민해 볼 만합니다

  • SuccessMessage.GET_RECEIPT_ITEM_SUCCESSErrorCode들(존재하지 않음/권한 없음)에 대해 HTTP 상태 코드와 응답 바디 구조를 모두 검증하고 있어서, 컨트롤러와 전역 예외 핸들러 사이 계약이 잘 고정되어 있습니다. 테스트 구성 자체는 매우 좋습니다.
  • 한 가지, 엔드포인트가 최종적으로 /api/v1/receipt/receipt/{receiptItemId} 형태가 되는데, 동일 리소스 명이 두 번 반복되는 URI는 가독성이 조금 떨어질 수 있습니다.
    • 예: /api/v1/receipt/item/{receiptItemId} 또는 /api/v1/receipt/items/{receiptItemId}처럼 리소스 계층을 분리하는 것도 선택지입니다.
  • 지금 구현/테스트는 일관되게 이 경로를 사용하고 있으므로 동작 상 문제는 없고, 향후 API 외부 공개 범위와 버전 전략을 보면서 필요하면 리팩터링(또는 alias 경로 추가)을 고려하셔도 좋겠습니다.
src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java (1)

10-11: 입고 아이템 조회 엔드포인트 구현은 깔끔하며, URI 구조만 약간 더 다듬을 여지가 있습니다

  • 구현 패턴이 기존 메서드(getReceipt, getReceiptFromOrder)와 거의 동일해서, 인증 주체 → userId 추출 → 서비스 호출 → ApiResponse.success 흐름이 잘 맞습니다. SuccessMessage.GET_RECEIPT_ITEM_SUCCESS 사용도 적절합니다.
  • 다만 클래스 레벨 @RequestMapping("/api/v1/receipt") + 메서드 @GetMapping("/receipt/{receiptItemId}") 조합으로 실제 URI가 /api/v1/receipt/receipt/{receiptItemId}가 됩니다. 의미적으로는 맞지만, 리소스명이 이중으로 들어가서 약간 장황하게 느껴질 수 있습니다.
    • 향후 API 외부 공개/버전 호환성을 고려하면, 예를 들어 /api/v1/receipt/item/{receiptItemId} 또는 /api/v1/receipt/items/{receiptItemId} 같은 형태로 바꾸는 것도 고민해볼 만합니다.
  • 지금 단계에서 기능적으로 문제는 없으니, 단기적으로는 그대로 사용하시되 다음 큰 API 리팩터링 타이밍에 URI 구조를 정리하는 후보로 올려두시면 좋겠습니다.

Also applies to: 138-151

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 439554c and fb139a3.

📒 Files selected for processing (6)
  • 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/service/ReceiptService.java (3 hunks)
  • src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java (1 hunks)
  • src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 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/receipt/controller/ReceiptController.java
  • src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java
  • src/main/java/com/almang/inventory/receipt/service/ReceiptService.java
🔇 Additional comments (2)
src/main/java/com/almang/inventory/global/exception/ErrorCode.java (1)

54-54: 입고 아이템 권한 에러 메시지 방향성 좋습니다

기존 도메인 제약 설명형 문구보다, 지금처럼 권한 중심의 일반화된 "입고 아이템에 접근할 수 없습니다." 메시지가 다양한 접근 거부 케이스(다른 상점, 잘못된 연관 등)에 재사용하기 훨씬 좋습니다. 별도 수정 필요 없어 보입니다.

src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1)

50-58: 입고 아이템 조회 성공 메시지 추가, 기존 패턴과 잘 맞습니다

GET_RECEIPT_ITEM_SUCCESS 네이밍과 "입고 아이템 조회 성공" 문구가 GET_ORDER_ITEM_SUCCESS와 대칭이라, API 응답 레벨에서 도메인 간 일관성이 잘 유지되고 있습니다. 별도 수정 없이 이대로 사용해도 좋겠습니다.

@JoonKyoLee JoonKyoLee merged commit 8600175 into main Nov 24, 2025
1 check passed
@JoonKyoLee JoonKyoLee deleted the feat/get-receipt-item branch November 25, 2025 03:30
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