# task-2272 완료 보고서: InsuRo markitdown 도입

**S**: InsuRo의 소식지/보험료 데이터 업로드 시 PDF/PPTX 파싱에 auto, table, vision 3가지 모드를 지원하고 있다.

**C**: PPTX 표 구조 변환 시 기존 방식(claude CLI, pdfplumber)은 정확도가 낮고 코드가 복잡하다. Microsoft markitdown(MIT 라이선스)은 PDF/PPTX/Excel/HTML 등을 구조 보존 Markdown으로 변환하여 파싱 정확도를 향상시킬 수 있다.

**Q**: markitdown을 4번째 파싱 모드로 도입하고, auto 모드에서도 우선 시도하도록 통합할 수 있는가?

**A**: markitdown v0.1.5를 설치하고, 서버/프론트 양쪽에 "markitdown" 파싱 모드를 추가 완료. auto 모드에서 markitdown을 먼저 시도하고 실패 시 기존 로직으로 폴백하도록 구현. npm build 성공, pytest 186/187 통과 (1건 간헐 실패는 기존 이벤트루프 이슈로 본 작업 범위 외), 서버 정상 기동 확인.

---

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| server/requirements.txt:24 | markitdown[pdf,pptx]>=0.1.0 추가 | grep "markitdown" OK (1줄) | verified |
| server/main.py:145 | ParsePremiumFileRequest.parse_mode에 "markitdown" 옵션 추가 | grep "markitdown" OK (7줄) | verified |
| server/main.py:4007 | parse_mode == "markitdown" 분기 추가 (MarkItDown 변환 + 메타데이터 추출) | grep "markitdown" OK | verified |
| server/main.py:4107 | auto 모드에서 markitdown 우선 시도 (100자 초과 시 사용, 실패 시 폴백) | grep "markitdown" OK | verified |
| src/pages/AdminPremiumData.tsx:73 | useState 타입에 "markitdown" 유니온 추가 | grep "markitdown" OK (2줄) | verified |
| src/pages/AdminPremiumData.tsx:506 | MarkItDown 변환 라디오 버튼 추가 | grep "markitdown" OK | verified |
| src/pages/AdminNewsletters.tsx:65 | parseMode state 추가 | grep "parseMode" OK (7줄) | verified |
| src/pages/AdminNewsletters.tsx:111 | formData에 parse_mode 전달 | grep "parse_mode" OK | verified |
| src/pages/AdminNewsletters.tsx:433 | 파싱 모드 라디오 UI 추가 (4가지 옵션) | grep "markitdown" OK | verified |
| server/tests/test_markitdown_mode.py | markitdown 파싱 모드 단위 테스트 8건 추가 | pytest 8 passed | verified |

## 테스트 결과

- **npm run build**: 성공 (12.55s, dist 생성 확인)
- **Python compile**: main.py 문법 검증 통과
- **pytest (전체)**: 186 passed, 1 failed (기존 간헐 실패, 단독 실행 시 통과)
- **pytest (markitdown)**: test_markitdown_mode.py 8 passed (0.59s)
- **markitdown import**: v0.1.5 정상 import 확인
- **빌드 결과 검증**: AdminPremiumData-D1hl785l.js, AdminNewsletters-CCJdYuJq.js에 markitdown 코드 포함 확인

## L1 스모크테스트 결과

- 서버 재시작: 성공 (포트 8002에서 기동, /api/status 200 OK 응답)
- API 응답 확인: `curl http://localhost:8002/api/status` → `{"status":"ok"}` 확인
- 스크린샷: Admin 페이지는 인증 필요로 Playwright 직접 확인 불가. 빌드 산출물(dist JS 파일) grep으로 markitdown 코드 포함 검증 완료

## 발견 이슈 및 해결

### 자체 해결 (2건)
1. **Pyright markitdown import 경고** — 런타임 lazy import (try/except) 패턴 사용으로 설치 여부에 무관하게 동작. Pyright 경고는 정상 (미설치 환경에서의 정적 분석 한계)
2. **TypeScript parseMode 미사용 경고 (AdminNewsletters.tsx)** — LSP 캐시 이슈로 추정. 실제로는 111줄(formData), 441-462줄(라디오 UI)에서 사용 중. npm build 성공으로 실제 에러 없음 확인

### 범위 외 미해결 (1건)
1. **pytest 간헐 실패 (TestGenerateStubEndpoint::test_generate_stub)** — 범위 외 사유: 기존 이벤트루프 격리 이슈. 단독 실행 시 통과, 전체 실행 시 간헐 실패. 본 작업 변경과 무관

## 머지 판단

- **머지 필요**: Yes
- **브랜치**: task/task-2272-dev2
- **워크트리 경로**: /home/jay/projects/InsuRo/.worktrees/task-2272-dev2
- **머지 의견**: npm build 성공, pytest 186/187 통과, 서버 정상 기동. markitdown 로직은 기존 코드와 독립적이며 폴백 처리 완비. 충돌 가능성 낮음

## 모델 사용 기록

- 토르(백엔드): sonnet — main.py + requirements.txt 수정
- 프레이야(프론트엔드): sonnet — AdminPremiumData.tsx + AdminNewsletters.tsx 수정
- 헤임달(테스터): sonnet — test_markitdown_mode.py 테스트 작성
- 오딘(팀장): opus — 설계/분배/검토/통합

## QC 셀프체크

- [x] 1. 영향 파일 목록 명시 (위 수정 파일 테이블 참조)
- [x] 2. 엣지 케이스: markitdown 미설치 시 폴백, 변환 실패 시 None 반환
- [x] 3. 작업 지시와 정확히 일치 (4개 파일 수정, 파싱 모드 추가)
- [x] 4. 에러 처리: try/except + logger.warning, 임시파일 cleanup
- [x] 5. 테스트: pytest 186/187, npm build 성공
- [x] 6. 발견 이슈 모두 해결 또는 범위 외 사유 명시
- [x] 7. 코드 아키텍처 원칙: 기존 parse_mode 분기 패턴 준수, 새 분기 추가
- [x] 8. 인터페이스 변경: parse_mode에 "markitdown" 값 추가 (하위 호환)
- [x] 13. L1 스모크테스트: 서버 기동 + API 200 OK 확인

## Gemini PR 리뷰

- PR: https://github.com/JonghyukJeon/InsuRo/pull/56
- Gemini 리뷰: PASS (High 0건, Medium 3건 DEFER)
- 머지 완료

## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회

