# task-1302.1 완료 보고서: BlogAuto 프로젝트 시작

**작성일**: 2026-04-01
**팀**: dev2-team (오딘)
**참여**: 토르(백엔드), 헤임달(테스터)

---

## SCQA

**S**: viruagent-cli 심층 분석(task-1302)이 완료되어 네이버 블로그 SE 에디터 + RabbitWrite API, 티스토리 내부 관리 API의 동작 방식이 파악된 상태이다. 기존 티스토리 PoC(task-1109.1)도 Playwright 기반으로 구현 완료되어 있다.

**C**: 분석 결과물만 존재하고 실제 포팅된 Python 코드가 없어, 블로그 자동 발행 파이프라인을 구축할 수 없다. viruagent-cli는 Node.js 기반이라 우리 Python 생태계와 직접 통합이 불가하다.

**Q**: viruagent-cli의 네이버 블로그/티스토리 핵심 API 로직을 Python으로 포팅하여 독립 프로젝트로 구성할 수 있는가?

**A**: `/home/jay/projects/BlogAuto/`에 독립 프로젝트를 생성하고 네이버 블로그(SE 에디터 + RabbitWrite API)와 티스토리(내부 관리 API) 발행 모듈을 Python(httpx)으로 구현 완료했다. pytest 41건 전체 통과, pyright 에러 0건. 기존 PoC(task-1109.1)의 Playwright 브라우저 자동화 대신 fetch 기반 API 방식을 채택하여 효율성을 개선했다.

---

## 산출물

- `/home/jay/projects/BlogAuto/config.py`
- `/home/jay/projects/BlogAuto/publisher/__init__.py`
- `/home/jay/projects/BlogAuto/publisher/base.py`
- `/home/jay/projects/BlogAuto/publisher/naver_blog.py`
- `/home/jay/projects/BlogAuto/publisher/tistory.py`
- `/home/jay/projects/BlogAuto/content/__init__.py`
- `/home/jay/projects/BlogAuto/content/generator.py`
- `/home/jay/projects/BlogAuto/tests/__init__.py`
- `/home/jay/projects/BlogAuto/tests/test_base.py`
- `/home/jay/projects/BlogAuto/tests/test_naver_blog.py`
- `/home/jay/projects/BlogAuto/tests/test_tistory.py`
- `/home/jay/projects/BlogAuto/tests/test_generator.py`
- `/home/jay/projects/BlogAuto/requirements.txt`
- `/home/jay/projects/BlogAuto/README.md`
- `/home/jay/projects/BlogAuto/pyrightconfig.json`

---

## 구현 상세

### 네이버 블로그 발행 (publisher/naver_blog.py, 596줄)
viruagent-cli의 `naverApiClient.js` + `editorConvert.js`를 Python으로 포팅:
- **인증**: 쿠키 기반 세션 (`NID_AUT` + `NID_SES`)
- **블로그 초기화**: `GET MyBlog.naver` → blogId regex 추출
- **SE 토큰**: `GET PostWriteFormSeOptions.naver` → Se-Authorization 토큰
- **카테고리**: `GET PostWriteFormManagerOptions.naver` → categoryFormViewList 파싱
- **HTML → SE 컴포넌트**: `POST upconvert.editor.naver.com` (API, 1차) + 로컬 HTML 파서 (폴백, 2차)
- **이미지 업로드**: session-key 발급 → `POST blog.upphoto.naver.com` → XML 응답 파싱
- **발행**: `POST RabbitWrite.naver` (documentModel v2.9.0 + populationParams)

### 티스토리 발행 (publisher/tistory.py, 384줄)
viruagent-cli의 `tistoryApiClient.js`를 Python으로 포팅:
- **인증**: 쿠키 기반 세션 (`TSSESSION`)
- **블로그 초기화**: `GET tistory.com/legacy/member/blog/api/myBlogs` → defaultBlog 추출
- **카테고리**: `GET manage/newpost` → `window.Config` regex + `json.loads()` (vm.runInNewContext 대신, 보안 강화)
- **발행**: `POST manage/post.json` (JSON body, visibility: 0=비공개/20=공개)
- **임시저장**: `POST manage/drafts`
- **이미지**: `POST manage/post/attach.json` (FormData)
- **Rate Limit**: JSON 파일 기반 일일 카운터 (15회/일 하드캡)

### 공통 모듈
- `publisher/base.py` (128줄): 추상 인터페이스, 예외 4종, 세션 쿠키 로더
- `config.py` (24줄): 환경변수 기반 설정
- `content/generator.py` (29줄): 콘텐츠 생성 스텁 (향후 AI 연동용)

---

## 테스트 결과

```
41 passed in 0.13s
```

- test_base.py: 9건 (세션 쿠키 로드, 데이터클래스)
- test_naver_blog.py: 12건 (블로그 초기화, 토큰, 카테고리, HTML 변환, 이미지 업로드, 발행)
- test_tistory.py: 15건 (레이트리밋, 블로그 초기화, 카테고리, 발행, 임시저장, 이미지, 포스트 목록)
- test_generator.py: 5건 (NotImplementedError, 파일 로드)
- pyright: 에러 0건
- black/isort: 포맷 준수

---

## 발견 이슈 및 해결

### 자체 해결 (4건)
1. **viruagent-cli vm.runInNewContext() 보안 위험** — `json.loads()` + regex 폴백으로 대체
   - 상세: tistory.py `get_categories()` - window.Config JSON 직접 파싱
2. **pyright 타입 에러 (str | None 반환)** — 지역 변수로 명시적 타입 바인딩
   - 상세: naver_blog.py:158, tistory.py:154-156
3. **미사용 import (ElementTree, AuthRequiredError)** — 제거
   - 상세: naver_blog.py:8,18
4. **black/isort 스타일 불일치** — 전체 파일 포맷팅 적용

### 범위 외 미해결 (3건)
1. **인증(로그인) 모듈 미구현** — Playwright 기반 로그인은 Phase 2에서 구현 예정. 현재는 수동으로 쿠키 JSON 파일 생성 필요.
   - 범위 외 사유: task 명세에 "세션/인증 관리 방식" 분석만 포함, 로그인 자동화는 별도 작업
2. **실제 API 통합 테스트 미실행** — 실제 네이버/티스토리 계정 필요
   - 범위 외 사유: task 명세 "실제 발행은 제이회장님 확인 후에만"
3. **viruagent-cli 이미지 검색 파이프라인 미포팅** — DuckDuckGo/Wikimedia 검색은 저작권 리스크로 제외
   - 범위 외 사유: 적용 제안서에서 "자체 이미지 라이브러리 또는 Gemini 이미지 생성 스킬 사용" 권장

---

## 설계 결정

1. **fetch API vs Playwright 브라우저 자동화**: viruagent-cli의 fetch 기반 API 방식 채택. 기존 PoC(task-1109.1)의 Playwright 방식은 브라우저 오버헤드가 크고, 실제 UI 셀렉터 매핑도 미검증 상태. fetch API가 더 가볍고 안정적.
2. **httpx 동기 모드**: 현재 단계에서 비동기 불필요. 향후 대량 발행 시 비동기 전환 용이(httpx.AsyncClient).
3. **독립 프로젝트**: ThreadAuto가 아닌 별도 repo로 분리. 각 프로젝트의 의존성/배포 독립성 유지.

---

## 다음 단계

1. **인증 모듈 구현**: Playwright 기반 네이버/카카오 로그인 → 쿠키 JSON 저장
2. **실제 테스트**: 실제 계정으로 비공개 발행 테스트
3. **blog-writer 연동**: 콘텐츠 생성 → 자동 발행 파이프라인
4. **스케줄러**: cron 기반 주기적 자동 발행

---

## QC 자동 검증

```json
{
  "test_runner": "PASS (41 passed in 0.13s)",
  "pyright_check": "PASS (0 errors)",
  "style_check": "PASS (black/isort 적용 완료)",
  "data_integrity": "PASS"
}
```
