# task-459.1 완료 보고서: ThreadAuto 영상(VIDEO) 타입 Threads 테스트 업로드

## 작업 요약
ThreadAuto에 VIDEO 타입 게시 기능을 구현하고, 실제 Threads에 3회 테스트 업로드를 성공적으로 완료했다.

## 수정/생성 파일 목록

### 수정 파일 (6개)
1. **api/models.py** — `MediaType` enum에 `VIDEO = "VIDEO"` 추가, `CreateContainerRequest`에 `video_url` 필드 추가
2. **api/client.py** — `post_video(video_url, caption)` + `_poll_container_status(container_id)` 메서드 추가
3. **publisher/image_server.py** — `get_public_url()` 하위 디렉토리 경로 지원 (output/videos/ 등)
4. **publisher/threads_publisher.py** — `publish()` 메서드에 video_path 분기 추가, `_get_video_url()` 메서드 추가, `_run_publish()`에 video_path 인자 추가
5. **cli.py** — `post-video` 커맨드 추가
6. **tests/test_client.py** — `test_post_video`, `test_post_video_polling_error`, `test_post_video_polling_timeout` 3개 테스트 추가

### 수정 테스트 파일 (2개)
7. **tests/test_publisher.py** — `TestThreadsPublisherPublishVideo` 클래스 추가 (4개 테스트)
8. **tests/test_image_server.py** — `test_get_public_url_relative_subdir` 테스트 추가

## 구현 상세

### API Client (api/client.py)
- `post_video(video_url, caption)`: VIDEO 컨테이너 생성 → 상태 폴링 → 발행
- `_poll_container_status(container_id)`: 5초 간격, 최대 12회(60초) 폴링
  - FINISHED → 리턴
  - ERROR → RuntimeError 발생
  - 60초 초과 → TimeoutError 발생

### Publisher (publisher/threads_publisher.py)
- `publish()` 메서드: post_data에 `video_path` 키가 있으면 비디오 발행 로직 실행
- `_run_publish()`: video_path → post_video(), image_path → post_image(), 둘 다 없으면 → post_text()

### Image Server (publisher/image_server.py)
- `get_public_url()`: image_dir 하위 파일이면 상대 경로 보존 (예: videos/test.mp4)
- 기존 동작(파일명만 추출) 하위호환 유지

### CLI (cli.py)
- `post-video <video_url> <caption>`: 영상 게시물 발행 커맨드

## 테스트 결과

### 단위 테스트
- **87개 테스트 전체 PASSED** (test_client: 11개, test_publisher: 38개, test_image_server: 38개)
- pyright: 0 errors, 0 warnings

### 실제 Threads 업로드 테스트 (3회 모두 성공)
- 테스트 영상: `test_vibelabs_style.mp4` (21KB, H.264, 1080x1920, 15.5초)
- 1회차 (CLI): Post ID `18035637338578790`
- 2회차 (Python 직접): Post ID `18576492361036552`
- 3회차 (단계별): Post ID `17981183765974698`
- 폴링 동작: IN_PROGRESS 6회 → FINISHED (약 35초 소요)

## 검증 기준 충족
- [x] Threads에 영상이 실제 게시됨 (3회 성공)
- [x] threads_post_id 정상 반환
- [x] 에러 발생 시 명확한 에러 메시지 (RuntimeError, TimeoutError)
- [x] 기존 TEXT/IMAGE/CAROUSEL 기능에 영향 없음 (87개 테스트 통과)

## 머지 판단
- **머지 필요**: Yes
- **브랜치**: task/task-459.1-dev1
- **워크트리 경로**: /home/jay/projects/ThreadAuto/.worktrees/task-459.1-dev1
- **머지 의견**: 87개 단위 테스트 전체 통과, 실제 Threads 업로드 3회 성공, pyright 0 에러. 기존 기능에 영향 없음. 머지 권장.

## 비고
- 워크트리의 `.tokens/` 디렉토리 부재로 메인 프로젝트에서 토큰 복사하여 테스트 수행
- 토큰 만료일: 2026-05-04 (현재 유효)
- ⚠️ 기존 테스트 실패 1건 (본 작업 범위 외): `tests/test_evergreen_topics.py::TestEvergreenTopicsInitialValues::test_used_count_initial_zero` — 메인 브랜치에서도 동일 실패 (used_count가 0이어야 하나 2)

## QC 자동 검증 결과 (3회 시도 — 에스컬레이션)
- file_check: PASS
- data_integrity: PASS
- tdd_check: PASS
- pyright_check: PASS (0 errors)
- style_check: PASS (black+isort 적용 완료)
- test_runner: FAIL (기존 실패 1건, 본 작업 범위 외)
- 본 작업 관련 87개 테스트: 전부 PASSED
- **QC FAIL 사유**: `test_evergreen_topics.py::test_used_count_initial_zero`가 메인 브랜치에서도 실패하는 기존 결함. 본 작업과 무관. 3회 시도 후 에스컬레이션.
