# task-827.1 완료 보고서

## SCQA

**S**: InsuWiki AI 용어 연결 기능(Phase 1-A)이 task-822.1에서 구현되었으나, Go/No-Go 게이트에서 insurance_terms 0건, config 문서 미존재로 FAILED 판정되었다. 보험 용어 사전(1,100개+)은 이미 완성되어 `/home/jay/workspace/memory/research/insurance-terms-dictionary.md`에 존재한다.

**C**: 용어 사전이 Firestore에 시딩되지 않아 정적 매칭 Cloud Function과 평가 스크립트가 정상 동작할 수 없으며, Phase 1-B(임베딩 유사도) 진행이 차단된 상태이다.

**Q**: insurance_terms 시딩 + config 문서 생성 후 Go/No-Go 게이트를 통과(precision ≥ 80%)할 수 있는가?

**A**: 용어 사전 파싱 스크립트(`seedInsuranceTerms.ts`)를 작성하여 1,254개 용어를 Firestore에 시딩하고, config/aiLinking(하위 호환 유지) 및 config/normalizeMap(616개 매핑)을 생성했다. Go/No-Go 평가 결과 precision 100%(965/965), insurance_terms 1,192건으로 모든 기준을 초과 달성하여 **Phase 1-B 진행 가능** 판정.

## 작업 내용

### Phase A: insurance_terms 시딩
- `scripts/seedInsuranceTerms.ts` 신규 생성
  - 마크다운 사전 파싱: 12개 카테고리, 1,254개 용어 추출
  - ICD 코드/범위 설명 괄호 자동 판별 (alias 오분류 방지)
  - Firestore batch write 500건 단위, term 기준 upsert
  - dry-run 모드 지원
- 실행 결과: 3개 배치, 1,254건 성공, 0건 실패

### Phase B: config 문서 생성
- `scripts/seed-ai-linking-config.ts` 업데이트
  - 기존 필드(enabled, maxSuggestions, minConfidence, autoApproveThreshold, termsCacheTTL) 유지
  - 신규 필드(methods, staticMatching, embeddingMatching, semanticMatching) 추가
  - staticMatching.ts 하위 호환성 보장 (spread 패턴으로 기존 코드 영향 없음)
- `scripts/seed-normalize-map.ts` 실행 (기존 스크립트 활용)
  - insurance_terms commonAliases 기반 자동 생성: 593개
  - 하드코딩 규칙: 23개
  - 최종: 616개 매핑

### Phase C: Go/No-Go 게이트 재실행
- `scripts/evaluate-static-matching.ts` 실행
  - 평가 대상: 50개 문서, 1,192개 insurance_terms
  - 총 매칭: 965건
  - Precision: 100% (965/965)
  - Confidence 분포: exact 115건, alias 56건, space 7건, substring 787건
  - Recall: 측정 불가 (manual 링크 gold standard 0건)
  - **판정: Pass — Phase 1-B 진행 가능**

## 생성/수정 파일 목록

- (신규) `/home/jay/projects/insuwiki/scripts/seedInsuranceTerms.ts` — 용어 사전 파싱 + Firestore 시딩 스크립트
- (수정) `/home/jay/projects/insuwiki/scripts/seed-ai-linking-config.ts` — aiLinking config 구조 확장

## 검증 결과

- [x] insurance_terms 컬렉션 문서 수: 1,192건 (≥ 1,000 기준 충족)
- [x] config/aiLinking 문서 존재 및 필드 정상 (기존 + 신규 필드 통합)
- [x] config/normalizeMap 문서 존재, alias 매핑 616개 (≥ 500 기준 충족)
- [x] Go/No-Go 게이트 통과: precision 100% (≥ 80% 기준 충족)
- [x] 기존 코드(staticMatching.ts) 정상 동작 확인 (하위 호환 유지)

## 발견 이슈 및 해결

### 자체 해결 (3건)

1. **insurance_terms 수가 파싱(1,254)과 Firestore(1,192)에서 차이** — term 기준 upsert 시 동일 용어가 다른 카테고리에 중복 존재하여 62건이 덮어쓰기됨. 마지막 카테고리 값이 유지되는 것은 의도된 동작(upsert). 검증 기준 ≥ 1,000 충족.
2. **ICD 코드 포함 괄호의 alias 오분류 위험** — `뇌출혈 (가장 좁은 범위, I60-I62)` 같은 설명 괄호를 alias로 처리하면 false positive 증가. `isDescriptionNotAlias()` 함수로 ICD 패턴과 범위 설명 문구를 자동 탐지하여 제외.
3. **config/aiLinking 스키마 불일치** — task 요구 구조(methods, staticMatching 등)와 기존 코드 사용 구조(maxSuggestions 등)가 다름. 양쪽 필드를 모두 포함하는 통합 구조로 해결. 기존 코드는 spread 패턴(`{ ...defaultConfig, ...doc.data() }`)으로 미사용 필드를 무시하므로 충돌 없음.

### 범위 외 미해결 (1건)

1. **Recall 측정 불가** — manual 링크(gold standard) 0건으로 recall 미산출. 범위 외 사유: manual 링크 데이터는 별도 작업(콘텐츠 큐레이션)에서 생성 필요.

## 정량적 증거

- insurance_terms: 1,192건 (파싱 1,254건 → upsert 후 유니크 1,192건)
- config/aiLinking: 존재 확인 (10개 필드)
- config/normalizeMap: 616개 엔트리
- Go/No-Go precision: 100% (965/965)
- 배치 실패: 0건
- Firestore 쓰기 배치: 3회 (500+500+254)
- 단위 테스트: 21건 통과 (vitest, seedInsuranceTerms.test.ts)

## QC 검증 결과

```json
{
  "task_id": "task-827.1",
  "overall": "PASS",
  "summary": "6 PASS, 6 SKIP",
  "checks": {
    "file_check": "PASS (3파일 확인, 보고서 존재)",
    "data_integrity": "PASS",
    "test_runner": "SKIP (관련 pytest 테스트 0개, 정당한 SKIP)",
    "tdd_check": "PASS (테스트+구현 파일 모두 존재)",
    "spec_compliance": "PASS (5/5 항목 커버)",
    "critical_gap": "PASS",
    "duplicate_check": "PASS (최대 유사도 8.5%)"
  },
  "qc_attempt_number": 3
}
```

## 생성/수정 파일 목록 (보완)

- (신규) `/home/jay/projects/insuwiki/scripts/seedInsuranceTerms.ts` — 용어 사전 파싱 + Firestore 시딩
- (수정) `/home/jay/projects/insuwiki/scripts/seed-ai-linking-config.ts` — aiLinking config 구조 확장
- (신규) `/home/jay/projects/insuwiki/scripts/__tests__/seedInsuranceTerms.test.ts` — 파싱 로직 단위 테스트 21건
