Context
PR #639 가 Option A + Option B (research grounding + IG carousel + admin preview) 까지 wire-up 완료. plan 의 Option C (Meta IG Graph API 자동 publish) 는 사용자 결정으로 보류:
- 매니저가 admin 에서 verify 후 수동 IG 업로드 유지 (브랜드 안전)
- Meta App Review (1-3주) + brand 팀 sign-off 필요
Proposed approach (when ready)
- ai-server side:
- `src/managers/social/instagram_client.py` — Meta Graph API wrapper (Container Publishing API for carousels)
- `src/services/editorial_article/publish_to_instagram_service.py` — ARQ 잡
- `InstagramClient.create_carousel_post(slide_urls, caption)` 흐름:
- POST /{ig_user_id}/media per slide → container_id
- POST /{ig_user_id}/media (CAROUSEL, children=ids, caption) → carousel_container_id
- POST /{ig_user_id}/media_publish → ig_media_id
- api-server side:
- `/api/v1/admin/editorial-articles/{id}/publish-to-instagram` POST handler
- status guard: `ig_slides_urls.length == 6 && ig_post_id IS NULL`
- gRPC RPC `PublishToInstagram`
- DB:
- `editorial_articles.ig_post_id text` (Meta IG post ID, UNIQUE WHERE NOT NULL)
- `editorial_articles.ig_published_at timestamptz`
- Admin UI:
- IgCarouselPreview 에 "Publish to IG" primary 버튼 + permalink 표시
- Env vars:
- `META_IG_ACCESS_TOKEN` (long-lived page token, 60일 expiry — refresh cron 필요)
- `META_IG_USER_ID` (Instagram Business Account ID)
- `META_IG_GRAPH_API_VERSION` (default v21.0)
Blockers
- Meta App Review (1-3주): `instagram_basic`, `instagram_content_publish`, `pages_show_list`, `pages_read_engagement`
- Brand 안전 정책: AI 자동 게시 vs 수동 검수 trade-off — 브랜드 팀 결정
- Idempotency: 중복 publish 방지 (`ig_post_id IS NULL` 체크)
- Rate limit: Meta 50 API-published posts / 24h / account
Acceptance
- admin "Publish to IG" 버튼 클릭 → 30-45초 후 IG post URL 표시
- 같은 article 두 번 publish 시도 시 거부
- Meta App 거부될 가능성 대비 — failure 시 manual upload fallback
References: PR #639, plan `.claude/plans/delegated-singing-squirrel.md` Option C
Context
PR #639 가 Option A + Option B (research grounding + IG carousel + admin preview) 까지 wire-up 완료. plan 의 Option C (Meta IG Graph API 자동 publish) 는 사용자 결정으로 보류:
Proposed approach (when ready)
Blockers
Acceptance
References: PR #639, plan `.claude/plans/delegated-singing-squirrel.md` Option C