# InsuRo PDF 스마트 분석 — 텍스트/Vision 하이브리드 분기

## 작업 레벨: Lv.2

## 프로젝트 시스템 3문서
- DevSystem: `/home/jay/workspace/memory/plans/anu-guide-system/plan.md`

## 프로젝트
- InsuRo: `/home/jay/projects/InsuRo`
- 서버: `/home/jay/projects/InsuRo/server`

## 배경
소식지/보험료 PDF에 이미지 기반 표/그래프가 많아 pdfplumber로 텍스트 추출 실패. 전체 PDF를 Vision 처리하면 Max200 낭비. 페이지별 스마트 분기 필요.

## ★ 2단계 스마트 판정 로직

### 1차: 텍스트 양 필터 (pdfplumber)
```python
for page in pdf.pages:
    text = page.extract_text() or ""
    char_count = len(text.strip())
    
    if char_count < 50:
        # 거의 빈 페이지 → Vision 필요
        vision_pages.append(page_num)
    elif char_count >= 500:
        # 텍스트 충분 → 그대로 사용
        text_results.append(text)
    else:
        # 50~500자 → 2차 품질 검증
        quality_check_pages.append((page_num, text))
```

### 2차: 텍스트 품질 검증 (50~500자 구간)
```python
import re

def has_meaningful_data(text: str) -> bool:
    """보험 문서에서 의미 있는 데이터가 추출됐는지 판단"""
    # 금액 패턴 (₩, 만원, 천원, 억, 원)
    money_pattern = r'[\d,]+\s*(?:만원|천원|억|원|만|₩)'
    # 퍼센트 패턴
    pct_pattern = r'[\d.]+\s*%'
    # 숫자가 3개 이상 포함
    numbers = re.findall(r'\d+', text)
    
    has_money = bool(re.search(money_pattern, text))
    has_pct = bool(re.search(pct_pattern, text))
    has_numbers = len(numbers) >= 3
    
    return has_money or has_pct or has_numbers

def has_table(page) -> bool:
    """pdfplumber로 표 추출 가능한지 확인"""
    tables = page.extract_tables()
    return len(tables) > 0 and any(len(t) > 1 for t in tables)

for page_num, text in quality_check_pages:
    if has_meaningful_data(text) or has_table(pdf.pages[page_num]):
        text_results.append(text)  # 텍스트 신뢰
    else:
        vision_pages.append(page_num)  # Vision 필요
```

### 3단계: Vision 처리 (필요한 페이지만)
```python
if vision_pages:
    # PDF → 이미지 변환 (해당 페이지만)
    from pdf2image import convert_from_bytes
    images = convert_from_bytes(pdf_bytes, first_page=p+1, last_page=p+1)
    
    # Claude CLI에 이미지 전달
    img_path = f"/tmp/pdf_page_{p}.png"
    images[0].save(img_path)
    
    result = subprocess.run(
        ["claude", "-p", f"{img_path} 파일을 읽고 이 보험 문서 페이지의 모든 텍스트, 숫자, 표 내용을 추출해줘. JSON 없이 텍스트만.",
         "--model", "haiku", "--allowedTools", "Read", "--output-format", "text"],
        capture_output=True, text=True, timeout=60
    )
    vision_results.append(result.stdout)
```

### 최종 결과 합산
```python
# 페이지 순서대로 텍스트 + Vision 결과 합산
all_text = "\n\n".join(ordered_results)
```

## 의존성
- `pdf2image`: PDF → 이미지 변환 (poppler-utils 필요)
- `pip install pdf2image` + `apt install poppler-utils`

## affected_files
- `server/main.py` (수정 — _smart_parse_file 함수 교체)

## 검증 시나리오
1. 텍스트 PDF 업로드 → pdfplumber만으로 추출 (Vision 미호출)
2. 이미지 기반 PDF 업로드 → 해당 페이지만 Vision 처리
3. 혼합 PDF (텍스트 + 이미지 페이지) → 페이지별 분기 동작
4. 보험료 표가 포함된 PDF → 금액/퍼센트 패턴 감지 → 텍스트 신뢰
5. 서버 재시작 후 정상 동작
