Skip to content

feat: 발주처 목록 조회 기능 구현#43

Merged
JoonKyoLee merged 6 commits intomainfrom
feat/vendor-list
Nov 21, 2025
Merged

feat: 발주처 목록 조회 기능 구현#43
JoonKyoLee merged 6 commits intomainfrom
feat/vendor-list

Conversation

@JoonKyoLee
Copy link
Contributor

@JoonKyoLee JoonKyoLee commented Nov 21, 2025

✨ 작업 내용

  • 발주처 목록 조회 기능 구현

📝 적용 범위

  • /vendor

📌 참고 사항

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 발주처 목록 조회 API 추가: 페이지네이션, 활성화 상태 필터, 이름 검색 기능 지원
    • 발주처 목록 조회 성공 메시지 추가
  • Improvements

    • 표준화된 페이지네이션 처리로 일관된 데이터 조회 환경 구현
  • Tests

    • 발주처 목록 조회 관련 테스트 케이스 추가 (페이지네이션, 필터 적용 등)

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

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

coderabbitai bot commented Nov 21, 2025

개요

발주처 목록 조회 기능을 구현하였으며, 페이지네이션과 필터링(활성화 상태, 이름) 지원을 추가하였습니다. PaginationUtil 유틸리티 클래스를 신규 도입하여 페이지 요청 생성을 표준화하였고, ProductService도 함께 마이그레이션되었습니다.

변경사항

역할군 / 파일 변경 요약
페이지네이션 인프라
src/main/java/com/almang/inventory/global/util/PaginationUtil.java, src/main/java/com/almang/inventory/global/api/SuccessMessage.java
페이지 요청 생성을 표준화하는 새로운 PaginationUtil 유틸리티 클래스 추가 (기본값: page=1일 때 0-based index, size=20). GET_VENDOR_LIST_SUCCESS 성공 메시지 상수 추가
발주처 기능
src/main/java/com/almang/inventory/vendor/controller/VendorController.java
발주처 목록 조회 엔드포인트 추가: GET /api/v1/vendor (페이지, 크기, 활성화 필터, 이름 검색 파라미터 지원)
src/main/java/com/almang/inventory/vendor/repository/VendorRepository.java
src/main/java/com/almang/inventory/vendor/service/VendorService.java
상품 기능 리팩토링
src/main/java/com/almang/inventory/product/service/ProductService.java
로컬 createPageRequest 헬퍼 메서드 제거, PaginationUtil.createPageRequest 사용으로 통일
테스트
src/test/java/com/almang/inventory/vendor/controller/VendorControllerTest.java, src/test/java/com/almang/inventory/vendor/service/VendorServiceTest.java
발주처 목록 조회, 활성화 필터, 이름 검색 필터 등 다양한 시나리오의 단위 테스트 추가

시퀀스 다이어그램

sequenceDiagram
    participant Client
    participant VendorController
    participant VendorService
    participant VendorRepository
    participant Database
    
    Client->>VendorController: GET /api/v1/vendor?page=1&size=20&isActivate=true&name=keyword
    VendorController->>VendorService: getVendorList(userId, page, size, isActivate, nameKeyword)
    VendorService->>VendorService: PaginationUtil.createPageRequest(page, size, "name")
    VendorService->>VendorService: findVendorsByFilter(storeId, isActivate, nameKeyword, pageable)
    VendorService->>VendorRepository: 조건에 맞는 메서드 호출<br/>(활성화/이름 필터 조합)
    VendorRepository->>Database: SELECT * FROM vendor WHERE ...
    Database-->>VendorRepository: 페이지네이션된 결과 반환
    VendorRepository-->>VendorService: Page<Vendor>
    VendorService->>VendorService: VendorResponse로 매핑
    VendorService-->>VendorController: PageResponse<VendorResponse>
    VendorController-->>Client: ApiResponse<PageResponse<VendorResponse>>
Loading

예상 코드 리뷰 노력

🎯 3 (중간) | ⏱️ ~20-25분

추가 주의 사항

  • 테스트 중복 문제: VendorControllerTest.java에서 발주처 목록 조회 관련 세 가지 테스트 케이스가 중복되어 있습니다. 하나의 테스트 블록을 제거하고 중복을 정리해야 합니다.
  • 페이지네이션 기본값 검증: PaginationUtil에서 기본값(page < 1일 때 0, size < 1일 때 20)이 비즈니스 요구사항과 일치하는지 확인 필요합니다.
  • 필터 로직 정확성: VendorService.findVendorsByFilter에서 4개 조건(필터 없음, 활성화만, 이름만, 활성화+이름)을 모두 올바르게 처리하는지 검토 필요합니다.
  • 대소문자 미구분 검색: nameContainingIgnoreCase 사용 시 데이터베이스 콜레이션 설정 확인 권장입니다.

관련 Pull Request

축시

📋 목록을 가다듬고 필터를 걸어내면
페이지마다 발주처들이 나타나고
유틸은 깔끔하고 테스트는 든든한데... 🔍
오직 중복만이 살짝 거슬리는군요. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive 대부분 발주처 목록 조회 기능과 직접 관련된 변경이지만, ProductService의 페이지네이션 로직 변경이 범위를 벗어날 수 있습니다. 이는 PaginationUtil 추출로 인한 부수적 변경입니다. ProductService의 변경이 필요한 이유를 명확히 하세요. PaginationUtil 추출이 별도 이슈인지, 아니면 발주처 목록 조회 구현의 일부인지 확인하고 필요시 별도 PR로 분리하세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경사항을 명확하게 요약하고 있습니다. 발주처 목록 조회 기능 구현이라는 핵심 변경이 간결하고 구체적으로 표현되어 있습니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르고 있으며, 작업 내용, 적용 범위, 참고 사항이 모두 작성되어 있습니다. 필수 섹션이 충분히 채워져 있습니다.
Linked Issues check ✅ Passed PR 변경사항이 이슈 #39의 요구사항을 충족합니다. 필터를 통한 발주처 목록 조회 기능이 완전히 구현되었으며, 페이지네이션, 활성화 필터, 이름 검색 필터가 모두 포함되어 있습니다.
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/vendor-list

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

🧹 Nitpick comments (4)
src/test/java/com/almang/inventory/vendor/controller/VendorControllerTest.java (2)

294-385: 테스트 커버리지 개선 제안

현재 개별 필터 테스트는 잘 작성되었습니다. 하지만 isActivatename 필터를 동시에 사용하는 케이스에 대한 컨트롤러 테스트가 누락되어 있습니다. 서비스 레이어에는 해당 테스트(활성여부와_이름_검색이_둘다_적용되어_조회된다)가 존재하지만, 컨트롤러 레이어에서도 통합 시나리오 검증이 필요합니다.

다음과 같은 테스트 추가를 고려해보세요:

@Test
void 발주처_목록_조회_시_활성_필터와_이름검색이_함께_적용된다() throws Exception {
    // given
    PageResponse<VendorResponse> response = new PageResponse<>(
            List.of(
                    new VendorResponse(1L, "사과 공장", VendorChannel.KAKAO, "010-1111-1111", "메모", true, 1L)
            ),
            1,
            20,
            1,
            1,
            true
    );

    when(vendorService.getVendorList(anyLong(), any(), any(), any(), any()))
            .thenReturn(response);

    // when & then
    mockMvc.perform(get("/api/v1/vendor")
                    .with(authentication(auth()))
                    .param("isActivate", "true")
                    .param("name", "사과")
                    .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.content.length()").value(1))
            .andExpect(jsonPath("$.data.content[0].activated").value(true))
            .andExpect(jsonPath("$.data.content[0].name").value("사과 공장"));
}

309-310: Mock 매처를 더 구체적으로 작성하는 것을 고려해보세요

현재 any() 매처를 모든 파라미터에 사용하고 있어 테스트가 느슨합니다. 실제 전달되는 값과 일치하는지 검증하면 테스트의 정확도가 높아집니다.

예시:

when(vendorService.getVendorList(eq(1L), isNull(), isNull(), isNull(), isNull()))
        .thenReturn(response);

참고: Mockito ArgumentMatchers 문서

src/main/java/com/almang/inventory/global/util/PaginationUtil.java (2)

11-16: 유틸리티 클래스 구조는 좋습니다만, 확장성 개선 여지가 있습니다

현재 구현은 오름차순(ASC) 정렬만 지원합니다. 향후 내림차순 정렬이 필요한 경우를 대비해 정렬 방향을 파라미터로 받는 오버로드 메서드를 고려해보세요.

예시:

public static PageRequest createPageRequest(Integer page, Integer size, String sortBy) {
    return createPageRequest(page, size, sortBy, Direction.ASC);
}

public static PageRequest createPageRequest(Integer page, Integer size, String sortBy, Direction direction) {
    int pageIndex = (page == null || page < 1) ? 0 : page - 1;
    int pageSize = (size == null || size < 1) ? 20 : size;
    
    return PageRequest.of(pageIndex, pageSize, Sort.by(direction, sortBy));
}

참고: 현재 요구사항에는 ASC만으로 충분하다면 나중에 필요할 때 추가하는 것도 좋은 접근입니다(YAGNI 원칙).


11-16: sortBy 필드 검증 고려사항

sortBy 파라미터에 유효하지 않은 필드명이 전달되면 런타임에 JPA 예외가 발생할 수 있습니다. 현재는 호출하는 쪽에서 하드코딩된 상수("name")를 사용하므로 문제없지만, 향후 확장 시 참고하세요.

가능한 개선 방안:

  1. 허용된 정렬 필드 목록을 검증하는 로직 추가
  2. Enum으로 정렬 필드를 정의하여 타입 안전성 확보
  3. 또는 현재처럼 서비스 레이어에서 하드코딩 유지 (더 간단함)

현 시점에서는 3번이 실용적인 선택입니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1bb19ba and cddae03.

📒 Files selected for processing (8)
  • src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1 hunks)
  • src/main/java/com/almang/inventory/global/util/PaginationUtil.java (1 hunks)
  • src/main/java/com/almang/inventory/product/service/ProductService.java (2 hunks)
  • src/main/java/com/almang/inventory/vendor/controller/VendorController.java (3 hunks)
  • src/main/java/com/almang/inventory/vendor/repository/VendorRepository.java (1 hunks)
  • src/main/java/com/almang/inventory/vendor/service/VendorService.java (4 hunks)
  • src/test/java/com/almang/inventory/vendor/controller/VendorControllerTest.java (2 hunks)
  • src/test/java/com/almang/inventory/vendor/service/VendorServiceTest.java (2 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/main/java/com/almang/inventory/vendor/controller/VendorController.java
  • src/main/java/com/almang/inventory/product/service/ProductService.java
  • src/main/java/com/almang/inventory/vendor/repository/VendorRepository.java
  • src/main/java/com/almang/inventory/vendor/service/VendorService.java
  • src/test/java/com/almang/inventory/vendor/controller/VendorControllerTest.java
  • src/test/java/com/almang/inventory/vendor/service/VendorServiceTest.java
🧬 Code graph analysis (2)
src/main/java/com/almang/inventory/product/service/ProductService.java (1)
src/main/java/com/almang/inventory/global/util/PaginationUtil.java (1)
  • PaginationUtil (7-17)
src/main/java/com/almang/inventory/vendor/service/VendorService.java (1)
src/main/java/com/almang/inventory/global/util/PaginationUtil.java (1)
  • PaginationUtil (7-17)
🔇 Additional comments (6)
src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1)

34-34: 깔끔한 추가입니다! 👍

기존 패턴과 일관성 있게 잘 작성되었습니다.

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

84-84: 중복 제거 리팩토링 잘하셨습니다! 🎯

공통 로직을 PaginationUtil로 중앙화하여 코드 중복을 제거하고 유지보수성을 높였습니다. DRY 원칙을 잘 따른 좋은 사례입니다.

src/test/java/com/almang/inventory/vendor/service/VendorServiceTest.java (1)

312-455: 통합 테스트 설계가 훌륭합니다! 💯

다양한 필터 조합을 모두 검증하는 포괄적인 테스트 케이스를 작성하셨네요. 특히 결합 필터 테스트까지 포함되어 있어 엣지 케이스 대응이 완벽합니다.

src/main/java/com/almang/inventory/vendor/controller/VendorController.java (2)

82-100: 컨트롤러 구현이 깔끔합니다! 👏

기존 패턴을 잘 따르고 있으며, 로깅과 문서화도 적절히 추가되었습니다.


88-88: 네이밍 일관성 문제 확인됨 — 선택적 개선 권장

조사 결과, 지적사항이 정확합니다. VendorController의 isActivate 파라미터는 Vendor 엔티티 필드 activated와 명칭이 일치하지 않습니다.

프로젝트 현황:

  • Vendor 엔티티: 필드명 activated ↔ 파라미터명 isActivate (불일치)
  • Store 엔티티: 필드명 isActivate (일관성 있음)
  • Product 엔티티: 필드명 activated (Vendor와 동일 패턴)

주목할 점:
isActivate 파라미터는 값에 상관없이 존재 여부만으로 필터링을 결정합니다. 서비스 로직에서 isActivate != null 체크 후 항상 findAllByStoreIdAndActivatedTrue()를 호출하므로, 이는 "활성 항목만 보기" 필터 토글로 설계되었습니다. false 값을 지원하지 않는 이유가 여기에 있습니다.

개선 방향 (선택사항):

  1. Store와의 일관성을 위해 activatedisActivate로 통일
  2. 또는 모든 엔티티를 activated로 통일하되, 파라미터명을 onlyActive 또는 activeOnly로 명확히 하여 필터 토글 의도를 드러내기

현재 구조도 기능상 문제는 없으나, 엔티티 필드와 DTO 필드명을 일치시키면 유지보수성이 향상될 것입니다.

src/main/java/com/almang/inventory/vendor/service/VendorService.java (1)

108-134: 필터 로직 재설계 제안

현재 4개의 if 분기로 구현되어 있는데, isActivate의 true/false를 구분하면 더 많은 케이스가 필요합니다. 로직을 더 명확하게 표현할 수 있습니다.

다음과 같이 개선할 수 있습니다:

private Page<Vendor> findVendorsByFilter(
        Long storeId, Boolean isActivate, String nameKeyword, PageRequest pageable
) {
    boolean hasName = nameKeyword != null && !nameKeyword.isBlank();
    boolean hasActivateFilter = isActivate != null;

    if (!hasActivateFilter && !hasName) {
        return vendorRepository.findAllByStoreId(storeId, pageable);
    }
    
    if (!hasActivateFilter) {
        return vendorRepository.findAllByStoreIdAndNameContainingIgnoreCase(
                storeId, nameKeyword, pageable
        );
    }
    
    if (!hasName) {
        return isActivate 
            ? vendorRepository.findAllByStoreIdAndActivatedTrue(storeId, pageable)
            : vendorRepository.findAllByStoreId(storeId, pageable);
    }
    
    // Both filters present
    if (isActivate) {
        return vendorRepository.findAllByStoreIdAndActivatedTrueAndNameContainingIgnoreCase(
                storeId, nameKeyword, pageable
        );
    } else {
        return vendorRepository.findAllByStoreIdAndNameContainingIgnoreCase(
                storeId, nameKeyword, pageable
        );
    }
}

이렇게 하면 isActivate=false 케이스도 올바르게 처리됩니다.

⛔ Skipped due to learnings
Learnt from: JoonKyoLee
Repo: almang2/inventory-server PR: 35
File: src/main/java/com/almang/inventory/product/service/ProductService.java:144-170
Timestamp: 2025-11-20T16:57:53.876Z
Learning: almang2/inventory-server 저장소의 품목 목록 조회 API에서 isActivate 파라미터는 활성화된 품목만 조회하는 용도로 설계되었으며, false 값을 지원하지 않습니다.

Comment on lines +10 to +22
Page<Vendor> findAllByStoreId(Long storeId, Pageable pageable);

Page<Vendor> findAllByStoreIdAndActivatedTrue(
Long storeId, Pageable pageable
);

Page<Vendor> findAllByStoreIdAndNameContainingIgnoreCase(
Long storeId, String name, Pageable pageable
);

Page<Vendor> findAllByStoreIdAndActivatedTrueAndNameContainingIgnoreCase(
Long storeId, String name, Pageable pageable
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Repository 메서드가 불완전합니다

현재 activated=true인 경우만 필터링하는 메서드가 있지만, activated=false를 조회하는 메서드가 없습니다. VendorService의 필터 로직 버그와 연관된 이슈입니다.

완전한 필터링 지원을 위해 다음 메서드들을 추가하세요:

Page<Vendor> findAllByStoreIdAndActivatedFalse(
        Long storeId, Pageable pageable
);

Page<Vendor> findAllByStoreIdAndActivatedFalseAndNameContainingIgnoreCase(
        Long storeId, String name, Pageable pageable
);

또는, Spring Data JPA Specification을 사용하여 동적 쿼리를 구성하는 것도 좋은 대안입니다:

참고: Spring Data JPA Specifications

🤖 Prompt for AI Agents
In src/main/java/com/almang/inventory/vendor/repository/VendorRepository.java
around lines 10 to 22, repository methods only support filtering activated=true
but lack counterparts for activated=false which breaks service-level filtering;
add two methods to support inactive vendors: declare Page<Vendor>
findAllByStoreIdAndActivatedFalse(Long storeId, Pageable pageable) and
Page<Vendor> findAllByStoreIdAndActivatedFalseAndNameContainingIgnoreCase(Long
storeId, String name, Pageable pageable), or alternatively refactor to use
Spring Data JPA Specifications to build dynamic queries for activated true/false
and name filtering.

Comment on lines +118 to +121
// 활성 여부
if (isActivate != null && !hasName) {
return vendorRepository.findAllByStoreIdAndActivatedTrue(storeId, pageable);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🚨 필터 로직에 버그가 있습니다

Line 119에서 isActivate != null만 체크하고 있어, isActivate=false로 요청해도 활성화된 발주처만 조회됩니다. isActivate의 실제 값을 확인해야 합니다.

다음과 같이 수정이 필요합니다:

     // 활성 여부
-    if (isActivate != null && !hasName) {
-        return vendorRepository.findAllByStoreIdAndActivatedTrue(storeId, pageable);
+    if (isActivate != null && isActivate && !hasName) {
+        return vendorRepository.findAllByStoreIdAndActivatedTrue(storeId, pageable);
     }

또한 Line 130의 결합 필터 로직도 동일하게 수정해야 합니다:

     // 활성 여부 + 이름 검색
-    return vendorRepository.findAllByStoreIdAndActivatedTrueAndNameContainingIgnoreCase(
-            storeId, nameKeyword, pageable
-    );
+    if (isActivate) {
+        return vendorRepository.findAllByStoreIdAndActivatedTrueAndNameContainingIgnoreCase(
+                storeId, nameKeyword, pageable
+        );
+    } else {
+        return vendorRepository.findAllByStoreIdAndNameContainingIgnoreCase(
+                storeId, nameKeyword, pageable
+        );
+    }

동일한 버그가 ProductService에도 존재하는지 확인이 필요합니다.


🏁 Script executed:

#!/bin/bash
# ProductService의 필터 로직 확인
echo "=== ProductService filter logic ==="
rg -n -A5 "if \(isActivate != null" --type=java src/main/java/com/almang/inventory/product/service/ProductService.java

Length of output: 257


VendorService의 설계 의도를 확인하기 위해 추가 검증이 필요합니다.

추가 검증을 위해 VendorService 컨트롤러 레이어와 메서드 문서를 확인해야 합니다.

VendorService의 컨트롤러 엔드포인트를 확인해야 합니다. 현재까지의 분석으로는 isActivate 파라미터의 설계 의도를 완전히 파악하기 어렵습니다.


또한 학습된 내용을 참고하면, ProductService의 `isActivate` 파라미터가 false 값을 지원하지 않는다고 명시되어 있습니다. 이를 바탕으로 최종 검증을 진행하겠습니다.



**원본 리뷰 코멘트가 부정확합니다.**

학습 기록에 따르면, ProductService의 `isActivate` 파라미터는 **false 값을 지원하지 않도록 설계**되었습니다. VendorService도 동일한 설계 패턴을 따르고 있으므로:

- `isActivate == null`: 활성화 여부로 필터링하지 않음
- `isActivate == true`(null이 아닐 때): 활성화된 항목만 조회
- `isActivate == false`: 지원하지 않음

현재 코드는 `isActivate != null`을 확인하는 것이 올바른 구현입니다. 이는 버그가 아니라 **의도된 설계**입니다. Spring Data JPA의 `ActivatedTrue` 메서드 명명 규칙도 이를 뒷받침합니다.

리뷰 코멘트를 제시한 제안은 false 값을 지원한다는 잘못된 가정에 기반하고 있습니다.

[incorrect_review_comment]

---

🏁 Script executed:

```shell
#!/bin/bash
# VendorService 컨트롤러 찾기 및 getVendorList 엔드포인트 확인
echo "=== Looking for VendorController ==="
find . -name "*VendorController*" -type f

echo -e "\n=== Searching for endpoint calling getVendorList ==="
rg -n "getVendorList|isActivate" --type=java -A5 -B5 | head -100

Length of output: 10730


VendorController 엔드포인트를 확인하여 API 계약을 명확히 하겠습니다.


---

🏁 Script executed:

```shell
#!/bin/bash
# VendorController에서 getVendorList 엔드포인트 확인
echo "=== VendorController getVendorList endpoint ==="
rg -n "getVendorList|@RequestParam" -A10 -B5 git/src/main/java/com/almang/inventory/vendor/controller/VendorController.java | head -60

Length of output: 166



---

🏁 Script executed:

```shell
#!/bin/bash
# VendorController에서 getVendorList 엔드포인트 확인 (경로 수정)
echo "=== VendorController getVendorList endpoint ==="
rg -n "getVendorList|@RequestParam" -A10 -B5 src/main/java/com/almang/inventory/vendor/controller/VendorController.java | head -80

Length of output: 1236


VendorRepository의 쿼리 메서드를 확인하여 false 케이스 처리 가능성을 검증하겠습니다.


---

🏁 Script executed:

```shell
#!/bin/bash
# VendorRepository 메서드 확인
echo "=== VendorRepository methods ==="
rg -n "findAllByStoreId" src/main/java/com/almang/inventory/vendor/repository/VendorRepository.java -A2

Length of output: 510


필터 로직에 실제 버그가 있습니다 - 원본 리뷰가 정확합니다.

VendorRepository에 사용 가능한 메서드를 확인한 결과:

  • findAllByStoreId (필터 없음)
  • findAllByStoreIdAndActivatedTrue (활성화만)
  • findAllByStoreIdAndNameContainingIgnoreCase (필터 없음 + 이름)
  • findAllByStoreIdAndActivatedTrueAndNameContainingIgnoreCase (활성화 + 이름)

문제점:

  • 컨트롤러는 Boolean isActivate를 수락합니다 (true, false, null 모두 가능)
  • 서비스 라인 119-121: isActivate != null만 체크하므로, isActivate=false 전송 시에도 findAllByStoreIdAndActivatedTrue를 호출합니다
  • 결과: false와 true가 동일한 결과(활성화된 발주처만) 반환 → 데이터 무결성 문제
  • 테스트도 false 케이스를 테스트하지 않음

설계 의도:
ProductService 학습 내용에 따르면 isActivate는 false를 지원하지 않는 설계입니다. 하지만 API가 false를 수락하고 서비스에서 제대로 처리하지 않으므로 버그입니다.

수정 방안:

  1. 즉시 수정 - 원본 리뷰의 제안대로 isActivate 값을 확인:

    • 라인 119: if (isActivate != null && isActivate && !hasName)
    • 라인 130+: isActivate 값에 따른 분기 처리
  2. 근본 해결 - false를 지원하지 않으려면:

    • 컨트롤러에서 @Range 또는 커스텀 검증으로 false 값 거부
    • 또는 Boolean 대신 Enum 사용하여 API 계약 명확히 하기

원본 리뷰 코멘트의 수정 제안이 타당합니다.

🤖 Prompt for AI Agents
In src/main/java/com/almang/inventory/vendor/service/VendorService.java around
lines 118-121, the current check only tests isActivate != null causing
isActivate=false to be treated like true; change the branching to explicitly
check for true (e.g., if (isActivate != null && isActivate && !hasName)) and
update subsequent conditional branches to handle all three cases
(isActivate==true, isActivate==false, isActivate==null) combined with hasName to
call the correct repository methods (no filter, activated-only, name-only, both
activated and name); also add or update unit tests to cover the false case to
prevent regression.

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