plans: 동남아 뉴스 계획 100% 완성

- API 연동 추가 (skill-news POST /api/news/sea/headlines, rb8001 fetch_sea_headlines)
- 배포 순서 명시 (skill-news → rb8001, 의존성)
- 로깅 전략 추가 (311 원칙 섹션 11)
- 테스트 계획 보강 (API 통합 테스트)
- 180줄 (200줄 이하 원칙 준수)
This commit is contained in:
Claude-51124 2026-01-29 10:27:15 +09:00
parent 33c52f800a
commit 87a8dc175f

View File

@ -75,39 +75,47 @@ SEA_NEWS_DAYS_BACK=1
- 프롬프트: "Translate the following news title to Korean. Return only the translated title without explanation: {title}" - 프롬프트: "Translate the following news title to Korean. Return only the translated title without explanation: {title}"
- 3건 배치 처리 (단일 호출로 통합, 311 원칙 섹션 14) - 3건 배치 처리 (단일 호출로 통합, 311 원칙 섹션 14)
### 3.4 포맷 (skill-news) ### 3.4 포맷 및 중복 제거
**신규 함수**: `skill_news/app/services/sea_news_service.py` `format_sea_news_for_slack()` **신규 파일**: `skill_news/app/services/sea_news_service.py`
- `format_sea_news_for_slack()`: `naver_startup_news_service.py:333-343` 패턴 참조
**참조**: `naver_startup_news_service.py:333-343` 포맷 로직 - 중복 제거: `companyx_news_collector.py:396-413` 패턴 (URL + 제목 기준)
```python - 이력 관리: `skill_news/data/sea_news_posting.json` (날짜, URL, 제목)
lines = ["", "", "*동남아 소식*", ""]
for i, article in enumerate(articles[:3], 1):
lines.append(f"{i:02d}. <{article.url}|{article.title_ko}>")
```
### 3.5 중복 제거 및 이력 관리
**파일**: `skill_news/data/sea_news_posting.json`
**참조**: `companyx_news_collector.py:396-413` 중복 제거 패턴
- URL + 제목 기준 중복 확인
- 전송 이력 저장 (날짜, URL, 제목)
--- ---
## 4. Phase 및 필요 작업 ## 4. API 연동 (rb8001 ↔ skill-news)
### 4.1 skill-news 신규 엔드포인트
**파일**: `skill_news/app/router/news_endpoints.py`
**엔드포인트**: `POST /api/news/sea/headlines` (참조: `/api/news/naver/startup-headlines`)
**응답**: `{ "success": true, "count": 3, "items": [...], "text": "*동남아 소식*\n\n01. <url|제목>..." }`
### 4.2 rb8001 수정
| 파일 | 수정 내용 |
|------|----------|
| `skill_commands.py:223` | `fetch_sea_headlines()` 신규 추가 (`fetch_naver_headlines()` 패턴 복사) |
| `startup_news_skill.py:11-93` | `run_headlines_job()`에서 동남아 뉴스 호출 + 섹션 삽입 (명언 앞, `:67-76` 패턴) |
**에러 핸들링**: 동남아 수집 실패 시 `try-except`로 생략, 깡프로만 전송
---
## 5. Phase 및 필요 작업
| Phase | 필요 작업 | | Phase | 필요 작업 |
|-------|-----------| |-------|-----------|
| **Phase 1** | `skill_news/app/services/sea_news_collector.py` 신규 생성. `google_news_collector.py:55-91` 패턴 복사 후 키워드·지역 파라미터 변경. 환경변수 `.env``SEA_NEWS_*` 추가. | | **Phase 1** | **skill-news**: `sea_news_collector.py` 신규 생성. `google_news_collector.py:55-91` 패턴 복사, 키워드·지역(`hl=en&gl=SG`) 변경. `.env``SEA_NEWS_*` 추가. |
| **Phase 2** | `skill_news/app/services/sea_news_filter.py` 신규 생성. 기회 키워드 매칭 + 본문 검증 + LLM 제목 번역(Gemini, 3건 배치). `sea_news_service.py``format_sea_news_for_slack()` 추가. | | **Phase 2** | **skill-news**: `sea_news_filter.py` + `sea_news_service.py` 신규 생성. 기회 키워드 매칭 + 본문 검증 + LLM 번역(Gemini, 3건 배치) + Slack 포맷. |
| **Phase 3** | `rb8001/app/services/skills/startup_news_skill.py:11-93` `run_headlines_job` 수정. 깡프로 텍스트 생성 후 동남아 섹션 삽입. 삽입 위치: 명언(`>` 시작) 앞 2줄. `startup_news_skill.py:37-52` 키워드 섹션 삽입 로직 참고. | | **Phase 3** | **skill-news**: `news_endpoints.py``POST /api/news/sea/headlines` 추가. |
| **Phase 4** | 기존 daily_headlines 스케줄 유지(09:10). 동남아 수집 실패 시 `try-except`로 동남아 섹션만 생략, 깡프로만 전송. | | **Phase 4** | **rb8001**: `skill_commands.py``fetch_sea_headlines()` 추가. `startup_news_skill.py` `run_headlines_job()`에서 동남아 섹션 삽입 로직 추가. |
| **Phase 5** | **배포**: skill-news 먼저 배포 (`git push`) → rb8001 배포 (`git push`). 순서 중요 (의존성). |
--- ---
## 5. 테스트 계획 ## 6. 테스트 계획
**315 원칙 준수**: pytest 자동 테스트, conftest.py fixtures 사용 **315 원칙 준수**: pytest 자동 테스트, conftest.py fixtures 사용
@ -116,6 +124,7 @@ for i, article in enumerate(articles[:3], 1):
| 수집 단위 테스트 | `skill_news/tests/test_sea_news_collector.py` | 키워드 검색, 24시간 필터, NewsArticle 반환 확인 | | 수집 단위 테스트 | `skill_news/tests/test_sea_news_collector.py` | 키워드 검색, 24시간 필터, NewsArticle 반환 확인 |
| 선별 단위 테스트 | `skill_news/tests/test_sea_news_filter.py` | 기회 키워드 매칭, 본문 검증, LLM 번역 모킹 | | 선별 단위 테스트 | `skill_news/tests/test_sea_news_filter.py` | 기회 키워드 매칭, 본문 검증, LLM 번역 모킹 |
| 포맷 단위 테스트 | `skill_news/tests/test_sea_news_service.py` | `01. <url\|제목>` 형식 확인 | | 포맷 단위 테스트 | `skill_news/tests/test_sea_news_service.py` | `01. <url\|제목>` 형식 확인 |
| API 통합 테스트 | `skill_news/tests/test_sea_news_endpoint.py` | `POST /api/news/sea/headlines` 응답 확인 |
| 연동 E2E 테스트 | `rb8001/tests/e2e/test_sea_news_headlines.py` | 깡프로 + 동남아 섹션 통합 Slack 메시지 확인 | | 연동 E2E 테스트 | `rb8001/tests/e2e/test_sea_news_headlines.py` | 깡프로 + 동남아 섹션 통합 Slack 메시지 확인 |
**conftest.py fixtures**: **conftest.py fixtures**:
@ -125,7 +134,21 @@ for i, article in enumerate(articles[:3], 1):
--- ---
## 6. 주의사항 (트러블슈팅 교훈) ## 7. 로깅 전략
**311 원칙 섹션 11**: INFO(시작/종료), DEBUG(중간 과정)
| 단계 | 로그 레벨 | 메시지 예시 |
|------|----------|------------|
| 수집 시작 | INFO | `동남아 뉴스 수집 시작: keywords={keywords}` |
| 수집 완료 | INFO | `동남아 뉴스 수집 완료: {count}개` |
| 선별 과정 | DEBUG | `기회 키워드 매칭: {title} → score={score}` |
| 번역 | INFO | `제목 번역 완료: {count}건` |
| 실패 | WARNING | `동남아 뉴스 수집 실패 (생략): {error}` |
---
## 8. 주의사항 (트러블슈팅 교훈)
| 교훈 | 출처 | 적용 | | 교훈 | 출처 | 적용 |
|------|------|------| |------|------|------|
@ -133,10 +156,11 @@ for i, article in enumerate(articles[:3], 1):
| OOM → 리소스 경합 | `250908_headline_failure_memory_error.md` | 깡프로(09:10) 이후 동남아 수집 (동일 job 내 순차 처리) | | OOM → 리소스 경합 | `250908_headline_failure_memory_error.md` | 깡프로(09:10) 이후 동남아 수집 (동일 job 내 순차 처리) |
| 좀비 프로세스 | `250904_admin_skill-news_zombie_process_gitea_actions.md` | docker-compose.yml `init: true` 확인 | | 좀비 프로세스 | `250904_admin_skill-news_zombie_process_gitea_actions.md` | docker-compose.yml `init: true` 확인 |
| 워크스페이스별 토큰 분리 | `250909_slack_briefing_failure.md` | `COMPANYX_SLACK_BOT_TOKEN` 사용 확인 | | 워크스페이스별 토큰 분리 | `250909_slack_briefing_failure.md` | `COMPANYX_SLACK_BOT_TOKEN` 사용 확인 |
| API 엔드포인트 확인 필수 | `250914_happybell80_깡프로뉴스_용어추출_기능추가.md` | skill-news API 스펙 먼저 확인 |
--- ---
## 7. 참고 파일 ## 9. 참고 파일
| 파일 | 참조 내용 | | 파일 | 참조 내용 |
|------|----------| |------|----------|
@ -144,6 +168,8 @@ for i, article in enumerate(articles[:3], 1):
| `skill_news/app/services/google_news_collector.py:100` | URL 파라미터 (when:Nd) | | `skill_news/app/services/google_news_collector.py:100` | URL 파라미터 (when:Nd) |
| `skill_news/app/services/companyx_news_collector.py:396-413` | 중복 제거 패턴 | | `skill_news/app/services/companyx_news_collector.py:396-413` | 중복 제거 패턴 |
| `skill_news/app/services/naver_startup_news_service.py:333-343` | Slack 포맷 (`01. <url\|제목>`) | | `skill_news/app/services/naver_startup_news_service.py:333-343` | Slack 포맷 (`01. <url\|제목>`) |
| `skill_news/app/router/news_endpoints.py` | 기존 `/api/news/naver/*` 엔드포인트 패턴 |
| `rb8001/app/commands/skill_commands.py:223-250` | `fetch_naver_headlines()` 패턴 |
| `rb8001/app/services/skills/startup_news_skill.py:11-93` | run_headlines_job 구조 | | `rb8001/app/services/skills/startup_news_skill.py:11-93` | run_headlines_job 구조 |
| `rb8001/app/services/skills/startup_news_skill.py:37-52` | 섹션 삽입 로직 (명언 앞) | | `rb8001/app/services/skills/startup_news_skill.py:67-76` | 섹션 삽입 로직 (명언 앞) |
| `DOCS/book/500_business/560_컴퍼니엑스_개요.md` | 컴퍼니엑스 투자 분야 | | `DOCS/book/500_business/560_컴퍼니엑스_개요.md` | 컴퍼니엑스 투자 분야 |