# task-157.1 완료 보고서

## 작업 정보
- **작업 ID**: task-157.1
- **작업명**: 약관AI Phase 1 — 검색 품질 핵심 개선
- **팀**: dev1-team (헤르메스 팀장)
- **일시**: 2026-03-03

## 작업 내용

InsuWiki 약관AI의 검색 품질을 근본적으로 개선하는 3가지 작업 완료.

### 작업 1: CL-1 청킹 재설계 (pdfIndexing.ts)
- `structureAwareChunk` 함수 신규 구현 (141~234행)
- "제X조" 패턴 조항 경계 인식 → 1개 조 = 1개 청크
- 2000자 초과 시 항(①②③) 단위 2차 분할
- 패턴 6종 인식: 제X조, ①②③, ⑴⑵⑶, 가.나.다., (1)(2)(3), 1. 2. 3.
- 단서조항 보존: "다만", "단,", "그러나" 등 10종 키워드 → 이전 문장에 강제 병합
- 면책/부지급 블록 강제 병합: "면책", "부지급" 등 6종 키워드
- 양방향 Overlap 300자 적용
- 기존 `splitIntoChunks` 폴백 유지

### 작업 2: CL-5 검색 정밀도 (vector-search/route.ts)
- 동적 임계값: productId/상품명 포함 시 TRUST=0.92/AMBIGUOUS=0.80, 일반 쿼리 TRUST=0.80/AMBIGUOUS=0.65
- 미등록 상품 사전 검증: insurance_metadata 조회 → 미등록 시 즉시 안내 반환
- productId 메타데이터 필터 우선 적용 (벡터 검색 후 후처리 필터링)
- `sanitizeAssertions`/`maskPII` 출력 필터 파이프라인 통합

### 작업 3: 출력 필터 (answerValidator.ts)
- `sanitizeAssertions`: 단정 표현 7종 자동 치환 (부정형 우선 매칭)
- `maskPII`: 주민등록번호, 전화번호, 이름+호칭 마스킹 (보험 약관 일반 용어 제외 목록 적용)
- `validateAnswer` 강화: 원문 출처 없이 결론만 있는 답변 차단

## 생성/수정 파일 목록

### 수정된 파일
- `/home/jay/projects/insuwiki/functions/src/pdfIndexing.ts` — structureAwareChunk 및 헬퍼 함수 5개 추가, 호출부 변경
- `/home/jay/projects/insuwiki/nextapp/src/app/api/ai/vector-search/route.ts` — 동적 임계값, 미등록 상품 검증, 출력 필터 통합
- `/home/jay/projects/insuwiki/nextapp/src/lib/ai/answerValidator.ts` — sanitizeAssertions, maskPII, validateAnswer 강화

### 테스트 파일
- `/home/jay/projects/insuwiki/functions/src/__tests__/pdfIndexing.test.ts` — structureAwareChunk 테스트 13개 추가 (기존 25개 유지)
- `/home/jay/projects/insuwiki/nextapp/src/lib/ai/answerValidator.test.ts` — 신규 생성, 37개 테스트

## 테스트 결과

| 테스트 파일 | 결과 |
|------------|------|
| pdfIndexing.test.ts | 38/38 통과 |
| answerValidator.test.ts | 37/37 통과 |
| **합계** | **75/75 통과** |

## 마아트(QC) 독립 검증 결과

### 검증 통과 항목
- 테스트 전체 재실행: 75/75 통과 확인
- TypeScript 타입 컴파일: 오류 없음
- 작업 지시서 요구사항 누락: 없음
- 파일 경로 정확성: 정상
- import/호출 순서 정합성: 정상 (validateAnswer → sanitizeAssertions → maskPII → 면책 문구)

### 발견 후 수정한 이슈
- **maskPII 오마스킹**: "계약자님", "피보험자씨", "당사 고객" 등 보험 약관 일반 용어 오마스킹 문제 → PII_NAME_EXCLUDES 제외 목록 추가 + "고객" 호칭 마스킹 대상에서 제거. 수정 후 테스트 추가 검증 완료.

### 배포 시 주의사항 (Firestore 복합 인덱스)
`checkProductRegistered` 함수에서 사용하는 3개 복합 쿼리에 대한 Firestore 인덱스가 필요:
- `insurance_metadata`: productId + isActive
- `insurance_metadata`: productName + isActive
- `insurance_metadata`: companyName + isActive

현재 인덱스 미등록 시 catch 블록이 통과 처리하여 서비스는 정상 동작하지만, 검증 기능이 무력화됨. 배포 전 `firestore.indexes.json`에 추가 필요.

## 버그 유무
- 기존 기능 회귀: 없음 (기존 25개 테스트 + 9개 회귀 테스트 통과)
- 새 기능 버그: 없음 (마아트 독립 검증 후 maskPII 오마스킹 이슈 수정 완료)

## 비고
- 2팀 인프라 작업과 충돌 가능성: 없음 (지시된 3개 파일만 수정)
- route.ts에서 Firestore Vector Search `findNearest`는 where 필터를 직접 지원하지 않으므로 후처리 필터링 적용
- PRODUCT_SIGNAL_PATTERNS 정규식은 일반 쿼리(수백자 이하)에서 성능 이슈 없음 (1000회 기준 <1ms)
