feat #565: add vector knowledge ingestion demo

This commit is contained in:
devmrko
2026-06-29 18:11:16 +09:00
parent c7b11ab669
commit 4ba6a57835
18 changed files with 847 additions and 4 deletions

View File

@@ -0,0 +1,36 @@
package com.cloudhandson.vpdbackoffice.service;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.junit.jupiter.api.Test;
class VectorChunkerTest {
@Test
void keepsParagraphsTogetherUntilTheConfiguredLimit() {
var chunks = VectorChunker.chunk(
"첫 번째 문단입니다.\n\n두 번째 문단은 같은 지식자료입니다.", 80);
assertThat(chunks).hasSize(1);
assertThat(chunks.get(0).chunkNo()).isEqualTo(1);
assertThat(chunks.get(0).text()).contains("첫 번째", "두 번째");
}
@Test
void splitsLongTextAndNumbersChunksFromOne() {
var chunks = VectorChunker.chunk("문장 하나입니다. ".repeat(30), 100);
assertThat(chunks).hasSizeGreaterThan(1);
assertThat(chunks).extracting("chunkNo").containsExactlyElementsOf(
java.util.stream.IntStream.rangeClosed(1, chunks.size()).boxed().toList());
assertThat(chunks).allSatisfy(chunk -> assertThat(chunk.text()).isNotBlank());
}
@Test
void rejectsBlankContent() {
assertThatThrownBy(() -> VectorChunker.chunk(" ", 600))
.isInstanceOf(AppException.class)
.hasMessageContaining("청킹할 문서 본문");
}
}

View File

@@ -109,6 +109,23 @@ class GuidedFlowTemplateTest {
assertThat(sse).contains("Instruction / parameter mapping").contains("bearerToken");
}
@Test
void vectorKnowledgePageShowsIngestPermissionAndSearchFlow() throws IOException {
String vector = template("vector-knowledge.html");
String result = template("fragments/vector-search-result.html");
assertThat(vector)
.contains("문서 등록 → 청킹 → 임베딩 → 태그 저장")
.contains("ALLOW TAG SPRING_BOOT")
.contains("DENY TAG ORDS")
.contains("권한 적용 벡터 검색")
.contains("/vector-knowledge/ingest")
.contains("/vector-knowledge/search");
assertThat(result)
.contains("TECH_TAG")
.contains("검색 기술 상세 보기");
}
private String template(String relativePath) throws IOException {
return Files.readString(Path.of("src/main/resources/templates").resolve(relativePath));
}