# [InfoKeyword] 홍보성 판단 로직 개선 — 네이버 단축URL 위장광고 감지 + 이미지 전화번호/전체항목 표시

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "worker/analyzer/external_links.py"
    - "worker/crawler/blog_content.py"
    - "worker/pipeline/analyzer.py"
    - "worker/analyzer/image_analysis.py"
    - "worker/analyzer/phone_address.py"
    - "worker/**/tests/**"
    - "tests/**"
  forbidden_paths:
    - ".env"
    - ".env.*"
    - ".github/**"
  commands:
    - "pytest"
    - "python3 -m py_compile"
    - "python3 -c"
    - "curl"
  merge_policy: "tiered"
  ttl_hours: 48
```

## 프로젝트
- 경로: `/home/jay/projects/InfoKeyword` (Next.js 프론트 + `worker/` FastAPI 분석 엔진)
- 이 worker(포트 8100)는 InsuRo(insuro.biz) 정보성키워드 기능도 호출하므로, 수정은 **양쪽에 반영**된다.

## 배경 (회장 피드백 — 블로그 TOP10 홍보성 진단 오류 2건)
"치매" 키워드 블로그 TOP10 진단에서:
- **Top2 "뉴히어로"**: 이미지에 외부 광고링크가 걸렸는데 **정보성으로 오판**(홍보성 미감지)
- **Top7 "보험디테일"**: 이미지에 전화번호가 보이는데 외부링크 signal만 뜨고 전화번호는 미감지. 홍보성 판정은 맞지만 **걸린 항목이 다 표시되길 원함**

## 근본 원인 (ANU 확정 — 재현 완료, 재확인 불필요)

### 원인 A (Top2) — `_is_naver_internal`이 회장 기준보다 과도하게 넓음
- 실제 재현: `https://blog.naver.com/newhero101/224368161108` 의 이미지 링크가 SmartEditor `data-linkdata`(linkUse=true)에 **`https://m.site.naver.com/2dtWW`** 로 심겨 있음.
- 이 단축 URL을 리다이렉트 추적하면(308) **최종 `https://dementiac.bohumclick.com/?adins_no=12101`** (광고 랜딩).
- 그런데 `worker/analyzer/external_links.py`의 `_is_naver_internal()`이 **`domain.endswith(".naver.com")` 이면 무조건 내부로 제외** → `m.site.naver.com`(네이버 단축URL 서비스)까지 내부로 처리 → external_links 비어짐 → 홍보성 신호 0 → **정보성 오판**.
- **이는 회장이 정한 기준(아래)과 불일치**. 블로거가 광고링크를 네이버 단축URL로 위장한 케이스를 놓친다.

**★ 회장이 정한 기준 (단일 소스: `memory/specs/infor-keyword/requirements-v1.md` §ii, §iii — verbatim)**:
- **ii) 외부링크**: 네이버 외부로 나가는 링크 = 홍보성. **예외(홍보 아님)는 오직**: ⓐ 블로그 **작성자 본인** 블로그 내 다른 글 링크 ⓑ 공익 사이트(`*.go.kr` / `*.or.kr`)
- **iii) 네이버 관련 링크**: 네이버 톡톡·플레이스 = **홍보성**. **예외는 `expert.naver.com`(엑스퍼트)뿐**.
- → 즉 네이버 링크 예외는 **딱 3종(본인블로그 / expert.naver.com / 공익)**. 그 외 모든 `*.naver.com`(특히 `m.site.naver.com`·`naver.me` 단축URL, 스마트스토어/쇼핑 등)은 내부로 뭉뚱그려 제외하면 안 된다.

### 원인 B (Top7) — 이미지 전화번호 미감지 + signal 부분 표시
- `worker/analyzer/image_analysis.py::analyze_blog_images`(Playwright 스크린샷 → 자체 LLM 멀티모달)가 이미지 속 전화번호를 놓침.
- `analyzer.py`가 홍보성으로 걸린 signal 중 일부만 노출되는 것으로 관측됨 → **걸린 항목 전부**가 결과에 나타나야 함.

## 목표 (수정 방향)

1. **`_is_naver_internal` 교정 (회장 기준 정확 반영)** — 네이버 도메인 중 내부/예외로 인정하는 것은 **①작성자 본인 블로그(blog.naver.com/<작성자>) ②`expert.naver.com` ③`*.go.kr`/`*.or.kr`** 로 한정. `m.site.naver.com`·`naver.me` 등 **네이버 단축URL 서비스는 예외에서 제외**한다. (톡톡/플레이스는 기존대로 홍보성 유지)
2. **단축URL 리다이렉트 추적** — `m.site.naver.com`·`naver.me` 등 단축 링크는 **HEAD/GET 리다이렉트를 따라가 최종 목적지 도메인으로 판정**(외부면 홍보성). 네트워크 실패/타임아웃은 graceful(추적 실패 시 보수적으로 '외부 의심' 플래그 또는 안전값 — 정책은 재현 기준으로 정하고 주석 명시). 타임아웃 상한(예: 5s)·리다이렉트 상한 둘 것.
3. **이미지 전화번호 감지 강화** — `analyze_blog_images`가 이미지 속 전화번호/주소를 더 안정적으로 잡도록 개선(스크린샷 실패·리사이즈·프롬프트·정규화 점검). 회장 기준 §i: **이미지든 텍스트든 전화번호/주소 있으면 홍보** / 예외: 네이버 카페 홍보 이미지("아프니까사장이다","나만의보험비교" 등).
4. **홍보성 signal 전체 표시** — `is_promotional` 판정 시 걸린 모든 reason/signal(phone·address·external_link·talktalk·place·attachment·phone_in_image·image_link 등)을 **누락 없이** 결과에 담아 프론트가 전부 보여줄 수 있게 한다.

## 검증 기준 (필수)
1. **재현 케이스 PASS**: `https://blog.naver.com/newhero101/224368161108` 를 분석하면 이미지 링크(`m.site.naver.com/2dtWW`→`bohumclick.com`)가 **홍보성 외부링크로 감지**되어 `is_promotional=true`, signal에 external_link(또는 image_link) 포함.
2. **회귀 방지 (중요)**: 기존 정상 정보성 블로그가 오탐(false positive)나지 않도록 — 작성자 본인 블로그 내 링크·expert.naver.com·go.kr/or.kr는 여전히 예외로 통과. 단축URL이 아닌 일반 naver.com 링크 처리 변경이 과도한 오탐을 만들지 않는지 유닛테스트로 확인.
3. 기존 `tests/test_external_links.py` 등 회귀 0. 신규 케이스(단축URL 위장·이미지 전화번호) 테스트 추가.
4. worker 재기동 후 실제 재현 케이스 1건 이상 실동작 확인.

## 배포/주의
- worker는 **로컬 프로세스**(PID 172743 계열, `uvicorn worker.main:app --port 8100`). 수정 후 worker 재기동으로 반영(InsuRo·InfoKeyword 웹앱 양쪽 반영). 재기동 시 무중단 유의.
- ⚠️ InfoKeyword repo는 과거 PR ruleset 데드락 이력 있음(`project_infokeyword_worker_mcp_fix_task2898`). **PR 머지가 막히면 로컬 커밋까지 완료 + ANU에 보고**(회장 결정 경로), 절대 강제 우회 금지.
- 회장 기준 단일 소스: `memory/specs/infor-keyword/requirements-v1.md`. 판단 애매하면 이 문서 우선, 그래도 애매하면 ANU 보고.

## 완료 보고 필수 항목
수정 파일/함수 diff · `_is_naver_internal` 변경 전후 · 단축URL 추적 구현 방식(타임아웃/상한) · 이미지 전화번호 개선 내용 · signal 전체표시 방식 · 재현 케이스 결과(newhero101 → is_promotional=true 증거) · 회귀 테스트 결과 · worker 재기동/실동작 확인 · PR/로컬커밋 상태.