# Task-514: Docling 파싱 캐시 + 한국어 FTS 고도화 (TODO #1 + #2)

## 목표
2건의 TODO 백로그를 한번에 해결한다.
1. Docling 처리 속도 문제 → 파싱 결과 캐싱으로 해결
2. 한국어 키워드 검색 정확도 → pg_bigm 또는 n-gram 기반 한국어 FTS

## 구현 범위

### 1. Docling 파싱 결과 캐시 (TODO #1)
- 경로: `/home/jay/workspace/libs/doc_parser.py` 수정
- **캐시 전략**: content_hash(SHA-256) 기반 로컬 파일 캐시
  - 캐시 디렉토리: `/home/jay/workspace/libs/.parse_cache/`
  - 키: content_hash (파일 바이트의 SHA-256)
  - 값: ParseResult를 JSON으로 직렬화/역직렬화
  - TTL: 없음 (동일 파일은 항상 같은 결과)
- `parse_pdf(file_bytes)` 호출 시:
  1. content_hash 계산
  2. 캐시에 존재하면 즉시 반환 (0.01초)
  3. 캐시에 없으면 Docling 파싱 후 결과 저장 (48초)
- `parse_pdf(file_bytes, use_cache=True)` — 기본값 True, False로 강제 재파싱 가능
- `clear_cache()` — 캐시 전체 삭제 함수
- **테스트**: 캐시 히트/미스, 강제 재파싱, clear_cache, 다른 파일은 다른 캐시

### 2. 한국어 FTS 고도화 (TODO #2)
- **방법 A (권장)**: n-gram 기반 GIN 인덱스
  - Supabase에서 pg_bigm 확장 사용 가능 여부 먼저 확인
  - 사용 가능하면: `CREATE INDEX ... USING gin (content gin_bigm_ops);`
  - 사용 불가면: pg_trgm (trigram) 인덱스로 대체 `CREATE INDEX ... USING gin (content gin_trgm_ops);`
  - trigram도 한국어 부분 매칭 지원 (정확한 형태소 분석은 아니지만 "보험" → "보험설계사" 매칭 가능)

- **SQL 마이그레이션 파일 추가**: `/home/jay/workspace/libs/migrations/002_korean_fts.sql`
  - pg_trgm 확장 활성화: `CREATE EXTENSION IF NOT EXISTS pg_trgm;`
  - GIN trigram 인덱스 추가: knowledge_chunks.content
  - hybrid_search() 함수 수정: 'simple' → pg_trgm 기반 유사도 검색으로 개선
  - `similarity(content, query_text)` 또는 `content % query_text` 사용

- **search.py 수정**: keyword_search 내부 로직 개선
  - 기존: `plainto_tsquery('simple', query_text)` — 단순 토큰 분리
  - 개선: trigram 유사도 기반 또는 LIKE '%query%' fallback 추가
  - 한국어 검색 테스트: "보험설계사", "금소법", "청약철회" 등

- **테스트**: 한국어 키워드 검색 mock 테스트

## 테스트
- doc_parser.py 캐시 관련 테스트 (최소 5건)
- 한국어 FTS SQL 문법 검증
- 기존 테스트 전부 통과 확인: `cd /home/jay/workspace/libs && python -m pytest tests/ -v`

## 주의사항
- doc_parser.py의 기존 인터페이스(parse_pdf, parse_document, ParseResult) 변경 금지
- 캐시는 선택적 (use_cache=False로 끌 수 있어야 함)
- 캐시 디렉토리는 .gitignore에 추가
- SQL 마이그레이션은 파일만 생성 (Supabase에 직접 실행하지 말 것)
- search.py 수정 시 기존 테스트 통과 필수
