# Plan: task-124.1 — InsuWiki 유튜브 자동요약 파이프라인 즉시조치+단기개선

## 작업 분석
유튜브 자동요약 파이프라인(`crawlYoutubeChannels.ts`)의 안정성/보안 이슈 5건 처리.
프로젝트 경로: `/home/jay/projects/insuwiki/`

## 서브태스크 분해 & 팀원 배정

### 즉시조치 1: 벡터인덱스 — 토르(백엔드)
- **문제**: `firestore.indexes.json`에 `insurance_chunks.embedding` 벡터 인덱스 미정의
- **영향**: vector-search API, 충돌감지 모두 실패 (console에서 수동 생성 필요)
- **조치**: `firestore.indexes.json`에 벡터 인덱스 정의 추가 (text-embedding-004 = 768차원, COSINE)
- **대상 파일**: `firestore.indexes.json`

### 즉시조치 2: 시크릿 — 토르(백엔드)
- **문제**: `run_pipeline.js:10`에 YouTube API 키 하드코딩 (`AIzaSyD...`)
- **영향**: Git 이력에 시크릿 노출, 키 로테이션 시 코드 수정 필요
- **조치**: 하드코딩 API 키 제거, .env.local에서만 읽도록 수정
- **대상 파일**: `functions/run_pipeline.js`

### 즉시조치 3: 타입 — 토르(백엔드)
- **문제**: `@ts-ignore`로 벡터 검색 타입 우회 (firebase-admin v11 → findNearest 미지원)
- **영향**: 타입 안전성 저하, 빌드 경고
- **조치**: @google-cloud/firestore 타입 augmentation 추가, any 타입 인터페이스화
- **대안 검토**: firebase-admin v12 업그레이드 → 파급 범위 크므로 기각. 타입 augmentation이 안전.
- **대상 파일**: `functions/src/crawlYoutubeChannels.ts`, `nextapp/src/app/api/ai/vector-search/route.ts`, 새 타입 파일

### 단기개선 1: 자막안정화 — 토르(백엔드)
- **문제**: 자막 다운로드 시 재시도 없음, 서명URL 만료 미처리
- **영향**: 일시적 네트워크 오류 시 자막 누락 → 품질 낮은 요약 생성
- **조치**: fetchYouTubeTranscript에 withBackoff 재시도 적용, 자막 파싱 정규식 보강
- **대상 파일**: `functions/src/crawlYoutubeChannels.ts`

### 단기개선 2: 에러로그 — 토르(백엔드)
- **문제**: console.* 만 사용, 파이프라인 실행 결과 추적 불가
- **영향**: 장애 시 원인 파악 어려움, 처리 결과 누적 데이터 없음
- **조치**: 파이프라인 실행 로그를 Firestore `pipeline_logs` 컬렉션에 저장, 실행별 결과 요약
- **대상 파일**: `functions/src/crawlYoutubeChannels.ts`

### 테스트 — 헤임달(테스터)
- TypeScript 컴파일 검증 (`tsc --noEmit` 또는 빌드)
- 변경 파일별 로직 검증

## 실행 순서
1. 토르: 즉시조치 3건 + 단기개선 2건 (모두 백엔드, 순차 의존 없음 → 병렬 가능)
2. 헤임달: 토르 결과물 검증

## 검토한 대안과 기각 사유
- firebase-admin v12 업그레이드: 다른 함수(ragQuery, pdfIndexing 등)에 breaking change 위험 → 기각
- winston/pino 로깅 프레임워크 도입: 단기개선 범위 초과, Cloud Functions는 console이 Cloud Logging으로 자동 전달됨 → 기각, Firestore 로그로 대체
- 자막 라이브러리(youtube-transcript 등) 도입: 외부 의존성 추가 위험 → 기각, 기존 HTML 파싱 보강

## 실패 시나리오 체크리스트

### 1. 비정상 입력/상태
- 벡터 인덱스 정의가 잘못된 dimension일 때? → text-embedding-004는 768차원 고정, 불일치 시 인덱스 빌드 실패하므로 명확한 에러 메시지 확인
- .env.local 파일이 없으면? → run_pipeline.js에 try-catch로 안내 메시지 출력

### 2. 동시성/경쟁 조건
- 크롤러가 동시에 2번 실행되면? → lastCrawledAt + 중복 체크(youtube_knowledge)로 중복 처리 방지 이미 구현됨
- pipeline_logs 동시 쓰기? → Firestore .add()는 자동 ID 생성으로 충돌 없음

### 3. 비정상 종료/타임아웃
- 자막 재시도 중 함수 타임아웃(540초)? → maxRetries를 2회로 제한, 실패 시 제목+설명 폴백 유지
- pipeline_logs가 불완전하게 남으면? → status: 'running' → 완료 시 'completed' 업데이트, 비정상 시 'running' 상태로 남음 (다음 실행 시 식별 가능)

### 4. 스테일 데이터
- 벡터 인덱스 빌드 지연 시? → 인덱스 생성 후 몇 분 소요. 그 동안 벡터 검색 fallback 처리 이미 있음 (catch로 스킵)
- pipeline_logs 무한 누적? → TTL 필드 추가하여 30일 후 자동 삭제 고려 (향후)

### 5. 통합 시 충돌
- firestore.indexes.json 변경이 기존 인덱스에 영향? → 벡터 인덱스는 신규 추가이므로 기존 인덱스 영향 없음
- 타입 augmentation이 다른 모듈 빌드에 영향? → functions와 nextapp는 별도 tsconfig, 영향 없음
