# Task-516: ThreadAuto 배치→온디맨드 단건 생성 전환

## 문제 (제이회장님 지적)
현재 daily_runner.py가 새벽에 20개를 한꺼번에 생성 → 이미지 공유, content_type 누락, 캡션 반복 등 품질 문제 발생.

### 제이회장님이 원하는 플로우
1. 스케줄 시간 도래 → **그때 콘텐츠 1개 생성**
2. 프리뷰를 텔레그램으로 전송 (승인 요청)
3. 제이회장님 승인 → Threads 업로드
4. 다음 스케줄까지 대기

## 현재 아키텍처 분석

### 배치 생성 플로우 (문제)
```
daily_runner.py → 20개 토픽 선정 → 20개 콘텐츠 생성 → 20개 이미지 렌더링 → daily_queue JSON 저장
publish_worker.py (데몬) → 큐에서 시간 된 포스트 꺼냄 → 프리뷰 전송 → 승인 → 업로드
```

### 핵심 버그 3개
1. **content_type 미설정**: topic_selector의 DAILY_MIX_V3에 타입 정의는 있으나, 생성된 post dict에 content_type 필드 누락. publish_worker에서 항상 "cardnews"로 fallback (publish_worker.py 211행)
2. **이미지 무조건 렌더링**: text 타입도 카드뉴스 이미지 생성 → 불필요한 렌더링 + 타입 혼동
3. **배치 생성 품질**: 20개를 한 세션에서 생성하면 Claude 응답이 반복적/유사해짐

## 수정 사항

### 1. 스케줄 기반 온디맨드 생성기 신규 작성
- 파일: `scheduler/on_demand_runner.py` (신규)
- 기능:
  - 오늘의 스케줄(20슬롯) 로드
  - 현재 시간 기준 다음 발행 슬롯 1개 확인
  - 해당 슬롯의 카테고리+content_type에 맞춰 콘텐츠 1개 생성
  - 이미지 렌더링 (cardnews/video만, text 타입은 스킵)
  - 큐에 추가 + 프리뷰 텔레그램 전송
  - 승인 대기 상태로 전환

### 2. 일일 스케줄 사전 생성 (daily_schedule.py 또는 기존 활용)
- 20슬롯의 발행시간 + 카테고리 + content_type만 미리 생성
- 콘텐츠 본문/이미지는 생성하지 않음
- 파일: `scheduler/daily_queue/{date}.json` — posts 배열에 빈 슬롯 (content=null, status="scheduled")

### 3. publish_worker.py 수정
- 기존: 큐에서 pending 포스트를 발행
- 변경: 데몬 모드에서 2가지 역할
  1. **생성 트리거**: 다음 발행 시간 15분 전 → on_demand_runner 호출 → 1개 생성 + 프리뷰 전송
  2. **발행 실행**: approved 상태인 포스트 발행
- `get_pending_posts()` (99-144행): status="scheduled" + publish_time 15분 이내 → 생성 트리거
- `get_approved_posts()`: status="approved" → 발행 실행

### 4. content_type 파이프라인 관통
- `topic_selector.py` (34-46행): DAILY_MIX_V3의 types 정보를 선택된 토픽 dict에 포함
  ```python
  # 반환 dict에 추가:
  {"category": "고민공감", "content_type": "text_empathy", ...}
  ```
- `daily_runner.py` / `on_demand_runner.py`: content_type을 post dict에 전달
- `build_daily_queue()` / 큐 구조: post에 `content_type` 필드 포함
- `publish_worker.py` (211행): fallback 제거, content_type 필수

### 5. 이미지 조건부 렌더링
- `content_type.startswith("text_")` → 이미지 렌더링 스킵, image_paths=[]
- `content_type == "cardnews"` → 카드뉴스 이미지 렌더링
- `content_type == "video"` → 영상 렌더링 (기존 로직)

## 핵심 파일 위치
- `scheduler/daily_runner.py` — 기존 배치 생성 (참고용, 온디맨드로 대체)
- `scheduler/publish_worker.py` — 데몬 수정 (생성 트리거 + 발행)
- `content/topic_selector.py` (34-46행) — DAILY_MIX_V3, content_type 전달
- `content/content_generator_v2.py` — 콘텐츠 생성 (1개 단위, 변경 최소)
- `renderer/cardnews.py` — 이미지 렌더링 (변경 없음)
- `config.py` — APPROVAL_MODE, APPROVAL_CHAT_ID 등

## 큐 구조 변경 (daily_queue JSON)
```json
{
  "date": "2026-03-13",
  "posts": [
    {
      "slot_index": 0,
      "publish_time": "2026-03-13T07:35:00+09:00",
      "category": "고민공감",
      "content_type": "text_empathy",
      "content": null,
      "image_paths": [],
      "caption": null,
      "status": "scheduled",
      "generated_at": null,
      "approved_at": null,
      "published_at": null
    }
  ]
}
```
- status 흐름: scheduled → generating → awaiting_approval → approved → published (또는 rejected)

## 주의사항
- daily_runner.py는 삭제하지 말고 보존 (백업용)
- 기존 큐 파일 구조 하위호환 유지
- publish_worker의 APPROVAL_MODE 로직(546-642행) 재활용
- cokacdir 텔레그램 전송: APPROVAL_CHAT_ID="6937032012", APPROVAL_KEY="c119085addb0f8b7"

## 테스트
1. 빈 스케줄 생성 → 20슬롯 확인
2. 1개 슬롯 온디맨드 생성 → content_type 반영 확인
3. text 타입 → 이미지 없음 확인
4. cardnews 타입 → 이미지 생성 확인
5. 프리뷰 텔레그램 전송 → 승인 → 발행 플로우

## 프로젝트 경로
`/home/jay/projects/ThreadAuto/`

## 작업 레벨: Lv.2 (기능 구현)