# 작업 보고: task-1098.1
- 팀: dev2-team (오딘)
- 작업 내용: YouTube 요약 파이프라인 서버 Python 구현

## SCQA

**S**: task-1094.1에서 Whisper GPU `/v1/youtube-transcribe` 엔드포인트 추가 완료, task-1095.1에서 에이전트 미팅을 통해 Cloud Functions 폐기 → 서버 Python 파이프라인 전환 합의가 이루어졌다.

**C**: 기존 Cloud Functions 파이프라인(`crawlYoutubeChannels.ts`, 918줄)은 localhost Whisper 호출 시 Cloudflare Tunnel 의존(SPOF), 540초 타임아웃 제한, 유지보수 복잡도 등 구조적 결함이 있어 서버 Python 파이프라인으로의 전환 구현이 필요하다.

**Q**: 6시간 크론 기반 서버 Python 파이프라인으로 YouTube 채널 신규 영상 감지 → 3-tier 전사 → Gemini 요약 → Drive 업로드 → Firestore 저장 → Telegram 보고까지의 전체 파이프라인을 구현할 수 있는가?

**A**: 7개 모듈 + 3개 테스트 파일로 전체 파이프라인을 구현 완료. pytest 25건 전체 통과, pyright 에러 0건. 기존 TS 파이프라인과 동일한 Firestore 스키마 호환 유지, Drive 폴더 구조 유지, 요약 프롬프트 재사용.

## 생성/수정 파일

**구현 모듈** (`/home/jay/projects/insuwiki/scripts/youtube-pipeline/youtube_pipeline/`):
- `__init__.py` — 패키지 초기화
- `config.py` (1,422B) — 환경변수, API 키, 서비스 설정
- `youtube_api.py` (3,301B) — YouTube Data API v3 채널/영상 조회
- `transcriber.py` (6,289B) — 3-tier 전사 (YouTube자막 → Whisper → 제목+설명)
- `summarizer.py` (4,315B) — Gemini 2.5 Flash 요약 + 임베딩 생성
- `drive_uploader.py` (5,038B) — Google Drive 업로드 (요약+전사+처리로그)
- `firestore_writer.py` (3,517B) — Firestore 저장 (youtube_knowledge, insurance_chunks)
- `main.py` (14,627B) — 파이프라인 오케스트레이터

**테스트** (`tests/`):
- `test_transcriber.py` — 12개 테스트 (3-tier 전사 로직)
- `test_summarizer.py` — 8개 테스트 (요약 생성, 임베딩, 재시도)
- `test_drive_uploader.py` — 5개 테스트 (파일명 안전화, 마크다운 생성, 중복 방지)

**설정**:
- `requirements.txt` — 의존성 (requests, google-generativeai, google-api-python-client, firebase-admin 등)
- `conftest.py` — pytest 경로 설정
- `pyrightconfig.json` — 타입 체크 설정

## 파이프라인 흐름

```
크론 6시간 → Whisper health check
→ Firestore youtube_channels에서 활성 채널 로드
→ 채널별: YouTube API uploads playlist → 신규 영상 감지 (lastCrawledAt 비교)
  → 영상별: 중복 체크 → 3-tier 전사 → Gemini 요약 (title_description 제외)
    → Drive 업로드 (요약+전사) → insurance_chunks 저장 → youtube_knowledge 저장
→ 처리 로그 Drive 업로드 → Telegram 보고
```

## 핵심 설계 결정
- **title_description fallback 영상**: 요약 생성 금지, insurance_chunks 저장 금지 (task 명세 준수)
- **승인 큐 없음**: 4단계 출처 신뢰 체계(policy>newsletter>wiki>youtube)에 의존
- **에러 격리**: 영상별 try/except로 개별 실패가 파이프라인 전체에 영향 없음
- **기존 호환**: Firestore 스키마, Drive 폴더 구조, 요약 프롬프트 모두 기존 TS 코드와 동일

## 테스트 결과

```
pytest: 25 passed, 1 warning (1.31s)
  - FutureWarning: google.generativeai deprecated → google.genai 전환 필요 (기능 영향 없음)
pyright: 0 errors, 0 warnings, 0 informations
black + isort: 적용 완료
```

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **youtube_api.py와 firestore_writer.py의 get_active_channels/update_last_crawled 중복** — main.py에서 youtube_api 버전 사용으로 통일, firestore_writer 버전은 독립 사용 가능하도록 유지
2. **Firestore Timestamp → datetime 변환** — `hasattr(last_crawled_at, 'timestamp')` 패턴으로 Firestore Timestamp 객체와 일반 datetime 모두 처리
3. **isort 프로파일 불일치** — QC 검증기와 로컬 isort 간 `--profile=black` 설정 차이로 발생, 프로파일 없이 재정렬하여 해결

### 범위 외 미해결 (2건)
1. **google.generativeai 라이브러리 deprecated** — 범위 외 사유: google.genai로의 마이그레이션은 별도 작업 필요 (현재 기능에 영향 없음)
2. **크론 등록 미수행** — 범위 외 사유: task 명세에 "파이프라인 스크립트 완성 후" 크론 등록이지만, E2E 테스트 후 등록이 안전. 실행 명령: `cd /home/jay/projects/insuwiki/scripts/youtube-pipeline && python -m youtube_pipeline.main`

## QC 자동 검증

```json
{
  "test_runner": "PASS (25 passed)",
  "pyright_check": "PASS (0 errors)",
  "file_check": "PASS (7/7 파일 확인)",
  "style_check": "PASS (black + isort)"
}
```
