# task-693.1 완료 보고서: ThreadAuto CLI post-carousel 커맨드 추가

## SCQA

**S**: ThreadAuto CLI에 `post-text`, `post-image`, `post-video` 커맨드가 구현되어 있고, `api/client.py:73`에 `post_carousel()` 메서드도 구현 완료 상태이다.

**C**: CLI에 `post-carousel` 진입점이 없어서, 카드뉴스 6장을 생성해도 봇이 `post-image`로 커버 1장만 업로드하는 문제가 발생한다.

**Q**: `post-carousel` CLI 커맨드를 추가하여 로컬 파일 경로의 자동 URL 변환과 함께 멀티이미지 게시를 지원할 수 있는가?

**A**: `cli.py`에 `post-carousel` 커맨드를 추가하고, 로컬 파일 → 공개 URL 자동 변환(ImageServer 활용)을 구현하여 해결. TDD 사이클 준수(RED 10건 → GREEN 10건), pytest 10/10 통과, pyright 0 에러.

## 변경 파일

- **수정**: `/home/jay/projects/ThreadAuto/cli.py` — `post-carousel` 커맨드 추가 (line 207~269)
- **생성**: `/home/jay/projects/ThreadAuto/tests/test_cli_carousel.py` — 6개 테스트 클래스, 10개 테스트 함수

## 구현 내용

### post-carousel 커맨드 (cli.py:212)
- 시그니처: `post_carousel(image_paths: list[str], caption: str)`
- 로컬 파일 감지: `http://`/`https://` 접두사 확인으로 URL/로컬 구분
- 로컬 파일 변환: `publisher.image_server.get_default_server()` → `ensure_server()` + `get_public_url()`
- API 호출: `ThreadsClient.post_carousel(image_urls, caption)`
- 출력: Rich Panel (기존 post-image/post-video 패턴 동일)
- 에러 처리: `typer.Exit(code=1)` (기존 패턴 동일)

## 테스트 결과

```
tests/test_cli_carousel.py — 10 passed in 0.19s
```

- 커맨드 등록 확인: 1건 PASS
- 토큰 미인증 종료: 1건 PASS
- URL 경로 패스스루: 2건 PASS (http, https)
- 로컬 경로 URL 변환: 2건 PASS (단독, 혼합)
- 성공 출력: 2건 PASS (Post ID, exit code 0)
- API 에러 처리: 2건 PASS (exit code 1, 에러 메시지)

## 검증 증거

- pytest: 10/10 passed (0.19s)
- pyright: 0 errors, 0 warnings, 0 informations
- black + isort: 포매팅 적용 완료
- `python cli.py post-carousel --help`: IMAGE_PATHS... 인자 + --caption/-c 옵션 정상 노출

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **`registered_commands`의 `name` 속성이 None** — `@app.command()`로 name 없이 등록된 커맨드는 `cmd.name`이 None. 테스트에서 `cmd.callback.__name__` 폴백 패턴 적용.
2. **로컬 import 패턴 유지** — `get_default_server`를 함수 내부 로컬 import로 처리하여 기존 CLI 패턴과 일관성 유지. 테스트에서 `patch("publisher.image_server.get_default_server")` 경로로 mock.
3. **혼합 경로(URL+로컬) 처리** — `image_paths` 중 일부만 로컬인 경우, 각 경로별 개별 판별 후 로컬만 변환하는 리스트 컴프리헨션 적용.

## QC 셀프 체크리스트
- [x] 1. 다른 파일 영향: cli.py만 수정, 기존 커맨드 미변경
- [x] 2. 엣지 케이스: 빈 이미지 목록(typer가 required로 처리), URL/로컬 혼합, 토큰 미인증
- [x] 3. 작업 지시 일치: post-carousel 커맨드 + 로컬 파일 변환 + 기존 스타일 일치
- [x] 4. 에러 처리: 토큰 없음, API 에러 시 exit code=1 + 메시지 출력
- [x] 5. 테스트 커버리지: 6개 카테고리 10개 테스트로 모든 경로 커버
- [x] 6. 발견 이슈 모두 해결: 3건 자체 해결 완료
