# 뉴스 브리핑 LangGraph 워크플로우 전환

**날짜**: 2026-02-02  
**작성자**: Claude  
**관련 파일**: `rb8001/app/services/skills/startup_news_skill.py`, `skill_news/app/services/sea_news_collector.py`  
**원칙 참조** (구현 전 필수 확인):
- `311_백엔드_구조_원칙.md`: LangGraph 워크플로우 (섹션 5), 계층 분리
- `312_문서_작성_원칙.md`: 핵심만 간결, 파일명:줄번호
- `315_테스트_원칙.md`: 테스트는 TDD로 진행 (Red → Green → Refactor)

---

## 1. 현재 문제

- **원칙 위반**: 뉴스 브리핑은 수집→필터→번역→포맷→전송 다단계 처리인데, 일반 함수로 구현되어 있음. 311 원칙 "복잡한 다단계 처리는 LangGraph 적극 활용" 위반.
- **추적성 부족**: 각 단계별 실패 지점, 중간 상태, 실행 시간 등이 로그에 체계적으로 남지 않음.
- **복구 불가**: 중간 단계 실패 시 처음부터 재실행해야 함 (체크포인트 없음).

---

## 2. LangGraph 전환 설계

### 2.1 상태 모델 (HeadlinesState)

| 필드 | 타입 | 설명 |
|------|------|------|
| channel_id | str | Slack 채널 ID |
| naver_items | List[Dict] | 깡프로 헤드라인 |
| sea_items | List[Dict] | 동남아 뉴스 |
| terms | Optional[List[str]] | 추출된 용어 |
| formatted_text | str | 최종 Slack 텍스트 |
| message_ts | Optional[str] | 전송된 메시지 ts |
| errors | List[str] | 각 단계 에러 |

### 2.2 노드 구성

1. **fetch_naver_node**: skill-news API 호출 → `naver_items` 반환
2. **fetch_sea_node**: skill-news SEA API 호출 → `sea_items` 반환 (실패 시 빈 리스트, 에러 기록)
3. **extract_terms_node**: Gemini로 용어 추출 → `terms` 반환 (환경변수 체크)
4. **format_node**: 깡프로 + 동남아 + 용어 섹션 조합 → `formatted_text` 반환
5. **send_node**: Slack 전송 → `message_ts` 반환 및 로그 기록

### 2.3 라우팅

```
START → fetch_naver → fetch_sea → extract_terms → format → send → END
```

- `fetch_sea` 실패 시에도 계속 진행 (graceful degradation)
- `extract_terms` 환경변수 false면 skip
- 각 노드 실패는 `errors` 리스트에 기록

### 2.4 체크포인터

- **AsyncSqliteSaver** 사용 (경량 워크플로우, 서버 재시작 시 재개 불필요)
- DB 경로: `/code/checkpoints/headlines_workflow.db`
- thread_id: `f"headlines_{channel_id}_{date}"`

---

## 3. Phase별 작업

### Phase 1: 워크플로우 파일 생성
- **파일**: `rb8001/app/services/workflows/headlines_workflow.py` (신규)
- **내용**: HeadlinesState, 5개 노드, StateGraph 정의

### Phase 2: startup_news_skill.py 리팩토링
- **기존**: `run_headlines_job()` 함수 → **변경**: LangGraph 워크플로우 호출
- **로그**: 각 노드별 실행 로그 + 최종 message_ts 로그

### Phase 3: 테스트 (TDD 진행, 315_테스트_원칙.md)
- **파일**: `rb8001/tests/test_headlines_workflow.py` (신규)
- **시나리오**: 
  - 정상 플로우 (깡프로 + 동남아 + 용어)
  - 동남아 실패 시 graceful degradation
  - 용어 추출 skip
  - message_ts 로그 확인

### Phase 4: 배포 및 검증
- **배포**: `git push origin main` (rb8001) → Gitea Actions 자동 배포
- **검증**: 내일 아침 09:10 스케줄 실행 시 로그에 노드별 실행 + message_ts 확인

---

## 4. 남은 작업

- [ ] `headlines_workflow.py` 생성 (LangGraph StateGraph)
- [ ] `startup_news_skill.py` 리팩토링 (워크플로우 호출)
- [ ] `test_headlines_workflow.py` 작성 (TDD 진행)
- [ ] 배포 및 스케줄 실행 검증

---

## 참고

- `book/300_architecture/311_백엔드_구조_원칙.md`
- `book/300_architecture/312_문서_작성_원칙.md`
- `book/300_architecture/315_테스트_원칙.md`
