[Feat] pgvector 검색 + live check + POST /search 조립 - #57
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ade 단위 테스트 — F-SEARCH-05/06/07 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 34 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughpgvector 기반 Top-K 검색, 후보별 live 권한 검증, 검색 결과 저장 및 Changes벡터 검색 및 API 흐름
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
actor Client
participant SearchController
participant SearchFacade
participant VectorSearchQueryService
participant PermissionQueryService
participant SearchResultCommandService
Client->>SearchController: POST /search
SearchController->>SearchFacade: search(userId, request)
SearchFacade->>VectorSearchQueryService: Top-K 후보 검색
VectorSearchQueryService-->>SearchFacade: VectorSearchCandidate 목록
SearchFacade->>PermissionQueryService: 후보별 canReadDocument()
PermissionQueryService-->>SearchFacade: 권한 판정
SearchFacade->>SearchResultCommandService: 검증된 후보 저장
SearchResultCommandService-->>SearchFacade: 저장 완료
SearchFacade-->>SearchController: SearchResponse
SearchController-->>Client: ApiResponse<SearchResponse>
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (4)
src/test/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandServiceTest.java (1)
60-65: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win저장 계약의 나머지 필드도 검증하세요.
이 테스트는 rank와
similarityScore만 확인합니다.matchedText와finalScore도 저장 계약의 일부이므로, capture한 엔티티에서 두 필드를 함께 assert해야 해당 매핑 회귀를 탐지할 수 있습니다.As per path instructions, "
src/test/**/*.java: 테스트 커버리지, 스프링 테스트 어노테이션, mock 사용법, 네이밍 규칙을 확인한다."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandServiceTest.java` around lines 60 - 65, Update the assertions in SearchResultCommandServiceTest to also verify matchedText and finalScore on the captured SearchResult entities in saved. Use the expected values for each entity and preserve the existing rank and similarityScore assertions.Source: Path instructions
docs/design/kangcheolung-#56-vector-search-live-check-api.md (1)
18-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value모든 fenced code block에 언어 식별자를 지정하세요.
docs/design/kangcheolung-#56-vector-search-live-check-api.md#L18-L47: 흐름도 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L57-L60: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L110-L112: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L132-L134: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L157-L166: 시나리오 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L176-L178: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L186-L189: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L210-L212: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L222-L224: 경로 블록에text를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L226-L232: HTTP 예시에http를 지정하세요.docs/design/kangcheolung-#56-vector-search-live-check-api.md#L236-L238: 경로 블록에text를 지정하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/design/kangcheolung-`#56-vector-search-live-check-api.md around lines 18 - 47, Specify language identifiers for every fenced code block in docs/design/kangcheolung-#56-vector-search-live-check-api.md: use text for the flow, path, and scenario blocks at lines 18-47, 57-60, 110-112, 132-134, 157-166, 176-178, 186-189, 210-212, 222-224, and 236-238; use http for the HTTP example at lines 226-232.Source: Linters/SAST tools
src/test/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryServiceTest.java (1)
51-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win리포지토리 호출 인자 계약도 검증하세요.
현재
any*()stub은modelId,permittedIds,topK, 벡터 직렬화 값이 잘못 전달돼도 테스트를 통과시킵니다.ArgumentCaptor또는 정확한 matcher로 이 값들을 검증해 pre-filter와 Top-K 계약 회귀를 막으세요.As per path instructions, "
src/test/**/*.java: 테스트 커버리지, 스프링 테스트 어노테이션, mock 사용법, 네이밍 규칙을 확인한다."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryServiceTest.java` around lines 51 - 62, Update the test around vectorSearchRepository.findTopK and vectorSearchQueryService.search to capture or precisely match every repository argument: the expected modelId, permittedIds, topK value, and serialized VECTOR input. Assert those values explicitly so incorrect pre-filter or Top-K arguments cannot satisfy the stub.Source: Path instructions
src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java (1)
42-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win전역
LENIENT설정을 제거하고 기본 strict stubbing을 유지하세요.현재 테스트의 stubbing은 각 시나리오에서 사용되므로 전역 완화는 불필요한 mock 설정을 숨길 수 있습니다. 필요한 경우에만 개별 stubbing에 한정해 완화하세요.
수정 예시
-import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; ... -@MockitoSettings(strictness = Strictness.LENIENT)As per path instructions,
src/test/**/*.java의 “mock 사용법” 확인 규칙을 적용했습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java` around lines 42 - 44, SearchFacadeTest의 클래스 수준 `@MockitoSettings`(strictness = Strictness.LENIENT)를 제거하고 Mockito 기본 strict stubbing을 사용하세요. 각 테스트 시나리오에서 실제로 불필요한 stubbing이 있는 경우에만 해당 개별 stubbing에 한정해 완화 설정을 적용하세요.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/design/kangcheolung-`#56-vector-search-live-check-api.md:
- Around line 249-257: Clarify the FAILED-history policy in the live-check API
design: either persist failure status through an independent transaction that
survives rethrown exceptions, including embedding, user, and collection lookup
failures before createProcessing(), or revise the documented behavior to state
that those pre-history failures do not create SearchQuery records. Align the
failure table and the “markFailed() then rethrow remains FAILED” section with
the chosen implementation.
In
`@src/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.java`:
- Around line 7-11: 각 신규 타입에 역할·책임·경계를 설명하는 클래스 수준 주석을 추가하세요. SearchRequest는
HTTP 검색 요청 DTO와 기본값·검증 경계를, SearchController는 HTTP API 진입점과 facade 위임을,
SearchResponse는 검색 응답 조립과 API 응답 경계를, SearchResultItem은 개별 결과 표현과 후보 모델 변환을,
SearchFacadeTest는 테스트 대상과 mock 경계를 설명해야 합니다. 변경 대상은
src/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.java
7-11,
src/main/java/com/opensource/docgrid/domain/search/controller/SearchController.java
22-26,
src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResponse.java
9-12,
src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.java
9-15,
src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java
42-45입니다.
- Line 10: Update the collectionId field in SearchRequest to accept null for
whole-collection searches but validate any provided value as strictly positive,
using the project’s existing DTO validation annotations and conventions.
In
`@src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResponse.java`:
- Around line 13-18: Update SearchResponse.of to wrap the constructed items list
in a copied unmodifiable list when creating the response, ensuring
SearchResponse.results cannot be modified by callers and matches the immutable
contract used by empty().
In
`@src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.java`:
- Line 14: Update the similarityScore contract consistently: either document and
implement the existing 1 - distance calculation for its actual -1~1 range, or
transform/clamp the value so it genuinely remains within 0~1 and update the
`@Schema` description accordingly. Ensure the implementation producing
similarityScore and the SearchResultItem schema describe the same returned
range.
In
`@src/main/java/com/opensource/docgrid/domain/search/repository/SearchResultRepository.java`:
- Around line 7-8: 添加类级 JavaDoc:在 SearchResultRepository 中说明其作为 SearchResult
持久化边界的职责;在 VectorSearchQueryServiceTest 中说明其验证 fast-path 与候选转换;在
SearchResultCommandServiceTest 中说明其验证搜索结果保存映射。为这三个新增类型分别补充职责、责任范围和边界描述。
In
`@src/main/java/com/opensource/docgrid/domain/search/service/SearchFacade.java`:
- Around line 29-42: Update the class-level flow documentation in SearchFacade
to include the User/Collection FK entity lookup and PROCESSING persistence
before the live check, renumber live check as step 6, shift search_results
saving to step 7, and SUCCESS/latency completion to step 8. Keep the documented
sequence aligned with the actual implementation.
- Around line 111-113: Update the exception path in SearchFacade so the failure
state recorded by SearchQueryCommandService.markFailed is committed
independently before the original exception is rethrown. Use a separate
REQUIRES_NEW transaction boundary for the failure update, or otherwise adjust
exception handling to prevent updateToFailed from rolling back while preserving
exception propagation.
---
Nitpick comments:
In `@docs/design/kangcheolung-`#56-vector-search-live-check-api.md:
- Around line 18-47: Specify language identifiers for every fenced code block in
docs/design/kangcheolung-#56-vector-search-live-check-api.md: use text for the
flow, path, and scenario blocks at lines 18-47, 57-60, 110-112, 132-134,
157-166, 176-178, 186-189, 210-212, 222-224, and 236-238; use http for the HTTP
example at lines 226-232.
In
`@src/test/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandServiceTest.java`:
- Around line 60-65: Update the assertions in SearchResultCommandServiceTest to
also verify matchedText and finalScore on the captured SearchResult entities in
saved. Use the expected values for each entity and preserve the existing rank
and similarityScore assertions.
In
`@src/test/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryServiceTest.java`:
- Around line 51-62: Update the test around vectorSearchRepository.findTopK and
vectorSearchQueryService.search to capture or precisely match every repository
argument: the expected modelId, permittedIds, topK value, and serialized VECTOR
input. Assert those values explicitly so incorrect pre-filter or Top-K arguments
cannot satisfy the stub.
In
`@src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java`:
- Around line 42-44: SearchFacadeTest의 클래스 수준 `@MockitoSettings`(strictness =
Strictness.LENIENT)를 제거하고 Mockito 기본 strict stubbing을 사용하세요. 각 테스트 시나리오에서 실제로
불필요한 stubbing이 있는 경우에만 해당 개별 stubbing에 한정해 완화 설정을 적용하세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 95eb3b3d-7a97-45c1-83c1-89d49c283504
📒 Files selected for processing (15)
docs/design/kangcheolung-#56-vector-search-live-check-api.mdsrc/main/java/com/opensource/docgrid/domain/search/controller/SearchController.javasrc/main/java/com/opensource/docgrid/domain/search/dto/VectorSearchCandidate.javasrc/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.javasrc/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResponse.javasrc/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.javasrc/main/java/com/opensource/docgrid/domain/search/repository/SearchResultRepository.javasrc/main/java/com/opensource/docgrid/domain/search/repository/VectorSearchRepository.javasrc/main/java/com/opensource/docgrid/domain/search/repository/VectorSearchRow.javasrc/main/java/com/opensource/docgrid/domain/search/service/SearchFacade.javasrc/main/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandService.javasrc/main/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryService.javasrc/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.javasrc/test/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandServiceTest.javasrc/test/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryServiceTest.java
| public record SearchRequest( | ||
| @NotBlank String queryText, | ||
| @Min(1) @Max(20) Integer topK, | ||
| Long collectionId | ||
| ) { |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
새 Java 타입에 역할·책임·경계를 설명하는 클래스 주석을 추가하세요.
src/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.java#L7-L11: HTTP 검색 요청 DTO와 기본값·검증 경계를 설명하세요.src/main/java/com/opensource/docgrid/domain/search/controller/SearchController.java#L22-L26: HTTP API 진입점과 facade 위임 경계를 설명하세요.src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResponse.java#L9-L12: 검색 응답 조립 DTO와 API 응답 경계를 설명하세요.src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.java#L9-L15: 개별 검색 결과 표현과 후보 모델 변환 경계를 설명하세요.src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java#L42-L45: SearchFacade 단위 테스트의 대상과 mock 경계를 설명하세요.
As per coding guidelines, “Every newly created class, interface, or record must have a class-level comment describing its role, responsibility, and boundary.”
📍 Affects 5 files
src/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.java#L7-L11(this comment)src/main/java/com/opensource/docgrid/domain/search/controller/SearchController.java#L22-L26src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResponse.java#L9-L12src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.java#L9-L15src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java#L42-L45
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.java`
around lines 7 - 11, 각 신규 타입에 역할·책임·경계를 설명하는 클래스 수준 주석을 추가하세요. SearchRequest는
HTTP 검색 요청 DTO와 기본값·검증 경계를, SearchController는 HTTP API 진입점과 facade 위임을,
SearchResponse는 검색 응답 조립과 API 응답 경계를, SearchResultItem은 개별 결과 표현과 후보 모델 변환을,
SearchFacadeTest는 테스트 대상과 mock 경계를 설명해야 합니다. 변경 대상은
src/main/java/com/opensource/docgrid/domain/search/dto/request/SearchRequest.java
7-11,
src/main/java/com/opensource/docgrid/domain/search/controller/SearchController.java
22-26,
src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResponse.java
9-12,
src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.java
9-15,
src/test/java/com/opensource/docgrid/domain/search/service/SearchFacadeTest.java
42-45입니다.
Source: Coding guidelines
| @Schema(description = "문서 제목") String documentTitle, | ||
| @Schema(description = "매칭된 청크 텍스트") String chunkText, | ||
| @Schema(description = "원본 문서 페이지 번호, 페이지 개념이 없는 형식은 null") Integer pageNo, | ||
| @Schema(description = "코사인 유사도 (0~1, 높을수록 유사)") BigDecimal similarityScore |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## Locate SearchResultItem"
fd -a 'SearchResultItem\.java$' . || true
echo "## Git status/stat"
git status --short
git diff --stat || true
echo "## Search for similarity/cosine transforms in Java"
rg -n "similarityScore|similarity|cosine|vector|Similarity|cosine\(" src/main/java || true
echo "## Candidate file"
file="$(fd 'SearchResultItem\.java$' . | head -n1 || true)"
if [ -n "${file:-}" ]; then
echo "FILE=$file"
wc -l "$file"
cat -n "$file"
fiRepository: DocGrid/backend
Length of output: 9933
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## VectorSearchCandidate"
file="$(fd 'VectorSearchCandidate\.java$' . | head -n1 || true)"
echo "FILE=$file"
wc -l "$file"
cat -n "$file"
echo "## VectorSearchRepository"
file="$(fd 'VectorSearchRepository\.java$' . | head -n1 || true)"
echo "FILE=$file"
wc -l "$file"
sed -n '1,120p' "$file" | cat -n
echo "## SearchResultCommandService"
file="$(fd 'SearchResultCommandService\.java$' . | head -n1 || true)"
echo "FILE=$file"
wc -l "$file"
cat -n "$file"
echo "## Relevant SQL/native query text"
rg -n "similarity_score|cosine|<=>|similarityScore|vectorStr|FindQuery|`@Query`|`@SqlResultSetMapping`|`@ConstructorResult`" src/main/java -SRepository: DocGrid/backend
Length of output: 13000
유사도 범위 표시를 실제 반환 값과 맞게 변경하세요.
현재 similarityScore는 1 - e.vector <=> queryVector로 계산되어 코사인 거리 범위가 0~2라면 결과도 -1~1에 열 수 있어 0~1 문서가 실제 응답 계약과 맞지 않습니다. 1 - distance의 계약을 유지하려면 문서와 구현에서 0~2라고 맞추고, 실제 유사도로 맞추려면 clamp 또는 1/2 * (1 - distance) 같은 변환을 일관되게 적용하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/opensource/docgrid/domain/search/dto/response/SearchResultItem.java`
at line 14, Update the similarityScore contract consistently: either document
and implement the existing 1 - distance calculation for its actual -1~1 range,
or transform/clamp the value so it genuinely remains within 0~1 and update the
`@Schema` description accordingly. Ensure the implementation producing
similarityScore and the SearchResultItem schema describe the same returned
range.
Source: Coding guidelines
| public interface SearchResultRepository extends JpaRepository<SearchResult, Long> { | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
신규 타입에 역할과 경계를 설명하는 클래스 레벨 주석을 추가하세요.
src/main/java/com/opensource/docgrid/domain/search/repository/SearchResultRepository.java#L7-L8:SearchResult영속화 경계를 설명하는 JavaDoc을 추가하세요.src/test/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryServiceTest.java#L25-L27: fast-path 및 후보 변환을 검증하는 테스트 클래스임을 설명하세요.src/test/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandServiceTest.java#L31-L33: 검색 결과 저장 매핑을 검증하는 테스트 클래스임을 설명하세요.
As per coding guidelines, "Every newly created class, interface, or record must have a class-level comment describing its role, responsibility, and boundary."
📍 Affects 3 files
src/main/java/com/opensource/docgrid/domain/search/repository/SearchResultRepository.java#L7-L8(this comment)src/test/java/com/opensource/docgrid/domain/search/service/query/VectorSearchQueryServiceTest.java#L25-L27src/test/java/com/opensource/docgrid/domain/search/service/command/SearchResultCommandServiceTest.java#L31-L33
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/opensource/docgrid/domain/search/repository/SearchResultRepository.java`
around lines 7 - 8, 添加类级 JavaDoc:在 SearchResultRepository 中说明其作为 SearchResult
持久化边界的职责;在 VectorSearchQueryServiceTest 中说明其验证 fast-path 与候选转换;在
SearchResultCommandServiceTest 中说明其验证搜索结果保存映射。为这三个新增类型分别补充职责、责任范围和边界描述。
Source: Coding guidelines
🔍 작업 내용
Closes #56
✨ 상세 설명
전체 흐름
신규 파일
VectorSearchRepository<=>코사인 거리 네이티브 쿼리VectorSearchRowVectorSearchCandidateVectorSearchQueryServiceSearchResultRepositorySearchResultCommandServiceSearchFacadeSearchControllerPOST /search— queryText 필수, topK 1~20 기본 5SearchRequest/SearchResponse/SearchResultItemstale 캐시 방어 시나리오 (포트폴리오 증빙)
권한 회수 직후 검색 시 pre-filter 단계에서 캐시 기반으로 문서가 포함될 수 있지만, live check(5단계
canReadDocument)에서invalidated_at확인 + ROLE/DEPT live 검증으로 해당 문서를 최종 제거한다.[PERM]+[SEARCH]타이밍 로그로 전 과정 추적 가능하다.🛠️ 추후 리팩토링 및 고도화 계획
@DataJpaTest로 UNION 쿼리 및 pgvector 쿼리 통합 테스트 추가📸 스크린샷 (선택)
해당 없음
💬 리뷰 요구사항
SearchFacade가@Transactional안에서 임베딩 서버 HTTP 호출을 포함하는 구조인데, 커넥션 점유 시간이 길어지는 트레이드오프가 있습니다. MVP 단계에서 허용 가능한 수준인지 의견 부탁드립니다.VectorSearchRepository의IN (:permittedIds)파라미터가 매우 많아질 경우(수천 건 이상) 쿼리 성능 이슈가 생길 수 있습니다. 현재 단계에서 추가 대응이 필요한지 의견 부탁드립니다.Summary by CodeRabbit
새 기능
문서