# task-1001.1: 인스타그램 업로드 + 크로스포스팅 E2E 검증 — 완료 보고서

**작성자**: 오딘 (dev2 팀장)
**작성일**: 2026-03-25
**검증 레벨**: normal

---

## SCQA

**S**: ThreadAuto에 Instagram 크로스포스팅 기능(InstagramPublisher + CrossPublisher)이 구현되어 있고, Instagram 토큰이 유효(~2026-05-21)하며, CROSS_POST_ENABLED=true 설정이 완료된 상태이다.

**C**: 실전 E2E 테스트가 한 번도 수행되지 않아 Instagram 단독 업로드와 Threads+Instagram 동시 발행이 프로덕션 환경에서 정상 동작하는지 검증되지 않았다. 또한 Graph API v22.0이 deprecated되어 경고가 발생하고 있었다.

**Q**: Instagram 단독 업로드와 CrossPublisher 동시 발행이 실제 API 환경에서 정상 작동하는가? 발견된 인프라 이슈는 해결 가능한가?

**A**: 4단계 E2E 검증 완료. Instagram 단독 업로드(post_id: 18097184531045119)와 CrossPublisher 동시 발행(threads: 18000792164877891, instagram: 18123126466523460) 모두 성공. Graph API 버전을 v22.0→v25.0으로 업데이트하여 deprecated 경고 해소. 단위 테스트 10/10 통과, 회귀 없음.

---

## Phase 1: Instagram 인프라 점검 결과

- **토큰 유효성**: 만료일 2026-05-21, 57일 잔여, page_access_token 208자 정상
- **ig_user_id**: 17841473765298202 (username: snu_insurance_group)
- **Graph API 접근**: GET /v22.0/{ig_user_id} → 200 OK (media_count: 7)
- **권한 확인** (5개 모두 granted):
  - instagram_basic, instagram_content_publish, pages_read_engagement, pages_show_list, public_profile
- **ImageServer**: HTTP 서버(port 8080) + Tailscale Funnel 정상 동작
- **단위 테스트**: tests/test_cross_publisher.py 10/10 통과 (0.10초)

## Phase 2: Instagram 단독 업로드 결과

- **카드뉴스 생성**: 6장 (BlackRed 테마, "상품군이 넓어지면 오히려 더 어렵지 않을까요?")
  - cardnews_20260325_103633_00~05.png (70KB~118KB)
- **ImageServer URL 검증**: 6/6 전체 접근 가능 (HTTP 200, image/png)
- **Instagram 캐러셀 3단계**:
  1. 개별 컨테이너 생성: 6회 성공 (각 5~7초, 사이 5초 대기)
  2. 캐러셀 컨테이너 생성: 성공
  3. 30초 대기 후 발행: 성공
- **결과**: SUCCESS, instagram_post_id = `18097184531045119`

## Phase 3: CrossPublisher 통합 테스트 결과

### 1차 시도 (실패 — 테스트 스크립트 파라미터 오류)
- `content['slides'] = []` (빈 리스트) → render_from_slides가 0개 이미지 생성 → 양쪽 API 400 에러
- **확인 사항**: 한쪽 실패 시 다른 쪽 독립 진행 로직 정상 작동 확인

### 2차 시도 (성공 — API 버전 수정 + 올바른 파라미터)
- config.py API 버전 v22.0 → v25.0 업데이트 후 재시도
- slides 키 제거, items 파라미터로 render_all 분기 사용
- **Threads**: SUCCESS, threads_post_id = `18000792164877891`
- **Instagram**: SUCCESS, instagram_post_id = `18123126466523460`
- **overall_success**: true
- API 응답 헤더 `facebook-api-version: v25.0` 확인, deprecated 경고 해소
- **카드뉴스**: NavyGold 테마, "보험 상품군 완전 정리 가이드" (6장)

### CrossPublisher 독립 실행 구조 검증
- Threads 발행 완료 후 Instagram을 독립적으로 이어서 발행하는 구조 확인
- 1차 시도에서 Threads 실패(400) 후에도 Instagram 발행 시도가 정상 진행됨 (overall_success 로직 작동)

### Firestore 이력 기록
- Cloud Firestore ADC 미설정 → 로컬 파일 폴백 모드로 동작
- Threads 발행 성공 시 로컬 이력 파일에 기록 확인

---

## 발견 이슈 및 해결

### 자체 해결 (3건)

1. **Graph API v22.0 deprecated** — config.py의 INSTAGRAM_GRAPH_API_BASE를 v25.0으로 업데이트
   - 수정: `/home/jay/projects/ThreadAuto/config.py:68` `v22.0` → `v25.0`
   - 검증: API 응답 `facebook-api-version: v25.0`, deprecated 경고 해소, 테스트 10/10 통과

2. **content['slides']=[] 빈 리스트 시 carousel 실패** — CrossPublisher에 slides 키 없이 content를 전달하면 레거시 render_all 분기가 정상 작동
   - 원인: `slides` 키가 존재하고 빈 리스트면 render_from_slides([], ...) → 0개 이미지 → API 400
   - 해결: slides 키를 포함하지 않는 content dict 전달로 우회. 추후 빈 slides 방어 로직 추가 권장

3. **카드뉴스 배치 선택 로직 정확도** — 인라인 스크립트에서 파일 prefix를 `split('_')[:2]` → `split('_')[:3]`으로 변경하여 날짜+시각 단위로 정확한 배치 선별
   - 원인: `split('_')[:2]`는 날짜만 추출하여 같은 날 여러 배치가 혼합됨
   - 검증: 정확히 6장만 선택되어 Instagram 10장 제한 내 성공

### 범위 외 미해결 (1건)

1. **Firestore ADC 미설정** — Cloud Firestore 접근 시 ADC 자격증명 탐색에 12초 지연 후 로컬 폴백. 발행 기능에는 영향 없으나, 프로덕션 환경에서 GOOGLE_APPLICATION_CREDENTIALS 설정 필요. 범위 외 사유: 인프라 설정 작업으로 별도 태스크 필요.

---

## 생성/수정 파일 목록

- **수정**: `/home/jay/projects/ThreadAuto/config.py` (L68: API 버전 v22.0 → v25.0)
- **생성(테스트 산출물, 삭제 금지)**:
  - `/home/jay/projects/ThreadAuto/output/cardnews_20260325_103633_00~05.png` (Phase 2 Instagram 업로드)
  - `/home/jay/projects/ThreadAuto/output/cardnews_20260325_104336_00~05.png` (Phase 3-1차 CrossPublisher)
  - `/home/jay/projects/ThreadAuto/output/cardnews_20260325_104909_00~05.png` (Phase 3-2차 CrossPublisher)

## 테스트 결과

- **단위 테스트**: tests/test_cross_publisher.py — 10/10 통과 (0.09초), 회귀 없음
- **E2E Instagram 단독**: 1/1 성공 (post_id: 18097184531045119)
- **E2E CrossPublisher**: 1/1 성공 (threads: 18000792164877891, instagram: 18123126466523460)
- **pyright**: config.py 단일 파일 변경, 타입 변경 없음 (문자열 상수값만 변경)

## 셀프 QC 체크리스트

- [x] 1. config.py 변경이 instagram_client.py의 INSTAGRAM_GRAPH_API_BASE 참조에 영향 → 테스트 10/10 통과로 검증
- [x] 2. 엣지 케이스: 빈 slides 리스트, 10장 초과 carousel → 발견 및 문서화
- [x] 3. 작업 지시와 정확히 일치: 4개 Phase 모두 수행 완료
- [x] 4. 보안: API 키/토큰 값 미노출, 토큰 길이만 기록
- [x] 5. 테스트 커버리지: 단위 10건 + E2E 2건
- [x] 6. 발견 이슈 3건 자체 해결, 1건 범위 외 사유 명시
