# task-158.1 완료 보고서 — 약관AI Phase 1: 인프라 + 보안 강화

**팀:** dev2-team (오딘 팀장)
**담당:** 토르(백엔드), 프레이야(보안), 헤임달(테스트), 마아트(QC)
**완료일:** 2026-03-03

---

## 작업 내용

### CL-2: 버전 관리
- `effectiveDateRange.end` 자동 설정: 새 약관 인덱싱 시 Firestore 트랜잭션으로 동일 productId 기존 문서의 end date 자동 설정
- `insurance_metadata` 문서 ID를 `${productId}_${effectiveDate}` 버전별 키로 전환
- `generationType` 필드 추가 (`'gen1'|'gen2'|'gen3'|'gen4'`)
- 버전 필터 유틸리티 `versionFilter.ts` 생성 (1팀이 vector-search에서 import 가능)
- `firestore.ts` 타입에 `GenerationType` 추가

### CL-3: ANN 인덱스 + 캐싱
- `firestore.indexes.json`: insurance_chunks, youtube_knowledge 벡터 인덱스를 `flat` → `treeAh`(ANN) 전환
- `queryCache.ts` 생성: 캐시 키 = SHA-256(query) + productId + version, TTL 24시간, Firestore `query_cache` 컬렉션
- `firestore.ts`에 `QueryCache` 타입 추가, COLLECTIONS에 `QUERY_CACHE` 등록

### CL-6: 보안
- `rateLimiter.ts`: 분 10 / 시간 100 / 일 500 쿼리 제한, uid + IP 이중 체크, Firestore 트랜잭션 기반
- `injectionFilter.ts`: 영문 8패턴 + 한국어 7패턴 인젝션 탐지, 보험 도메인 화이트리스트 10키워드, 200자 초과 경고, sanitizeInput 함수
- `firestore.rules`: `query_cache`, `rate_limits` 서버 전용 규칙 추가

---

## 생성/수정 파일 목록

### 신규 생성 (4개)
- `nextapp/src/lib/ai/versionFilter.ts` — 버전 필터 유틸리티 (4 export 함수)
- `nextapp/src/lib/cache/queryCache.ts` — 쿼리 캐시 (4 export 함수)
- `nextapp/src/lib/security/rateLimiter.ts` — Rate Limiter (2 export 함수 + 1 interface)
- `nextapp/src/lib/security/injectionFilter.ts` — 인젝션 필터 (2 export 함수 + 1 interface)

### 수정 (4개)
- `firestore.indexes.json` — 벡터 인덱스 flat → treeAh 전환
- `firestore.rules` — query_cache, rate_limits 서버 전용 규칙 추가
- `nextapp/src/types/firestore.ts` — GenerationType, QueryCache, RateLimitRecord 타입 + COLLECTIONS 추가
- `functions/src/pdfIndexing.ts` — 메타데이터 upsert 트랜잭션화 (버전별 문서 + end date 자동 설정 + generationType)

### 테스트 파일 (2개)
- `nextapp/src/lib/security/__tests__/injectionFilter.test.ts`
- `nextapp/src/lib/ai/__tests__/versionFilter.test.ts`

---

## 테스트 결과

### 헤임달 테스트 (1차)
- injectionFilter.ts: Vitest 62 PASS
- versionFilter.ts: Vitest 29 PASS
- firestore.indexes.json: 4/4 검증 PASS
- firestore.rules: 4/4 검증 PASS
- firestore.ts: 15/15 검증 PASS
- pdfIndexing.ts: 8/8 검증 PASS
- queryCache.ts: 10/10 코드리뷰 PASS
- rateLimiter.ts: 15/15 코드리뷰 PASS
- **총 147개 검증 항목 모두 PASS**

### 마아트 QC (독립 재검증)
- Vitest 재실행: **91/91 PASS** (267ms)
- TypeScript 컴파일: **에러 0건** (`tsc --noEmit` 통과)
- 파일 경로/내용: **모두 정상**
- 작업 지시 체크리스트: **10/10 항목 충족**
- WARNING 1건 발견 → 수정 완료 (pdfIndexing.ts createdAt 필드 추가)
- **종합 판정: APPROVED**

---

## 버그 유무

- 마아트가 발견한 `createdAt` 누락 이슈 → 즉시 수정 완료
- 그 외 버그 없음

---

## 주의사항

- `insurance_metadata` 문서 ID가 `productId` → `${productId}_${effectiveDate}`로 변경됨. 기존에 productId로 직접 조회하던 코드(admin page 등)는 `where('productId', '==', ...)` 쿼리로 전환 필요
- 1팀이 `vector-search/route.ts`에서 `versionFilter.ts`를 import하여 사용할 예정
- `query_cache` 컬렉션에 Firestore TTL 정책 설정 필요 (`expireAt` 필드 기준 자동 삭제)
- `rate_limits` 컬렉션은 자체 윈도우 만료 로직으로 관리됨 (별도 TTL 불필요)

---

## 비고

- 청킹 로직(splitIntoChunks 등) 1팀 담당 부분은 일절 수정하지 않음
- vector-search/route.ts 절대 미수정
- TypeScript strict 모드 컴파일 에러 0건 확인
