# Agent 미팅: 과거 약관 버전 조회 기능 설계

**날짜**: 2026-03-03
**소집 이유**: CL-7 원클릭 재인덱싱에서 과거 약관 버전 검색 지원을 위한 설계 결정
**참여 페르소나**: 헤르메스(1팀장), 오딘(2팀장), 비너스(디자인센터), 아르고스(테스터), 로키(레드팀)
**총 사이클 수**: 2

---

## Cycle 1

### 아누 분석

핵심 문제: 현재 InsuranceChunkArchive에 7일 TTL이 적용되어 과거 버전 청크가 영구 삭제됨.
보험은 "가입 시점 약관"이 적용되므로, 설계사가 과거 약관을 조회하는 빈도가 높음.

기존 구현: versionFilter.ts에 filterMetadataByDate() 함수 존재하지만, 실제 검색에서는 filterCurrentChunks()만 사용 중.

### 페르소나 의견

**헤르메스**: (1) archive 영구 보존 + TTL 제거, (2) targetDate 파라미터로 현행/과거 분기, (3) 버전 목록 API + 셀렉트박스 UI, (4) chunkHash 기반 임베딩 재사용으로 비용 절감

**오딘**: (1) 저장 비용 $2/월 무시 가능, (2) 같은 컬렉션 혼합 시 ANN 인덱스 오염으로 검색 비용 3배 증가($144/월 추가), (3) Cold Storage 비현실적 (복원 비용/지연), (4) 별도 archive 컬렉션 + exact KNN이 최적 (현행 성능 무영향, 과거 검색 1-3초)

**비너스**: (1) 날짜 입력 → 약관 버전 자동 매핑 UX, (2) 구버전 결과에 amber 배너 1회 표시 (카드별 반복 금지 = 경고 피로 방지), (3) 차등 경고 (현행과 내용 다를 때만 배지), (4) 3클릭 이내 완료 플로우

**아르고스**: (1) 전환일 겹침(EDGE-002) 위험 높음, (2) 재인덱싱 멱등성 파괴 위험, (3) 골든 테스트셋 200건 회귀 검증 필수, (4) 실손 세대 전환 경계 테스트 필요

**로키**: (1) 유/무료 티어링 권장 (과거 버전 = 유료 기능), (2) 날짜 파라미터 서버사이드 검증 필수 (미래 날짜 차단, 범위 강제), (3) 단일 쿼리 = 단일 버전 원칙, (4) 조회 로그 90일 후 익명화, (5) 과거 버전 전용 rate limit (분 5/시간 30/일 100)

### 합의
1. insurance_chunks(현행 ANN) + insurance_chunks_archive(과거 exact KNN) 분리
2. 7일 TTL 즉시 제거 → 영구 보존
3. targetDate 파라미터로 현행/과거 분기
4. 날짜 서버사이드 검증, 단일 쿼리 = 단일 버전
5. 응답에 버전 컨텍스트 워터마크 강제

### 미해결 항목
- 전환일 겹침 처리 규칙
- 유/무료 티어링 범위
- 별표(appendices) 버전 관리

---

## Cycle 2

### 아누 분석 (미해결 항목 결론)

**1. 전환일 겹침**: filterMetadataByDate()가 `start <= targetDate < end` (strict less than) 사용 → 구버전 end와 신버전 start가 같으면 신버전만 반환. 현재 코드로 이미 해결됨. 테스트 케이스 추가만 필요.

**2. 유/무료 티어링**: 기능 구현은 하되 API 미들웨어에서 플랜 체크. 베타 기간 전체 개방, 유료 전환 시 제한. 비즈니스 모델과 연동.

**3. 별표 버전 관리**: MVP에서는 약관 본문 청크만 아카이브. 별표 아카이브는 2차 우선순위.

### 합의
- 추가 코딩 없이 기존 로직으로 전환일 해결 확인
- 유/무료 티어링은 API 레벨에서 구현
- 별표 아카이브는 다음 이터레이션

---

## 최종 합의 사항

### 데이터 아키텍처
1. `insurance_chunks`: 현행 버전 전용 (ANN treeAh 인덱스 유지)
2. `insurance_chunks_archive`: 과거 버전 영구 보존 (TTL 제거, ANN 인덱스 불필요, exact KNN 사용)
3. `InsuranceChunkArchive` 타입에서 `archiveExpireAt` 제거, `supersededByDate` 추가
4. `InsuranceChunk`에 `chunkHash` 필드 추가 (임베딩 재사용 키, 2차 우선순위)

### API 설계
5. vector-search/route.ts: `includeOldVersions` → `targetDate: string | null` 교체
6. targetDate null → 현행 검색 (insurance_chunks, ANN)
7. targetDate 존재 → 과거 검색 (insurance_chunks_archive, exact KNN)
8. 신규 API: `/api/ai/versions?productId=xxx` — 상품별 버전 목록 반환
9. 캐시 키에 targetDate 포함

### UI/UX
10. "조회 기준" 라디오: 현행 / 가입 시점
11. 가입일 직접 입력 → 약관 버전 자동 매핑
12. 약관 버전 드롭다운 병렬 제공
13. 구버전 결과: 상단 amber 컨텍스트 바 1회 + 카드 좌측 amber border
14. 차등 경고: 현행과 내용 다를 때만 "현행 변경됨" 배지

### 보안
15. 날짜 서버사이드 검증: YYYY-MM 형식만 허용, 미래 날짜 차단, 범위 2000-01 ~ 현재
16. 단일 쿼리 = 단일 버전 (교차 컨텍스트 오염 방지)
17. 응답에 버전 워터마크 강제 삽입
18. 과거 버전 전용 rate limit: 분 5 / 시간 30 / 일 100
19. 유/무료 티어링: 베타 전체 개방, 유료 전환 시 과거 버전 접근 제한
20. 조회 로그 90일 후 user_id 익명화

### 비용 영향
- 저장 추가: ~$2/월 (무시 가능)
- 현행 검색 비용: 변동 없음 (분리 덕분)
- 과거 검색 비용: 월 500회 기준 ~$1.80/월
- Cold Storage 대안: 비현실적 (기각)

### 테스트 요구사항
- 전환일 경계값 테스트 (EDGE-002)
- 골든 테스트셋 200건 회귀 검증
- 재인덱싱 멱등성 테스트 (3회 연속)
- 실손 세대 전환 경계 쿼리 테스트

### 우선순위
- P0: TTL 제거 (archiveExpireAt 제거 + Firestore TTL 정책 해제)
- P0: targetDate 파라미터 + archive 검색 로직
- P1: 버전 목록 API + 프론트엔드 UI
- P1: 보안 (날짜 검증, rate limit, 워터마크)
- P2: chunkHash 임베딩 재사용
- P2: 별표 아카이브 버전 관리

---

## 다음 단계
- 이 설계를 1팀(헤르메스)에 위임하여 구현
- 파일 수정 범위: switch/route.ts, vector-search/route.ts, firestore.ts, SearchInput.tsx 등
- 2팀 담당 파일(firestore.indexes.json, firestore.rules)과 충돌 방지 주의

*작성: 아누 (개발실장) / 2026-03-03*
