# task-225.1 완료 보고서: ThreadAuto Phase 3 — Claude LLM 콘텐츠 생성 + 크롤러 + Firestore 파이프라인

## 작업 내용
AI 콘텐츠 생성 엔진 + 뉴스/랜딩페이지 크롤러 + Firestore 저장 파이프라인을 구현했다. RSS 7개 피드 수집, 보험업계 키워드 필터링, Claude CLI 기반 카드뉴스 텍스트 생성, Pillow 이미지 렌더링, Firestore 저장까지 전체 파이프라인을 구축했다.

### 구현 모듈

**1. 크롤러 (crawler/)**
- `rss_fetcher.py` — feedparser 기반 RSS 7개 피드(다자비, 뉴스와이어, 이투데이, 이데일리, 한경, 매경, 파이낸셜) 수집. 개별 피드 실패 시 나머지 계속 수집
- `keyword_filter.py` — 3단계 키워드(primary=3점, secondary=2점, tertiary=1점) 기반 보험업계 이직 관련 기사 필터링 및 점수 정렬
- `landing_page.py` — Playwright headless Chromium으로 incar-top1.tistory.com 랜딩페이지 크롤링. networkidle 대기 + 스크롤 시뮬레이션 + BeautifulSoup 구조화

**2. LLM 콘텐츠 생성 (content/)**
- `prompts.py` — TypeA~E 5가지 프롬프트 템플릿 (숫자훅/뉴스카드/비교카드/성공스토리/체크리스트). 금지사항, 톤앤매너, JSON 출력 형식 강제
- `generator.py` — Claude CLI (`claude -p`) subprocess 호출. timeout 60초, 실패 시 1회 재시도. 마크다운 코드블록 JSON 파싱
- `quality.py` — 금지 키워드 40개 검출, 자카드 유사도 중복 체크, 슬라이드 구조 검증, 히스토리 30건 FIFO 관리

**3. 파이프라인 (pipeline/)**
- `orchestrator.py` — 소재 수집 → 콘텐츠 생성 → 품질 검증 → 이미지 렌더링 → Firestore 저장 전체 파이프라인. run_single / run_batch 지원
- `scheduler_data.py` — 하루 10건 발행 스케줄 (08:00~21:30, TypeA~E 로테이션). 시간 조회, 다음 스케줄 탐색

**4. Firestore 연동 (storage/)**
- `firestore.py` — insuwiki-j2h 프로젝트 Firestore CRUD. ta_posts/ta_sources/ta_history 3개 컬렉션. Firebase 미연결 시 로컬 JSON 폴백 자동 전환
- `image_upload.py` — 로컬 모드(개발용 file:// URL) / GCS 모드(미구현 예약)

**5. CLI 확장**
- `crawl-news` — RSS 수집 + 키워드 필터링 결과 rich Table 출력
- `generate` — 소재 기반 콘텐츠 생성 (news/landing/manual 소스 지원)
- `pipeline` — 전체 파이프라인 실행 (단건/배치)

## 생성/수정 파일 목록

### 신규 생성
- `/home/jay/projects/ThreadAuto/crawler/__init__.py` — 패키지 초기화
- `/home/jay/projects/ThreadAuto/crawler/rss_fetcher.py` — RSS 피드 수집
- `/home/jay/projects/ThreadAuto/crawler/keyword_filter.py` — 키워드 필터링
- `/home/jay/projects/ThreadAuto/crawler/landing_page.py` — 랜딩페이지 크롤러
- `/home/jay/projects/ThreadAuto/content/__init__.py` — 패키지 초기화 + 공개 API
- `/home/jay/projects/ThreadAuto/content/generator.py` — Claude CLI 콘텐츠 생성
- `/home/jay/projects/ThreadAuto/content/prompts.py` — 프롬프트 템플릿 5종
- `/home/jay/projects/ThreadAuto/content/quality.py` — 품질 관리 + 히스토리
- `/home/jay/projects/ThreadAuto/pipeline/__init__.py` — 패키지 초기화
- `/home/jay/projects/ThreadAuto/pipeline/orchestrator.py` — 파이프라인 오케스트레이터
- `/home/jay/projects/ThreadAuto/pipeline/scheduler_data.py` — 발행 스케줄 데이터
- `/home/jay/projects/ThreadAuto/storage/__init__.py` — 패키지 초기화
- `/home/jay/projects/ThreadAuto/storage/firestore.py` — Firestore CRUD
- `/home/jay/projects/ThreadAuto/storage/image_upload.py` — 이미지 업로드
- `/home/jay/projects/ThreadAuto/tests/test_crawler.py` — 크롤러 테스트 32개
- `/home/jay/projects/ThreadAuto/tests/test_content.py` — 콘텐츠 생성 테스트 50개
- `/home/jay/projects/ThreadAuto/tests/test_pipeline.py` — 파이프라인 테스트 44개
- `/home/jay/projects/ThreadAuto/tests/test_landing_page.py` — 랜딩페이지 테스트 18개

### 수정
- `/home/jay/projects/ThreadAuto/cli.py` — crawl-news, generate, pipeline 3개 명령 추가
- `/home/jay/projects/ThreadAuto/requirements.txt` — feedparser, firebase-admin, beautifulsoup4, playwright 추가

## 테스트 결과
- **전체 209 passed / 0 failed** (2.02s)
  - 기존 Phase 1~2 테스트 65개: 전부 PASS
  - 신규 Phase 3 테스트 144개: 전부 PASS
    - test_crawler 32개, test_content 50개, test_pipeline 44개, test_landing_page 18개

## 버그 유무
- 발견된 버그 없음

## 완료 조건 충족 확인
1. RSS 7개 피드 크롤링 + 키워드 필터링: 구현 완료 (rss_fetcher + keyword_filter)
2. Claude CLI로 카드뉴스 텍스트 생성: 구현 완료 (generator + prompts)
3. 전체 파이프라인 1건 실행: 구현 완료 (orchestrator.run_single)
4. CLI 명령 3개: 구현 완료 (crawl-news, generate, pipeline)
5. 테스트 전체 PASS: 209개 전부 통과 (기존 65 + 신규 144)

## QC 자동 검증 결과
```json
{
  "task_id": "task-225.1",
  "overall": "PASS",
  "checks": {
    "api_health": "SKIP (서버 작업 아님)",
    "file_check": "18/18 파일 OK",
    "data_integrity": "PASS",
    "test_runner": "PASS — 209 passed in 2.02s"
  }
}
```

## 비고
- Phase 1~2 코드 수정 없음 — cli.py에 3개 명령, requirements.txt에 4개 의존성만 추가
- Claude CLI (`claude -p`) subprocess 호출만 사용, Anthropic SDK 직접 사용 안 함 (LLM 규칙 준수)
- Firestore는 firebase_admin SDK 미설치 시 로컬 JSON 폴백으로 자동 전환 (개발 환경 호환)
- Playwright 미설치 환경에서도 나머지 기능 정상 동작 (graceful ImportError 처리)
- Phase 4(Cloud Scheduler + Slack 모니터링) 연결 준비 완료
