Skip to content

feat: 품목 상세 조회 기능 구현#34

Merged
JoonKyoLee merged 4 commits intomainfrom
feat/product-detail
Nov 20, 2025
Merged

feat: 품목 상세 조회 기능 구현#34
JoonKyoLee merged 4 commits intomainfrom
feat/product-detail

Conversation

@JoonKyoLee
Copy link
Contributor

@JoonKyoLee JoonKyoLee commented Nov 20, 2025

✨ 작업 내용

  • 품목 상세 조회 기능 추가

📝 적용 범위

  • /product

📌 참고 사항

Summary by CodeRabbit

Release Notes

  • 새로운 기능

    • 사용자 인증 및 저장소 접근 제어가 적용된 상품 상세 조회 기능 추가. 사용자는 자신의 저장소에 속한 상품의 상세 정보를 안전하게 조회할 수 있습니다.
  • 테스트

    • 상품 상세 조회의 성공 케이스, 존재하지 않는 상품 처리, 저장소 접근 권한 검증 등을 포함한 포괄적인 테스트 케이스 추가.

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

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

coderabbitai bot commented Nov 20, 2025

한눈에 보기

Walkthrough

품목 상세 조회 기능을 구현합니다. ProductService에 getProductDetail 메서드 추가, ProductController에 GET 엔드포인트 추가, 스토어 접근 권한 검증을 별도 헬퍼 메서드로 분리, 관련 테스트 케이스 추가되었습니다.

Changes

분류 / 파일 변경 요약
SuccessMessage 상수 추가
src/main/java/com/almang/inventory/global/api/SuccessMessage.java
GET_PRODUCT_DETAIL_SUCCESS("품목 상세 조회 성공") 열거형 상수 추가
ProductController 엔드포인트 추가
src/main/java/com/almang/inventory/product/controller/ProductController.java
GET /api/v1/product/{productId} 엔드포인트 추가, 인증된 사용자의 상품 상세 조회 처리, 스웨거 문서화 포함
ProductService 메서드 추가
src/main/java/com/almang/inventory/product/service/ProductService.java
getProductDetail(productId, userId) 퍼블릭 메서드 추가, 스토어 접근 권한 검증 로직을 validateStoreAccess(product, user) 프라이빗 헬퍼로 분리, 기존 updateProduct에서 권한 검증 헬퍼 활용
ProductControllerTest 테스트 케이스 추가
src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java
상세 조회 성공 케이스, 상품 미존재 시 404 에러 검증, 다른 스토어 상품 접근 시 403 에러 검증 (3개 테스트 케이스)
ProductServiceTest 테스트 케이스 추가
src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
상세 조회 성공 후 모든 필드 검증, 미존재 상품 조회 예외 처리, 다른 스토어 상품 조회 예외 처리 (3개 테스트 케이스)

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as ProductController
    participant Service as ProductService
    participant Repo as ProductRepository
    participant DB

    Client->>Controller: GET /api/v1/product/{productId}
    Controller->>Controller: Extract userId from authentication
    Controller->>Service: getProductDetail(productId, userId)
    Service->>Repo: findById(productId)
    Repo->>DB: SELECT product
    DB-->>Repo: Product
    Repo-->>Service: Optional<Product>
    
    alt Product Found
        Service->>Service: validateStoreAccess(product, user)
        alt Store Owner
            Service->>Service: Log success
            Service-->>Controller: ProductResponse
            Controller-->>Client: 200 OK + GET_PRODUCT_DETAIL_SUCCESS
        else Store Access Denied
            Service-->>Controller: BaseException(STORE_ACCESS_DENIED)
            Controller-->>Client: 403 Forbidden + Error
        end
    else Product Not Found
        Service-->>Controller: BaseException(PRODUCT_NOT_FOUND)
        Controller-->>Client: 404 Not Found + Error
    end
Loading

코드 리뷰 평가

🎯 3 (Moderate) | ⏱️ ~20분

추가 검토 대상:

  • 스토어 접근 권한 검증의 일관성: validateStoreAccess 헬퍼 메서드로 중복 로직을 제거한 점은 좋습니다. 다만 updateProductgetProductDetail에서 동일한 검증 로직을 사용하므로, 향후 삭제(deleteProduct), 상품 목록 조회 등 다른 엔드포인트에서도 이 헬퍼를 활용할 계획이 있는지 확인하면 좋겠습니다.
  • 에러 메시지 일관성: PRODUCT_NOT_FOUNDSTORE_ACCESS_DENIED 예외가 올바르게 정의되어 있는지, 서비스 계층에서 적절히 던져지는지 확인해주세요.
  • 테스트 커버리지: 성공 케이스, 미존재 상품, 접근 거부 케이스를 모두 테스트한 점은 훌륭합니다. 추가로 로깅 검증이나 성능(대량 데이터) 테스트가 필요한지 고려해보세요.

관련 가능성 있는 PR

Poem

🎁 한 품목의 상세함을 그려내고
✅ 권한 검증으로 안전을 세우며
🧪 테스트 삼 쌍으로 견고함을 다지니,
가지런한 코드로 기능 완성! 🚀

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항을 명확하게 요약하고 있습니다. '품목 상세 조회 기능 구현'은 변경사항의 핵심을 잘 전달합니다.
Description check ✅ Passed PR 설명이 템플릿의 모든 필수 섹션(작업 내용, 적용 범위, 참고 사항)을 포함하고 있으며 관련 이슈 번호도 명시되어 있습니다.
Linked Issues check ✅ Passed Issue #30의 요구사항인 '품목 상세 조회 기능' 구현이 완전하게 달성되었습니다. 컨트롤러, 서비스, 테스트 모두 포함되어 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 Issue #30의 범위 내에 있습니다. 새로운 GET 엔드포인트, 서비스 로직, 검증 헬퍼 메서드, 테스트 모두 상세 조회 기능 구현과 직접 관련이 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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/product-detail

📜 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 435e9e3 and b0ef5b6.

📒 Files selected for processing (5)
  • src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1 hunks)
  • src/main/java/com/almang/inventory/product/controller/ProductController.java (2 hunks)
  • src/main/java/com/almang/inventory/product/service/ProductService.java (3 hunks)
  • src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java (2 hunks)
  • src/test/java/com/almang/inventory/product/service/ProductServiceTest.java (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 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/product/controller/ProductControllerTest.java
  • src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
  • src/main/java/com/almang/inventory/product/service/ProductService.java
  • src/main/java/com/almang/inventory/product/controller/ProductController.java
🔇 Additional comments (13)
src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1)

27-27: 깔끔한 메시지 추가입니다!

기존 패턴과 일관성 있게 품목 상세 조회 성공 메시지가 추가되었습니다.

src/test/java/com/almang/inventory/product/service/ProductServiceTest.java (3)

432-472: 완벽한 테스트 케이스입니다!

품목 상세 조회 성공 케이스를 모든 필드에 대해 검증하고 있으며, 기존의 given-when-then 패턴을 일관성 있게 따르고 있습니다.


474-485: 예외 처리 테스트가 명확합니다.

존재하지 않는 품목에 대한 예외 처리를 적절히 검증하고 있습니다.


487-528: 접근 권한 검증 테스트가 철저합니다!

다른 상점의 품목 접근 시 STORE_ACCESS_DENIED 예외가 발생하는지 제대로 검증하고 있습니다. 멀티 테넌시 환경에서 중요한 보안 테스트입니다.

src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java (4)

10-10: 필요한 import가 추가되었습니다.

GET 요청 테스트를 위한 import가 적절히 추가되었습니다.


386-425: 컨트롤러 레이어 테스트가 탄탄합니다!

인증, 응답 상태 코드, 메시지, 그리고 주요 데이터 필드까지 모두 검증하고 있어 엔드포인트가 올바르게 동작함을 확인할 수 있습니다.


427-445: 404 에러 케이스를 적절히 처리합니다.

존재하지 않는 품목 조회 시 NOT_FOUND 응답을 제대로 검증하고 있습니다.


447-465: 403 접근 제어가 올바르게 테스트되었습니다!

다른 상점의 품목 접근 시 FORBIDDEN 상태와 STORE_ACCESS_DENIED 에러 코드를 정확히 검증하고 있습니다.

src/main/java/com/almang/inventory/product/controller/ProductController.java (2)

17-17: 필요한 import가 추가되었습니다.

GET 매핑 어노테이션이 적절히 import 되었습니다.


65-78: REST API 엔드포인트가 훌륭합니다!

기존의 createProduct, updateProduct와 동일한 패턴을 따르고 있어 일관성이 뛰어납니다:

  • 인증 정보 추출
  • 구조화된 로깅
  • 서비스 계층 위임
  • 표준화된 ApiResponse 반환
  • Swagger 문서화

RESTful 설계 원칙을 잘 따르고 있습니다.

src/main/java/com/almang/inventory/product/service/ProductService.java (3)

44-44: 훌륭한 리팩토링입니다!

인라인 검증 코드를 validateStoreAccess 헬퍼 메서드로 추출하여 코드 재사용성과 가독성을 높였습니다. DRY(Don't Repeat Yourself) 원칙을 잘 따르고 있습니다.


60-68: 품목 상세 조회 메서드가 완벽합니다!

다음과 같은 좋은 관행을 따르고 있습니다:

  • @Transactional(readOnly = true): 읽기 전용 트랜잭션으로 성능 최적화
  • 일관된 검증 순서: User → Product → Store Access
  • 명확한 로깅
  • 기존 코드와 일관성 있는 패턴

Spring의 읽기 전용 트랜잭션에 대해 더 알고 싶다면 Spring 트랜잭션 문서를 참고하세요.


110-114: 접근 권한 검증 로직이 깔끔하게 분리되었습니다!

validateStoreAccess 헬퍼 메서드를 추출하여:

  • updateProduct와 getProductDetail에서 재사용 가능
  • 단일 책임 원칙(SRP) 준수
  • 향후 다른 메서드에서도 활용 가능

이런 식의 공통 로직 추출은 유지보수성을 크게 향상시킵니다. 👍


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

@JoonKyoLee JoonKyoLee merged commit 6594b2e into main Nov 20, 2025
1 check passed
@JoonKyoLee JoonKyoLee deleted the feat/product-detail branch November 21, 2025 03:18
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