# task-160.1 완료 보고서

## 작업 정보
- **작업 ID**: task-160.1
- **작업명**: 약관AI Phase 2 — 품질 강화 + 피드백 루프
- **팀**: dev1-team (헤르메스 팀장)
- **일시**: 2026-03-03

## 작업 내용

InsuWiki 약관AI Phase 2: 2팀 모듈 통합, 별표 인덱싱, 피드백 루프 API 3가지 작업 완료.

### 작업 1: 2팀 모듈 통합 (vector-search/route.ts)
4개 모듈을 벡터 검색 파이프라인에 통합:
- **rateLimiter**: API 핸들러 최상단에 적용, 한도 초과 시 429 + Retry-After 헤더
- **injectionFilter**: sanitizeInput으로 입력 정제 + checkInjection으로 인젝션 탐지, unsafe 시 400
- **queryCache**: productId 존재 시 캐시 조회/저장 (TTL 24시간), 캐시 히트 시 즉시 반환
- **versionFilter**: 현행 메타데이터 기반 버전 필터, includeOldVersions 파라미터로 전체 버전 포함 옵션

처리 순서: 인증 → Rate Limit → Body 파싱 → sanitizeInput → checkInjection → 미등록 상품 검증 → 캐시 조회 → 벡터 검색 → 버전 필터 → 유사도 게이트 → 답변 생성 → 캐시 저장 → 반환

에러 핸들링: 캐시/버전필터 실패 시 warn 후 통과 처리 (서비스 가용성 우선)

### 작업 2: 별표(부속서류) 인덱싱 (pdfIndexing.ts)
- **별표 감지**: `[별표]`, `별표`, `부표`, `부속서류` 키워드 패턴으로 섹션 감지
- **별표 분리**: `separateAppendixSections` 함수로 본문과 별표 섹션 분리, [PAGE N] 마커 기반
- **유형 분류**: `classifyAppendixType`으로 `surgery_table`/`disability_table`/`disease_code`/`other` 자동 분류
- **별표 청크 저장**: `sourceType: 'appendix'`, `appendixType` 메타데이터 추가
- **본문-별표 참조 연결**: 본문 청크에서 "별표 참조", "별표 수술분류표에 따라" 등 감지 시 `relatedAppendixIds` 메타데이터로 별표 청크 ID 연결
- **처리 순서**: 별표 청크 먼저 저장 → 본문 청크에서 ID 참조

### 작업 3: 피드백 루프 API (feedback/route.ts)
기존 PATCH 유지 + POST 엔드포인트 신규 추가:
- **입력**: `{ queryId, feedbackType, comment? }`, 인증 필수
- **중복 방지**: 동일 userId 중복 피드백 → 409 Conflict
- **원자적 저장**: Firestore 트랜잭션으로 `answer_feedback` 저장 + `query_logs.feedbackStatus` 업데이트
- **리뷰 큐**: incorrect/incomplete 피드백 시 `admin_review_queue` 컬렉션에 등록
- **XSS 방지**: comment HTML 태그 제거

## 생성/수정 파일 목록

### 수정된 파일
- `/home/jay/projects/insuwiki/nextapp/src/types/firestore.ts` — InsuranceChunk에 appendixType/relatedAppendixIds 추가, AnswerFeedback 타입 추가, COLLECTIONS에 ANSWER_FEEDBACK 추가
- `/home/jay/projects/insuwiki/nextapp/src/app/api/ai/vector-search/route.ts` — 4개 모듈 통합 (rateLimiter, injectionFilter, queryCache, versionFilter), 미사용 SIMILARITY_THRESHOLDS import 제거
- `/home/jay/projects/insuwiki/functions/src/pdfIndexing.ts` — 별표 감지/분리/분류 함수 추가, 별표 청크 저장 로직, 본문-별표 참조 연결, 3개 함수 export 추가
- `/home/jay/projects/insuwiki/nextapp/src/app/api/ai/feedback/route.ts` — POST 엔드포인트 추가, 트랜잭션 기반 피드백 저장, 리뷰 큐 등록

### 신규 생성 파일
- `/home/jay/projects/insuwiki/functions/src/__tests__/appendixDetection.test.ts` — 별표 감지/분류/분리 테스트 48개
- `/home/jay/projects/insuwiki/nextapp/src/app/api/ai/feedback/__tests__/route.test.ts` — 피드백 API 테스트 30개

## 테스트 결과

- appendixDetection.test.ts: 48/48 통과
- feedback/route.test.ts: 30/30 통과
- pdfIndexing.test.ts (회귀): 38/38 통과
- answerValidator.test.ts (회귀): 37/37 통과
- versionFilter.test.ts (회귀): 29/29 통과
- injectionFilter.test.ts (회귀): 62/62 통과
- **nextapp 전체**: 15 파일 364/364 통과
- **functions 전체**: 2 파일 86/86 통과
- **합계**: 450/450 통과

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

### 검증 통과 항목
- 전체 테스트 재실행: 450/450 통과 확인
- TypeScript 타입 컴파일: functions 0 에러, nextapp 0 에러 (수정 후)
- 6개 파일 경로 정확성: 정상
- vector-search 4개 모듈 import + 실제 호출: 모두 확인됨
- pdfIndexing separateAppendixSections 호출 + sourceType='appendix' 저장: 확인됨
- feedback 트랜잭션 원자성: answer_feedback 저장 + query_logs 업데이트가 단일 트랜잭션: 확인됨
- 인증 체크: PATCH/POST 양쪽 verifyAuth 적용 확인
- Rate Limit + Injection Filter 최상단 적용: 확인됨
- XSS 방지: stripHtmlTags 함수 + 테스트 검증 확인

### 발견 후 수정한 이슈
1. **TS7006 타입 에러**: vector-search/route.ts L432 `(s)` 파라미터에 implicit any → 타입 어노테이션 추가로 해결
2. **Dead import**: 미사용 `SIMILARITY_THRESHOLDS` import 제거
3. **sourceType 캐스팅 불완전**: sources 캐스팅에 `'appendix'` 추가

### 수정 후 재검증
- nextapp TypeScript 타입 검사: 0 에러
- nextapp 전체 테스트: 364/364 통과

## 버그 유무
- 기존 기능 회귀: 없음 (기존 모든 테스트 통과)
- 새 기능 버그: 없음 (마아트 독립 검증 후 3건 수정 완료)

## 비고
- 별표 없는 PDF는 기존 로직과 동일하게 작동 (appendixSections 빈 배열)
- 캐시는 productId 있을 때만 사용 (일반 쿼리는 결과가 다양하므로 캐시 안 함)
- admin_review_queue는 트랜잭션 외부 처리 (큐 누락이 피드백 저장 자체를 롤백할 만큼 치명적이지 않음)
- HTML entity 인코딩 우회(`&lt;script&gt;`) 방어는 현재 서버사이드 저장이므로 위험 낮음, 향후 admin UI 렌더링 시 별도 escaping 권고
