Conversation
워크스루상품 코드 체계를 단일 변경사항
시퀀스 다이어그램sequenceDiagram
participant Client
participant RetailController
participant RetailService
participant ExcelParser as Excel Parser
participant ProductRepo as ProductRepository
participant RetailRepo as RetailRepository
participant InventoryRepo as InventoryRepository
participant DB as Database
Client->>RetailController: POST /api/v1/retail/upload (multipart file)
RetailController->>RetailController: 파일 유효성 검증
RetailController->>RetailService: processRetailExcel(file)
RetailService->>ExcelParser: 엑셀 파일 파싱
ExcelParser->>ExcelParser: 헤더 스킵, 데이터 행 추출
ExcelParser-->>RetailService: POS코드, 수량 배열
loop 각 상품 행
RetailService->>ProductRepo: findByPosCode(posCode)
ProductRepo->>DB: SELECT * FROM product
DB-->>ProductRepo: Product 객체
ProductRepo-->>RetailService: Optional<Product>
RetailService->>RetailService: Retail 레코드 생성
RetailService->>InventoryRepo: findByProduct(product)
InventoryRepo->>DB: SELECT * FROM inventory
DB-->>InventoryRepo: Inventory 객체
InventoryRepo-->>RetailService: Optional<Inventory>
RetailService->>RetailService: displayStock 감소 (해당 시)
end
RetailService->>RetailRepo: saveAll(retailList)
RetailRepo->>DB: INSERT INTO retails
DB-->>RetailRepo: 저장 완료
RetailRepo-->>RetailService: 저장됨
RetailService-->>RetailController: 완료
RetailController-->>Client: 200 OK / 4xx/5xx 에러
예상 코드 리뷰 난이도🎯 4 (복잡함) | ⏱️ ~45-60분 중점 검토 영역
관련 이슈
관련 PR
추천 라벨
시
개선 제안1. Product 도메인 마이그레이션 전략 명확화 현재 기존
2. CustomerOrderService의 미구현 재고 감소 로직 // 현재 코드
log.warn("Cafe24 주문[{}]의 상품[{}] 수량[{}]에 대해 재고 차감 로직이 미구현되었습니다.",
customerOrder.getId(), item.getProductName(), item.getQuantity());이 접근은 운영 환경에서 재고 불일치를 야기할 수 있습니다.
3. Excel 파싱의 견고성 강화 RetailService의 // 현재: 셀 값 추출 시 NPE 가능성
String posCode = getStringValue(row.getCell(0)); // null 체크?
BigDecimal quantity = getNumericValue(row.getCell(1));
if (cell == null || cell.getCellType() == CellType.BLANK) {
throw new InvalidExcelFormatException("행 " + rowIndex + ": 필수 셀이 비어있습니다");
}4. 트랜잭션 경계 명시 RetailService의 `@Transactional`
public void processRetailExcel(MultipartFile file) {
// ...
}5. 테스트 커버리지 확대 현재 RetailServiceTest는 성공 경로만 다룹니다. 추가 필요:
칭찬 포인트이 PR은 소매 재고 시스템을 엑셀 기반으로 확장하면서도 기존 코드 패턴을 잘 따릅니다. 특히 Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/almang/inventory/customerorder/service/CustomerOrderService.java (1)
98-98: 디버그 아티팩트 제거가 필요합니다.
F_TEST주석은 디버그/테스트 목적으로 남겨진 것으로 보입니다. 코드 정리를 위해 제거하세요.- // 추가적인 고객 주문 관련 비즈니스 로직은 여기에 구현될 수 있습니다. F_TEST + // 추가적인 고객 주문 관련 비즈니스 로직은 여기에 구현될 수 있습니다.
🧹 Nitpick comments (10)
src/main/java/com/almang/inventory/customerorder/service/CustomerOrderService.java (1)
63-75: 미완성 재고 로직에 대한 추적이 필요합니다.주석 처리된 코드와 TODO 플레이스홀더는 재고 감소 로직이 아직 구현되지 않았음을 명확히 보여줍니다. 이 부분이 프로덕션 배포 전에 완료되어야 하는지 확인하세요.
이 TODO를 추적하기 위한 이슈를 생성해 드릴까요?
src/main/java/com/almang/inventory/retail/service/RetailService.java (4)
39-41: 비효율적인 상점 조회 방식 개선이 필요합니다.
storeRepository.findAll()은 모든 상점을 메모리에 로드한 후 첫 번째만 사용합니다. 상점이 많아지면 성능 문제가 발생할 수 있습니다.
StoreRepository에findFirst()또는 페이징을 사용하는 메서드를 추가하세요:// StoreRepository에 추가 Optional<Store> findFirstBy();- Store store = storeRepository.findAll().stream().findFirst() + Store store = storeRepository.findFirstBy() .orElseThrow(() -> new BaseException(ErrorCode.STORE_NOT_FOUND));
43-44: 파일 유효성 검증이 필요합니다.Excel 파일 처리 전에 파일 확장자와 크기를 검증하면 잘못된 파일 업로드로 인한 오류를 조기에 방지할 수 있습니다. 또한, 악의적인 대용량 파일 업로드로 인한 DoS 공격을 방지할 수 있습니다.
// processRetailExcel 메서드 시작 부분에 추가 private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB // 파일 검증 추가 if (file.isEmpty()) { throw new BaseException(ErrorCode.INVALID_FILE, "파일이 비어있습니다."); } if (file.getSize() > MAX_FILE_SIZE) { throw new BaseException(ErrorCode.FILE_TOO_LARGE, "파일 크기가 10MB를 초과합니다."); } String filename = file.getOriginalFilename(); if (filename == null || !filename.toLowerCase().endsWith(".xlsx")) { throw new BaseException(ErrorCode.INVALID_FILE_FORMAT, "xlsx 파일만 지원합니다."); }
91-94: 예외 처리 개선이 필요합니다.
RuntimeException으로 감싸면 원본 예외의 컨텍스트가 손실될 수 있습니다. 커스텀 예외를 사용하면 API 응답에서 더 명확한 에러 메시지를 제공할 수 있습니다.} catch (IOException e) { log.error("Failed to parse Excel file", e); - throw new RuntimeException("Failed to parse Excel file", e); + throw new BaseException(ErrorCode.EXCEL_PARSE_ERROR, "Excel 파일 파싱 실패: " + e.getMessage()); }
ErrorCode에EXCEL_PARSE_ERROR를 추가해야 합니다.
103-107: 숫자 변환 시 정밀도 손실 가능성.
(long) cell.getNumericCellValue()는 큰 숫자나 소수점이 있는 값에서 정밀도가 손실될 수 있습니다. POS 코드가 긴 숫자 문자열인 경우 문제가 될 수 있습니다.} else if (cell.getCellType() == CellType.NUMERIC) { - return String.valueOf((long) cell.getNumericCellValue()); + // 정밀도 유지를 위해 BigDecimal 사용 + return BigDecimal.valueOf(cell.getNumericCellValue()).toPlainString(); } else {src/main/java/com/almang/inventory/retail/domain/Retail.java (1)
12-42: 엔티티 구조가 깔끔합니다! 👍기존 프로젝트 패턴(BaseTimeEntity 상속, Lombok 활용, LAZY fetch)을 잘 따르고 있습니다.
updateQuantity메서드는 서비스 레이어에서 검증 후 호출되므로 null 체크가 필요 없습니다(기존 학습 내용 기반).선택적 개선 사항으로, JPA 엔티티에서
Set이나Map컬렉션 사용 시 예기치 않은 동작을 방지하기 위해equals/hashCode재정의를 고려해 보세요. Hibernate 공식 문서 참고.src/test/java/com/almang/inventory/retail/service/RetailServiceTest.java (2)
53-109: 테스트 커버리지 확장을 권장합니다.현재 성공 케이스만 테스트되어 있습니다. 다음 시나리오에 대한 테스트 추가를 고려해 주세요:
- 상품 코드가 존재하지 않는 경우
- 재고가 존재하지 않는 경우
- 잘못된 파일 형식 (예: CSV)
- 빈 데이터 행
또한 저장된
Retail엔티티의 실제 값 검증과 재고 차감 로직 검증이 누락되어 있습니다:// ArgumentCaptor를 활용한 저장 값 검증 예시 ArgumentCaptor<List<Retail>> captor = ArgumentCaptor.forClass(List.class); verify(retailRepository).saveAll(captor.capture()); List<Retail> savedRetails = captor.getValue(); assertThat(savedRetails).hasSize(1); assertThat(savedRetails.get(0).getQuantity()).isEqualByComparingTo(BigDecimal.valueOf(10));
70-92: 리소스 관리 개선을 위해 try-with-resources 사용을 고려하세요.테스트 코드에서도 리소스 누수 방지는 좋은 습관입니다.
- Workbook workbook = new XSSFWorkbook(); - Sheet sheet = workbook.createSheet("Sheet1"); - // ... header and data setup ... - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - workbook.write(bos); - workbook.close(); + byte[] excelBytes; + try (Workbook workbook = new XSSFWorkbook(); + ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + Sheet sheet = workbook.createSheet("Sheet1"); + // ... header and data setup ... + workbook.write(bos); + excelBytes = bos.toByteArray(); + }src/main/java/com/almang/inventory/product/dto/response/ProductResponse.java (2)
7-21: ProductResponse 레코드 필드 구조 변경 – API 스키마 영향 점검 제안
code→cafe24Code,posCode분리는 도메인과 외부 시스템을 명확히 나눠줘서 방향성은 좋습니다. 다만 public DTO 시그니처가 바뀌었기 때문에, 기존에code필드를 파싱하던 클라이언트(프론트, 외부 연동, 엑셀 템플릿 등)가 있다면 바로 깨질 수 있습니다.
- 원인: 응답 스키마가 완전히 교체되었는데, 하위 호환 계층(예: deprecated 필드, v2 엔드포인트)이 없이 바로 교체되는 형태입니다.
- 개선 방법:
- 이미 모든 소비자가 이 변경을 따라가도록 동기화되었다면 문제 없지만, 아니라면
- 일정 기간 동안
code를 남겨두고 @deprecated, @Schema(description = "... will be removed") 등으로 마이그레이션 기간을 두거나,- 최소한 API 문서/엑셀 포맷 스펙에 “code → cafe24Code/posCode로 분리됨”을 명시해 주는 것을 권장합니다.
cafe24Code,posCode가 선택 입력이라면, null 허용 여부를 도메인(@column(nullable = ...))과 DTO 문서(Swagger @Schema(required = ...))에서 명시해 두면 이후 유지보수 시 혼동이 줄어듭니다.참고로 이런 응답 DTO 변경은 일반적으로 “API 버전업 또는 명시적인 스키마 변경 공지”와 함께 가는 것이 REST API 베스트 프랙티스로 많이 소개됩니다.
22-38: from(Product) 매핑 – 필드 정합성 OK, 매퍼 추출 고려
from(Product)내부에서 새 필드들(cafe24Code,posCode,unitPerBox,unitWeightG,costPrice)을 record 파라미터 순서에 맞게 잘 매핑해 두셨습니다. 응답 필드와 도메인 필드 간 대응 관계가 직관적이라 읽기 좋네요.다만 비슷한
Product → DTO매핑(예:InventoryResponse, 다른 Product 관련 응답)이 점점 늘어날 가능성이 있어 보이므로, 다음을 한 번 고민해볼 만합니다.
- 원인: 매핑 로직이 각 DTO의
from(...)정적 메서드로 흩어지면, 필드가 추가/변경될 때마다 여러 곳을 동시에 수정해야 하고, 일부 DTO에서 누락/불일치가 발생할 수 있습니다.- 개선 방법:
ProductMapper같은 전용 매퍼 클래스를 두거나, MapStruct 등 매핑 라이브러리를 도입해서Product→ 여러 Response DTO 매핑을 한곳에서 관리하는 패턴을 고려해볼 수 있습니다.- 특히 가격/단위 관련 필드는 다른 응답 객체에서도 재사용될 여지가 크므로, 공통 변환 로직을 한 곳으로 모아두면 테스트와 검증이 쉬워집니다.
추가로
product.getVendor().getId()접근은 기존 학습 내용상 Service 단에서 vendor를 검증하고 컬럼도 nullable=false라 현재 형태로도 괜찮아 보입니다 (Based on learnings, ...).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
sample_retail.xlsxis excluded by!**/*.xlsx
📒 Files selected for processing (19)
build.gradle(1 hunks)generate_sample_excel.py(1 hunks)src/main/java/com/almang/inventory/customerorder/service/CustomerOrderService.java(3 hunks)src/main/java/com/almang/inventory/inventory/dto/response/InventoryResponse.java(1 hunks)src/main/java/com/almang/inventory/product/domain/Product.java(2 hunks)src/main/java/com/almang/inventory/product/dto/request/CreateProductRequest.java(1 hunks)src/main/java/com/almang/inventory/product/dto/request/UpdateProductRequest.java(1 hunks)src/main/java/com/almang/inventory/product/dto/response/ProductResponse.java(3 hunks)src/main/java/com/almang/inventory/product/repository/ProductRepository.java(1 hunks)src/main/java/com/almang/inventory/product/service/ProductService.java(6 hunks)src/main/java/com/almang/inventory/retail/controller/RetailController.java(1 hunks)src/main/java/com/almang/inventory/retail/domain/Retail.java(1 hunks)src/main/java/com/almang/inventory/retail/repository/RetailRepository.java(1 hunks)src/main/java/com/almang/inventory/retail/service/RetailService.java(1 hunks)src/test/java/com/almang/inventory/inventory/controller/InventoryControllerTest.java(1 hunks)src/test/java/com/almang/inventory/inventory/service/InventoryServiceTest.java(1 hunks)src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java(1 hunks)src/test/java/com/almang/inventory/product/service/ProductServiceTest.java(1 hunks)src/test/java/com/almang/inventory/retail/service/RetailServiceTest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-20T10:43:47.502Z
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.502Z
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/inventory/service/InventoryServiceTest.javasrc/main/java/com/almang/inventory/retail/domain/Retail.javasrc/main/java/com/almang/inventory/product/domain/Product.javasrc/main/java/com/almang/inventory/product/repository/ProductRepository.javasrc/main/java/com/almang/inventory/product/service/ProductService.javasrc/main/java/com/almang/inventory/product/dto/request/UpdateProductRequest.javasrc/test/java/com/almang/inventory/product/service/ProductServiceTest.javasrc/main/java/com/almang/inventory/customerorder/service/CustomerOrderService.javasrc/test/java/com/almang/inventory/product/controller/ProductControllerTest.javasrc/main/java/com/almang/inventory/product/dto/response/ProductResponse.java
📚 Learning: 2025-11-22T18:12:13.172Z
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.172Z
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/inventory/service/InventoryServiceTest.javasrc/main/java/com/almang/inventory/retail/domain/Retail.javasrc/main/java/com/almang/inventory/product/domain/Product.javasrc/main/java/com/almang/inventory/product/repository/ProductRepository.javasrc/main/java/com/almang/inventory/product/service/ProductService.javasrc/test/java/com/almang/inventory/inventory/controller/InventoryControllerTest.javasrc/main/java/com/almang/inventory/product/dto/request/UpdateProductRequest.javasrc/test/java/com/almang/inventory/product/service/ProductServiceTest.javasrc/main/java/com/almang/inventory/customerorder/service/CustomerOrderService.java
🔇 Additional comments (21)
src/main/java/com/almang/inventory/customerorder/service/CustomerOrderService.java (1)
57-60: cafe24Code 기반 상품 조회로 변경 - 좋습니다! 👍
findByCode에서findByCafe24Code로 변경한 것은 새로운 코드 모델과 일치합니다.src/main/java/com/almang/inventory/retail/repository/RetailRepository.java (1)
1-7: 깔끔한 Repository 구현입니다.JPA Repository 패턴을 따르고 있으며, 현재 요구사항에 충분합니다. 향후 조회 기능이 필요하면
findByProductAndStore,findByAppliedAtBetween등의 쿼리 메서드를 추가할 수 있습니다.src/main/java/com/almang/inventory/retail/service/RetailService.java (2)
69-71: 상품 미발견 시 전체 트랜잭션 실패 - 의도된 동작인지 확인 필요.현재 구현에서는 하나의 POS 코드라도 찾지 못하면 전체 Excel 처리가 실패합니다. 부분 성공을 허용할지, 아니면 전체 실패(all-or-nothing)가 비즈니스 요구사항인지 확인하세요.
부분 성공을 허용한다면 다음과 같이 에러를 수집하고 로깅하는 방식을 고려하세요:
List<String> notFoundCodes = new ArrayList<>(); // ... Product product = productRepository.findByPosCode(posCode).orElse(null); if (product == null) { notFoundCodes.add(posCode); log.warn("POS code not found, skipping: {}", posCode); continue; } // 처리 후 notFoundCodes가 있으면 경고 또는 응답에 포함
82-85: 재고 감소 로직의 트랜잭션 일관성 검토 필요.루프 내에서
inventory.decreaseDisplay(quantity)가 호출되지만,Retail엔티티들은 루프 종료 후saveAll()로 저장됩니다. 현재@Transactional이 적용되어 있어 전체가 하나의 트랜잭션으로 처리되지만,saveAll()이전에 예외가 발생하면 재고는 이미 감소된 상태가 될 수 있습니다.JPA의 dirty checking으로 인해 트랜잭션 커밋 시점에 모든 변경이 함께 반영되므로 큰 문제는 아니지만, 명시적인 순서 보장을 위해 확인이 필요합니다.
공식 문서 참고: Spring Data JPA 트랜잭션 관리 (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions)
src/main/java/com/almang/inventory/product/dto/request/CreateProductRequest.java (1)
10-22: API 변경사항이 잘 반영되었습니다.
code필드를cafe24Code와posCode로 분리한 것은 각 채널별 코드 관리를 명확하게 합니다.@NotBlank검증으로 필수값 처리도 적절합니다.이 변경은 Breaking Change입니다. API를 사용하는 클라이언트(프론트엔드, 외부 시스템)에 변경사항을 공지했는지 확인하세요.
src/main/java/com/almang/inventory/product/service/ProductService.java (2)
63-63: updateBasicInfo 호출이 새로운 시그니처와 일치합니다.
cafe24Code와posCode를 전달하도록 업데이트되었습니다. 기존 learnings에 따르면 서비스에서 검증 후 엔티티 메서드를 호출하므로 추가 null 체크가 불필요합니다.
112-131: Product 엔티티 생성 로직이 새로운 필드 구조를 반영합니다.
toEntity메서드가cafe24Code와posCode를 사용하여 Product를 생성하도록 업데이트되었습니다. 빌더 패턴을 사용한 깔끔한 구현입니다.src/test/java/com/almang/inventory/inventory/service/InventoryServiceTest.java (2)
83-100:newProduct헬퍼 업데이트가 적절합니다.
cafe24Code와posCode필드 추가에 맞춰 테스트 데이터 생성이 잘 업데이트되었습니다."C-" + code패턴으로 cafe24Code를 생성하여 두 코드 간 구분이 명확합니다.
137-138: 새 필드에 대한 assertion 추가 완료!
cafe24Code()와posCode()검증이 적절히 추가되었습니다.src/main/java/com/almang/inventory/inventory/dto/response/InventoryResponse.java (2)
11-12:cafe24Code와posCode분리가 적절합니다.단일
productCode에서 두 개의 명시적 필드로 분리하여 각 코드의 용도가 명확해졌습니다. 이는 PR 목적(okpos code 및 cafe24상품코드 관리)과 일치합니다.
7-32: No action needed:cafe24CodeandposCodefields are properly implemented and tested.The commit "split pos code and cafe24 code" intentionally refactored the Product domain to distinguish between Cafe24 and POS system codes. The
InventoryResponsewas never using a combinedproductCodefield—it currently exposes bothcafe24CodeandposCodeas separate fields, which is the intended design. Tests throughout the codebase (InventoryControllerTest, InventoryServiceTest) already validate this structure and pass.src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java (3)
45-61: LGTM! 테스트 설정이 깔끔하게 구성되었습니다.
@Autowired와@MockitoBean어노테이션을 활용한 DI 구성이 명확하고, 인증 헬퍼 메서드도 재사용 가능하게 잘 분리되어 있습니다. 👍
63-114: LGTM! cafe24Code와 posCode 필드가 올바르게 테스트되고 있습니다.새로운 필드들에 대한 요청/응답 검증이 잘 구현되어 있습니다. 품목 등록 성공 시나리오가 완전하게 커버되어 있네요.
331-364: LGTM! 다른 상점 발주처 접근 제한 테스트가 잘 구현되었습니다.권한 검증 로직에 대한 테스트가 명확하게 작성되어 있습니다.
ErrorCode.VENDOR_ACCESS_DENIED검증도 적절합니다.src/test/java/com/almang/inventory/product/service/ProductServiceTest.java (2)
38-49: LGTM! 테스트 의존성 주입이 잘 구성되었습니다.통합 테스트에 필요한 Repository들이 명확하게 주입되어 있습니다.
83-132: LGTM! 품목 생성 성공 테스트가 완벽하게 구현되었습니다.
cafe24Code와posCode검증, 그리고 연관된Inventory자동 생성 검증까지 꼼꼼하게 테스트하고 있네요. 훌륭합니다! 🎉src/test/java/com/almang/inventory/inventory/controller/InventoryControllerTest.java (4)
47-63: LGTM! 테스트 설정이 잘 구성되어 있습니다.의존성 주입과 인증 헬퍼가 명확하게 분리되어 있습니다.
79-89: LGTM!InventoryResponse에cafe24Code와posCode가 올바르게 추가되었습니다.새로운 필드들이 응답 객체에 정확히 포함되어 있고, 테스트에서도 이를 검증하고 있습니다.
339-385: LGTM! 상점 재고 목록 조회 테스트가 새 필드들을 잘 검증하고 있습니다.
$.data.content[0].cafe24Code와$.data.content[0].posCode검증이 포함되어 API 응답 구조 변경이 올바르게 반영되었습니다.
387-427: LGTM! 재고 이동 테스트에서 새 필드 검증이 완벽합니다.
productName,cafe24Code,posCode모두 검증되고 있어 응답 데이터 무결성이 보장됩니다. 👍src/main/java/com/almang/inventory/product/domain/Product.java (1)
79-92: LGTM!updateBasicInfo메서드가 새 필드들을 잘 처리합니다.부분 업데이트 패턴이 일관되게 적용되어 있습니다. 기존 learnings에서 확인된 바와 같이 ProductService에서 검증 후 호출되므로 null 체크 로직이 적절합니다. Based on learnings, 서비스 레이어에서 사전 검증이 이루어집니다.
| // Excel (Apache POI) | ||
| implementation 'org.apache.poi:poi-ooxml:5.2.3' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
curl -s "https://search.maven.org/solrsearch/select?q=g:org.apache.poi+AND+a:poi-ooxml&rows=10&wt=json" | jq -r '.response.docs[] | "\(.v)"' | head -20Repository: almang2/inventory-server
Length of output: 72
🌐 Web query:
Apache POI poi-ooxml 5.2.3 security vulnerabilities CVE
💡 Result:
Yes — poi-ooxml 5.2.3 is vulnerable to CVE-2025-31672 (Improper Input Validation: OOXML ZIP entries with duplicate names). The issue affects all poi-ooxml versions < 5.4.0; upgrade to >= 5.4.0 to fix it. [1][2][3]
Sources:
- NVD entry for CVE-2025-31672. [1]
- GitHub Advisory (Apache POI poi-ooxml < 5.4.0). [2]
- Snyk vulnerability page / package details. [3]
🌐 Web query:
Apache POI latest version 2024 2025
💡 Result:
Latest Apache POI releases (relevant to 2024–2025):
- 5.3.0 — released 2024-07-02. [1]
- 5.4.0 — released 2025-01-08. [1]
- 5.4.1 — released 2025-04-06. [1]
- 5.5.0 — released 2025-11-15 (latest stable). [2][1]
Sources: Apache POI changelog and download page. [1] https://poi.apache.org/changes.html [2] https://poi.apache.org/download.cgi
Upgrade Apache POI to patch CVE-2025-31672.
poi-ooxml:5.2.3 is vulnerable to CVE-2025-31672 (improper input validation in OOXML ZIP entries with duplicate names). This affects all versions below 5.4.0. Upgrade to at least 5.4.0 (or 5.5.0, the current latest stable release).
🤖 Prompt for AI Agents
In build.gradle around lines 54-55 the Apache POI dependency is pinned to
vulnerable version 'org.apache.poi:poi-ooxml:5.2.3'; update the dependency
version to at least 5.4.0 (preferably 5.5.0) to address CVE-2025-31672 by
replacing the version string with 'org.apache.poi:poi-ooxml:5.5.0' (or '5.4.0'
if you prefer), then run a Gradle refresh/resolve to ensure the updated artifact
is fetched and the build still passes.
| data = { | ||
| 'Product Code': ['P00000LM000D', 'P00000WA000B', 'P00000IP000A'], | ||
| 'Quantity': [10, 5, 20], | ||
| 'Applied At': ['2023-12-01 10:00:00', '2023-12-01 11:00:00', ''] | ||
| } |
There was a problem hiding this comment.
샘플 데이터 컬럼 위치가 RetailService와 일치하지 않습니다.
RetailService에서는 Cell 1(인덱스 1)에서 POS 코드를, Cell 3(인덱스 3)에서 수량을 읽습니다. 현재 샘플 데이터는 인덱스 0, 1, 2에 데이터를 배치하므로 실제 업로드 시 파싱 오류가 발생할 수 있습니다.
다음과 같이 수정하여 컬럼 위치를 맞추세요:
data = {
- 'Product Code': ['P00000LM000D', 'P00000WA000B', 'P00000IP000A'],
- 'Quantity': [10, 5, 20],
- 'Applied At': ['2023-12-01 10:00:00', '2023-12-01 11:00:00', '']
+ 'Empty': ['', '', ''], # Cell 0
+ 'POS Code': ['P00000LM000D', 'P00000WA000B', 'P00000IP000A'], # Cell 1
+ 'Empty2': ['', '', ''], # Cell 2
+ 'Quantity': [10, 5, 20], # Cell 3
+ 'Applied At': ['2023-12-01 10:00:00', '2023-12-01 11:00:00', ''] # Cell 4 (미사용)
}🤖 Prompt for AI Agents
In generate_sample_excel.py around lines 4 to 8, the sample data columns are
currently at indices 0,1,2 but RetailService expects the POS code at index 1 and
quantity at index 3; modify the data dict so there are placeholder columns to
align positions (e.g., add a first-column placeholder and a third-column
placeholder) and place 'Product Code' at index 1 and 'Quantity' at index 3 (keep
'Applied At' after those), ensuring each row has the same number of entries so
exported Excel columns match RetailService's expected cell indices.
| @Column(name = "name", length = 255, nullable = false) | ||
| private String name; | ||
|
|
||
| @Column(name = "code", length = 30, nullable = false) | ||
| private String code; | ||
| @Column(name = "cafe24_code", length = 50, nullable = false) | ||
| private String cafe24Code; | ||
|
|
||
| @Column(name = "pos_code", length = 50, nullable = false) | ||
| private String posCode; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n src/main/java/com/almang/inventory/product/domain/Product.java | head -100Repository: almang2/inventory-server
Length of output: 3638
🏁 Script executed:
# Search for migration files and flyway/liquibase configuration
find . -type f \( -name "*.sql" -o -name "*.yaml" -o -name "*.yml" -o -name "application*.properties" \) | grep -E "(migration|db|flyway|liquibase)" | head -20Repository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Check for migration directories
find . -type d \( -name "migration*" -o -name "db" -o -name "flyway" -o -name "liquibase" \) 2>/dev/nullRepository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Search for cafe24_code or pos_code references in SQL or migration files
rg -i "cafe24|pos_code" --type sql --type yaml -l 2>/dev/null || echo "No matches found"Repository: almang2/inventory-server
Length of output: 94
🏁 Script executed:
cat docs/rds_create_tables.sql | grep -A 5 -B 5 "cafe24\|pos_code"Repository: almang2/inventory-server
Length of output: 980
🏁 Script executed:
# Search for Flyway or Liquibase migration directories
find . -type d -name "db" -o -name "migration" 2>/dev/null | head -10Repository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Check for migration files in common locations
find . -path "*/db/migration*" -o -path "*/flyway*" -o -path "*/liquibase*" 2>/dev/null | head -20Repository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Look at the structure of migration/db directories if they exist
ls -la src/main/resources/ 2>/dev/null | grep -E "db|migration|flyway"Repository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
cat docs/rds_create_tables.sql | grep -n "CREATE TABLE.*products"Repository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
cat docs/rds_create_tables.sqlRepository: almang2/inventory-server
Length of output: 2017
🏁 Script executed:
# Search for any mention of cafe24_code or pos_code in the entire codebase
rg "cafe24_code|pos_code" --type sqlRepository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Search for products table definition anywhere in codebase
rg "CREATE TABLE.*products" --type sqlRepository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Find all SQL files
fd -e sqlRepository: almang2/inventory-server
Length of output: 94
🏁 Script executed:
# Search for any SQL files or migration-related files
find . -type f \( -name "*.sql" -o -name "*.ddl" \) 2>/dev/nullRepository: almang2/inventory-server
Length of output: 96
🏁 Script executed:
# Check if there's an existing products table schema somewhere else
rg "products" -t sqlRepository: almang2/inventory-server
Length of output: 175
🏁 Script executed:
# Look for any schema or DDL comments in Java files
rg "cafe24_code|pos_code" -A 3 -B 3Repository: almang2/inventory-server
Length of output: 1003
Database migration script required for cafe24_code and pos_code columns.
The new cafe24Code and posCode fields are marked nullable = false in the entity, but no corresponding database migration script exists in the codebase. The docs/rds_create_tables.sql file does not contain definitions for these columns on the products table.
Before merging, create a database migration script that:
- Adds
cafe24_code(VARCHAR(50), NOT NULL) column - Adds
pos_code(VARCHAR(50), NOT NULL) column - Provides default values or migration strategy for existing product records
Without this migration, the application will fail when Hibernate attempts to persist or update products.
| public record UpdateProductRequest( | ||
| @NotNull Long vendorId, | ||
| String name, | ||
| String code, | ||
| ProductUnit unit, | ||
| BigDecimal boxWeightG, | ||
| @Positive Integer unitPerBox, | ||
| BigDecimal unitWeightG, | ||
| Boolean isActivated, | ||
| @Min(0) Integer costPrice, | ||
| @Min(0) Integer retailPrice, | ||
| @Min(0) Integer wholesalePrice | ||
| ) {} | ||
| @NotNull Long vendorId, | ||
| String name, | ||
| String cafe24Code, | ||
| String posCode, | ||
| ProductUnit unit, | ||
| BigDecimal boxWeightG, | ||
| @Positive Integer unitPerBox, | ||
| BigDecimal unitWeightG, | ||
| Boolean isActivated, | ||
| @Min(0) Integer costPrice, | ||
| @Min(0) Integer retailPrice, | ||
| @Min(0) Integer wholesalePrice) { | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find and examine CreateProductRequest
echo "=== CreateProductRequest.java ==="
fd -t f "CreateProductRequest.java" --exec cat {}
# Find the test file and relevant test method
echo "=== ProductControllerTest - validation test ==="
fd -t f "ProductControllerTest.java" --exec wc -l {} \;Repository: almang2/inventory-server
Length of output: 1069
🏁 Script executed:
#!/bin/bash
# Search for the specific test mentioned in the review (line 369-381 or 178-204)
echo "=== Test method searching for empty string validation ==="
rg -n -B 2 -A 15 "empty|Empty|빈.*문자" src/test/java/com/almang/inventory/product/controller/ --type java | head -100Repository: almang2/inventory-server
Length of output: 125
🏁 Script executed:
#!/bin/bash
# Check UpdateProductRequest current validation state more thoroughly
echo "=== Full UpdateProductRequest.java ==="
fd -t f "UpdateProductRequest.java" --exec cat {}Repository: almang2/inventory-server
Length of output: 889
🏁 Script executed:
#!/bin/bash
# Find test methods in ProductControllerTest that test update product validation
echo "=== Test methods for update product ==="
rg -n "void.*update|updateProduct|PUT|patch" src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java -A 3
# Also search for test assertions with invalid input or validation
echo "=== Test validation assertions ==="
rg -n "INVALID_INPUT_VALUE|BindException|valid" src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java | head -30Repository: almang2/inventory-server
Length of output: 4505
🏁 Script executed:
#!/bin/bash
# Read the test file to check for update-related tests
echo "=== ProductControllerTest content (lines 350-400) ==="
sed -n '350,400p' src/test/java/com/almang/inventory/product/controller/ProductControllerTest.java
echo "=== ProductControllerTest content (lines 1-50) to find test class structure ==="
head -50 src/test/java/com/almang/inventory/product/controller/ProductControllerTest.javaRepository: almang2/inventory-server
Length of output: 5370
UpdateProductRequest의 검증 어노테이션 누락 확인됨. name, cafe24Code, posCode 필드에 @NotBlank 추가 필요.
CreateProductRequest에는 이 세 필드에 @NotBlank 어노테이션이 있지만, UpdateProductRequest에는 누락되어 있습니다. 현재 테스트 "품목_수정_요청값_검증에_실패하면_예외가_발생한다()"(line 367-394)는 vendorId의 @NotNull 위반과 가격 필드의 @Min(0) 위반으로 인해 통과하고 있지만, 빈 문자열 값들은 검증되지 않고 있습니다.
일관성 유지와 입력값 검증을 위해 name, cafe24Code, posCode에 @NotBlank 어노테이션을 추가해주세요.
🤖 Prompt for AI Agents
In
src/main/java/com/almang/inventory/product/dto/request/UpdateProductRequest.java
around lines 9 to 22, add @NotBlank to the parameters name, cafe24Code, and
posCode so they are validated like in CreateProductRequest; update imports to
include javax.validation.constraints.NotBlank if not already present, rebuild to
ensure the existing validation test now also fails on blank strings and adjust
any tests if necessary.
| // 상품 코드로 상품 찾기 (카페24 주문 처리용) | ||
| Optional<Product> findByCafe24Code(String cafe24Code); | ||
|
|
||
| // POS 코드로 상품 찾기 (소매 판매 엑셀 업로드용) | ||
| Optional<Product> findByPosCode(String posCode); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and examine ProductRepository.java
find . -type f -name "ProductRepository.java" | head -5Repository: almang2/inventory-server
Length of output: 146
🏁 Script executed:
# Find and examine Product entity class
find . -type f -name "Product.java" | grep -E "entity|model" | head -5Repository: almang2/inventory-server
Length of output: 50
🏁 Script executed:
# Search for cafe24Code and posCode field definitions
rg -n "cafe24Code|posCode" --type java -B2 -A2Repository: almang2/inventory-server
Length of output: 24586
🏁 Script executed:
# Read the full Product entity class to check for unique constraints
cat -n src/main/java/com/almang/inventory/product/domain/Product.java | head -70Repository: almang2/inventory-server
Length of output: 2557
Add unique constraints on cafe24Code and posCode fields in Product entity
The cafe24Code and posCode fields are currently missing unique constraints but are used as lookup keys in findByCafe24Code() and findByPosCode() queries. Without these constraints, duplicate codes could exist in the database, causing these repository methods to silently return only the first match. This creates a data integrity risk in order processing workflows (Cafe24 orders and retail Excel uploads).
Add unique = true to both @column annotations in the Product entity, or use @table(uniqueConstraints = {...}) if store-scoped uniqueness is required.
🤖 Prompt for AI Agents
In src/main/java/com/almang/inventory/product/repository/ProductRepository.java
around lines 28 to 32, the repository methods findByCafe24Code and findByPosCode
rely on fields that lack database uniqueness, risking duplicate entries and
ambiguous lookups; update the Product entity to enforce uniqueness by adding
unique = true to the @Column for cafe24Code and posCode, or if uniqueness must
be scoped (e.g., per store), add a @Table(uniqueConstraints =
{@UniqueConstraint(columnNames = {"store_id","cafe24_code"}),
@UniqueConstraint(columnNames = {"store_id","pos_code"})}) and adjust column
names accordingly so the database enforces the constraint.
| // 고무장갑 비활성 처리 | ||
| productService.updateProduct( | ||
| willBeInactive.productId(), | ||
| new UpdateProductRequest( | ||
| vendor.getId(), | ||
| willBeInactive.name(), | ||
| willBeInactive.code(), | ||
| willBeInactive.unit(), | ||
| willBeInactive.boxWeightG(), | ||
| willBeInactive.unitPerBox(), | ||
| willBeInactive.unitWeightG(), | ||
| false, | ||
| willBeInactive.costPrice(), | ||
| willBeInactive.retailPrice(), | ||
| willBeInactive.wholesalePrice()), | ||
| user.getId()); |
There was a problem hiding this comment.
컴파일 에러: ProductResponse.code() 메서드가 존재하지 않습니다.
ProductResponse에서 code 필드가 cafe24Code와 posCode로 분리되었으므로, .code() 호출은 컴파일 에러를 발생시킵니다. cafe24Code()와 posCode()를 사용해야 합니다.
productService.updateProduct(
willBeInactive.productId(),
new UpdateProductRequest(
vendor.getId(),
willBeInactive.name(),
- willBeInactive.code(),
+ willBeInactive.cafe24Code(),
+ willBeInactive.posCode(),
willBeInactive.unit(),
willBeInactive.boxWeightG(),
willBeInactive.unitPerBox(),
willBeInactive.unitWeightG(),
false,
willBeInactive.costPrice(),
willBeInactive.retailPrice(),
willBeInactive.wholesalePrice()),
user.getId());참고: DTO 필드 변경 시 IDE의 "Rename" 리팩토링 기능을 활용하면 누락을 방지할 수 있습니다.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
around lines 921-936, the test calls willBeInactive.code() which no longer
exists because ProductResponse split the code field into cafe24Code and posCode;
update the UpdateProductRequest construction to pass willBeInactive.cafe24Code()
and willBeInactive.posCode() in place of the old .code() argument(s) so the
request matches the new DTO fields (adjust argument order to match
UpdateProductRequest's new signature).
| // 활성 + 이름 매칭 | ||
| productService.createProduct( | ||
| new CreateProductRequest( | ||
| vendor.getId(), | ||
| "고체치약", | ||
| "P-001", | ||
| ProductUnit.G, | ||
| BigDecimal.valueOf(900.0), | ||
| 10, | ||
| BigDecimal.valueOf(90.0), | ||
| 1000, | ||
| 1500, | ||
| 1200), | ||
| user.getId()); | ||
|
|
||
| // 비활성 + 이름 매칭 | ||
| ProductResponse inactiveMatch = productService.createProduct( | ||
| new CreateProductRequest( | ||
| vendor.getId(), | ||
| "고무장갑", | ||
| "P-002", | ||
| ProductUnit.EA, | ||
| null, | ||
| 1, | ||
| null, | ||
| 500, | ||
| 800, | ||
| 600), | ||
| user.getId()); | ||
|
|
||
| // 비활성 + 이름 미매칭 | ||
| ProductResponse inactiveNonMatch = productService.createProduct( | ||
| new CreateProductRequest( | ||
| vendor.getId(), | ||
| "세제", | ||
| "P-003", | ||
| ProductUnit.ML, | ||
| BigDecimal.valueOf(1000.0), | ||
| 5, | ||
| BigDecimal.valueOf(200.0), | ||
| 3000, | ||
| 4000, | ||
| 3500), | ||
| user.getId()); |
There was a problem hiding this comment.
컴파일 에러: 동시 필터링 테스트에서 동일한 문제들이 반복됩니다.
CreateProductRequest에 cafe24Code 누락, 그리고 Lines 1007, 1023에서 .code() 호출 문제가 있습니다.
동일한 패턴의 수정이 필요합니다:
CreateProductRequest생성자에cafe24Code파라미터 추가.code()→.cafe24Code(),.posCode()변경
🤖 Prompt for AI Agents
In src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
around lines 956 to 999, the CreateProductRequest constructions are missing the
new cafe24Code parameter and related accessor calls elsewhere use .code()
instead of the updated .cafe24Code() or .posCode(); update each
CreateProductRequest invocation within this block to supply the cafe24Code
argument in the correct position expected by the constructor, and replace any
.code() calls in this test (and the repeated patterns nearby at lines ~1007 and
~1023) with the appropriate .cafe24Code() or .posCode() accessor so the calls
match the new DTO signature.
| @Test | ||
| void 품목_삭제에_성공한다() { | ||
| // given | ||
| Store store = newStore(); | ||
| Vendor vendor = newVendor(store); | ||
| User user = newUser(store); | ||
|
|
||
| ProductResponse created = productService.createProduct( | ||
| new CreateProductRequest( | ||
| vendor.getId(), | ||
| "고체치약", | ||
| "P-001", | ||
| ProductUnit.G, | ||
| BigDecimal.valueOf(900.0), | ||
| 10, | ||
| BigDecimal.valueOf(90.0), | ||
| 1000, | ||
| 1500, | ||
| 1200), | ||
| user.getId()); |
There was a problem hiding this comment.
컴파일 에러: 삭제 테스트에서 cafe24Code 누락
ProductResponse created = productService.createProduct(
new CreateProductRequest(
vendor.getId(),
"고체치약",
+ "C-001",
"P-001",
ProductUnit.G,
BigDecimal.valueOf(900.0),
10,
BigDecimal.valueOf(90.0),
1000,
1500,
1200),
user.getId());📝 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.
| @Test | |
| void 품목_삭제에_성공한다() { | |
| // given | |
| Store store = newStore(); | |
| Vendor vendor = newVendor(store); | |
| User user = newUser(store); | |
| ProductResponse created = productService.createProduct( | |
| new CreateProductRequest( | |
| vendor.getId(), | |
| "고체치약", | |
| "P-001", | |
| ProductUnit.G, | |
| BigDecimal.valueOf(900.0), | |
| 10, | |
| BigDecimal.valueOf(90.0), | |
| 1000, | |
| 1500, | |
| 1200), | |
| user.getId()); | |
| @Test | |
| void 품목_삭제에_성공한다() { | |
| // given | |
| Store store = newStore(); | |
| Vendor vendor = newVendor(store); | |
| User user = newUser(store); | |
| ProductResponse created = productService.createProduct( | |
| new CreateProductRequest( | |
| vendor.getId(), | |
| "고체치약", | |
| "C-001", | |
| "P-001", | |
| ProductUnit.G, | |
| BigDecimal.valueOf(900.0), | |
| 10, | |
| BigDecimal.valueOf(90.0), | |
| 1000, | |
| 1500, | |
| 1200), | |
| user.getId()); |
🤖 Prompt for AI Agents
In src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
around lines 1046-1065, the call to new CreateProductRequest is missing the
required cafe24Code parameter (causing a compile error); update the constructor
invocation to include a cafe24Code value (e.g., "C-001") in the correct position
(between the product name and productCode) so the argument list matches the
CreateProductRequest signature.
| ProductResponse productOfStore2 = productService.createProduct( | ||
| new CreateProductRequest( | ||
| vendor2.getId(), | ||
| "고체치약", | ||
| "P-001", | ||
| ProductUnit.G, | ||
| BigDecimal.valueOf(900.0), | ||
| 10, | ||
| BigDecimal.valueOf(90.0), | ||
| 1000, | ||
| 1500, | ||
| 1200), | ||
| userOfStore2.getId()); |
There was a problem hiding this comment.
컴파일 에러: 다른 상점 품목 삭제 테스트에서 cafe24Code 누락
ProductResponse productOfStore2 = productService.createProduct(
new CreateProductRequest(
vendor2.getId(),
"고체치약",
+ "C-001",
"P-001",
ProductUnit.G,
BigDecimal.valueOf(900.0),
10,
BigDecimal.valueOf(90.0),
1000,
1500,
1200),
userOfStore2.getId());📝 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.
| ProductResponse productOfStore2 = productService.createProduct( | |
| new CreateProductRequest( | |
| vendor2.getId(), | |
| "고체치약", | |
| "P-001", | |
| ProductUnit.G, | |
| BigDecimal.valueOf(900.0), | |
| 10, | |
| BigDecimal.valueOf(90.0), | |
| 1000, | |
| 1500, | |
| 1200), | |
| userOfStore2.getId()); | |
| ProductResponse productOfStore2 = productService.createProduct( | |
| new CreateProductRequest( | |
| vendor2.getId(), | |
| "고체치약", | |
| "C-001", | |
| "P-001", | |
| ProductUnit.G, | |
| BigDecimal.valueOf(900.0), | |
| 10, | |
| BigDecimal.valueOf(90.0), | |
| 1000, | |
| 1500, | |
| 1200), | |
| userOfStore2.getId()); |
🤖 Prompt for AI Agents
In src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
around lines 1117-1129, the CreateProductRequest instantiation for
productOfStore2 is missing the required cafe24Code parameter which causes a
compilation error; update the constructor call to include a valid cafe24Code
string (e.g., "C-001" or an appropriate test value) in the correct position to
match the CreateProductRequest signature, and adjust any other test
instantiations to the same constructor ordering if necessary.
| @Test | ||
| void 삭제된_품목은_목록_및_상세에서_조회되지_않는다() { | ||
| // given | ||
| Store store = newStore(); | ||
| Vendor vendor = newVendor(store); | ||
| User user = newUser(store); | ||
|
|
||
| ProductResponse product = productService.createProduct( | ||
| new CreateProductRequest( | ||
| vendor.getId(), | ||
| "고체치약", | ||
| "P-001", | ||
| ProductUnit.G, | ||
| BigDecimal.valueOf(900.0), | ||
| 10, | ||
| BigDecimal.valueOf(90.0), | ||
| 1000, | ||
| 1500, | ||
| 1200), | ||
| user.getId()); |
There was a problem hiding this comment.
컴파일 에러: 삭제 후 조회 불가 테스트에서 cafe24Code 누락
ProductResponse product = productService.createProduct(
new CreateProductRequest(
vendor.getId(),
"고체치약",
+ "C-001",
"P-001",
ProductUnit.G,
BigDecimal.valueOf(900.0),
10,
BigDecimal.valueOf(90.0),
1000,
1500,
1200),
user.getId());정리: 총 10개 이상의 테스트에서 동일한 문제가 발생하고 있습니다. 일괄 수정이 필요합니다. 테스트 헬퍼 메서드(예: createDefaultProductRequest(Long vendorId))를 만들어 중복을 줄이는 것을 권장드립니다.
🤖 Prompt for AI Agents
In src/test/java/com/almang/inventory/product/service/ProductServiceTest.java
around lines 1138-1157 the test fails to compile because the
CreateProductRequest used in tests is missing the required cafe24Code argument;
update the test to supply a valid cafe24Code value (e.g. "C24-001") when
constructing CreateProductRequest or add an overloaded constructor/utility
factory used by tests that fills cafe24Code by default; apply the same change
across the other ~10+ test cases and refactor by adding a test helper method
like createDefaultProductRequest(Long vendorId) to centralize defaults including
cafe24Code and reduce duplication.
|
@Youngwave1128 RetailService.java 코드를 살펴보았는데요, 개선했으면 하는 부분이 있어서 코멘트 남깁니다.
실제 사용성에 맞게 가정 하신 부분도 있으실거 같은데요, 제가 맞지 않을수도 있어서 확인해보시고 수정해주시면 좋을 거 같아 코멘트 남깁니다. |
✨ 작업 내용
📝 적용 범위
📌 참고 사항
Summary by CodeRabbit
릴리스 노트
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.