[WATCH-01] ML: 뉴스 데이터 고도화 (링크·번역·per-headline 감성·요약)

작업 내용 (설계 의도)

변경 사항

news.py가 헤드라인 제목 문자열 목록만 반환하는 구조를 Headline 데이터 클래스(title·url·translated_title·sentiment) 목록 + 전체 요약 문자열로 교체한다. claude -p 단일 배치 호출로 요약·번역·per-item 감성을 한 번에 처리한다. Signal 응답 shape이 변경되므로 FE 타입 동기화 필요(WATCH-04 선행).

다이어그램

처리 흐름

sequenceDiagram
    participant S as signal_service
    participant N as news.py
    participant H as headlines.py
    participant A as sentiment.py
    S->>N: fetch_headlines_v2(query, market, limit)
    N->>H: _google_news / _gdelt with URLs
    H-->>N: list[{title,url}]
    N-->>S: list[{title,url}]
    S->>A: analyze_headlines_v2(headlines, market)
    A->>A: claude -p (요약+번역+per-item 감성)
    A-->>S: HeadlineAnalysis(headlines, summary)

클래스 의존

flowchart LR
    signal_service --> news.py
    signal_service --> sentiment.py
    news.py --> headlines.py
    sentiment.py --> subprocess["subprocess\n(claude -p)"]

테스트 케이스

  • _google_news_with_url{title, url} 쌍을 반환한다
  • _gdelt_with_url{title, url} 쌍을 반환한다
  • KR 시장 헤드라인은 translated_title이 원문과 동일하다
  • US 시장 헤드라인은 translated_title이 한국어로 번역된다
  • claude 응답 파싱 실패 시 원문을 translated_title로 사용하고 sentiment"중립"이 된다
  • 빈 헤드라인 목록 전달 시 summary가 빈 문자열이고 items가 빈 목록이다
  • build_signal이 새 HeadlineAnalysis 타입을 Signal.headlines에 바인딩한다