DOCS/journey/troubleshooting/250908_skill_news_companyx_data_integration.md
Claude-51124 22557e7132 docs: 오래된 트러블슈팅 아카이브 및 구조 정리
- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동
- book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서)
- 빈 폴더 제거 (journey/assets/*)
2025-11-17 14:06:05 +09:00

3.4 KiB

Company-X 뉴스 데이터 통합 문제 해결

배경

  • 날짜: 2025-09-08
  • 문제: skill-news가 Company-X 뉴스를 수집하지만 본문과 요약이 없어 skill-publish가 홈페이지에 게시할 수 없음
  • 원인: companyx_news_collector.py가 제목/URL만 저장하고 스크래핑/요약 결과를 버림

문제 상황

1. 초기 증상

  • rb8001이 skill-news에서 Company-X 뉴스 15개 찾았지만 0개 전달받음
  • skill-publish가 받은 데이터에 summary, content, thumbnail_url 없음
  • Squarespace 홈페이지 게시 불가

2. 근본 원인

# 기존 companyx_history.json 구조 (문제)
{
  "articles": [
    {
      "url": "https://...",
      "title": "제목",
      "timestamp": "2025-09-07T15:38:56"
    }
  ]
}
  • 단순 중복 체크용으로만 사용
  • 스크래핑/요약 데이터 저장 안 함
  • 매번 동일 기사 재처리

3. company-x_hompage와의 차이

  • company-x_hompage: 3단계 JSON 파일로 전체 데이터 저장
  • skill-news: URL/제목만 저장하고 나머지 버림

해결 과정

1. 시간 파싱 기능 추가

def _parse_time_text(self, time_text: str) -> str:
    """Google News 시간 텍스트를 날짜 문자열로 변환 (YYYY-MM-DD)"""
    # "3일 전", "5시간 전" → "2025-09-05" 형식으로 변환

2. NewsArticle 모델 확장

time_text: Optional[str] = Field(None, description="원본 시간 텍스트")
found_at: Optional[datetime] = Field(None, description="실제 수집 시각")

3. companyx_news_posting.json으로 통합

# 새로운 구조 (company-x_hompage 형식)
{
  "keyword": "컴퍼니엑스",
  "last_updated": "2025-09-08T...",
  "total_count": 5,
  "articles": {
    "article_id": {
      "id": "article_id",
      "title": "제목",
      "publisher": "언론사",
      "parsed_date": "2025-09-05",
      "time_text": "3일 전",
      "found_at": "2025-09-08T...",
      "url": "https://...",
      "content": "본문 전체",
      "actual_url": "리다이렉트 후 URL",
      "thumbnail_url": "썸네일 URL",
      "scraped_at": "2025-09-08T...",
      "summary": "280-320자 요약",
      "summary_length": 285,
      "company_name": "COMPANY X",
      "summarized_at": "2025-09-08T...",
      "status": "summarized",
      "published_at": null,
      "published_by": null,
      "skipped_at": null,
      "skipped_by": null
    }
  }
}

4. 업데이트 메서드 구현

  • update_scraped_data(): 스크래핑 후 데이터 업데이트
  • update_summarized_data(): 요약 후 데이터 업데이트
  • 각 단계별로 기존 데이터에 추가 정보 누적

최종 결과

  • 하나의 companyx_news_posting.json 파일에 모든 데이터 통합
  • 수집 → 스크래핑 → 요약 → published/skipped 상태 관리
  • GET /api/news/google/companyx/{article_id} - rb8001이 필요시 조회
  • PATCH /api/news/google/companyx/{article_id} - status 업데이트

교훈

  1. 데이터 손실 방지: 비싼 연산(스크래핑/AI 요약) 결과는 반드시 저장
  2. 참조 구현 확인: company-x_hompage 같은 검증된 구현 참고
  3. 통합 테스트: rb8001 → skill-news → skill-publish 전체 파이프라인 테스트
  4. 환경변수 활용: 하드코딩 대신 환경변수로 설정 관리
  5. 단계별 상태 추적: collected → scraped → summarized 상태 관리