# 스레드 자동화 20/일 확대 + 파이프라인 가동

## 작업 레벨: Lv.2

## 목표
현재 10개/일 구조를 20개/일로 확대하고, 실제 자동화 파이프라인을 가동한다.

## 현재 상태
- 콘텐츠 생성 (Claude CLI): 구현됨 (`content/content_generator_v2.py`)
- 카드뉴스 렌더링 (PIL): 구현됨 (`renderer/cardnews.py`)
- 스케줄링 (APScheduler): 구현됨 (`scheduler/`)
- Threads API 발행: 구현됨 (`publisher/threads_publisher.py`)
- 토큰 갱신: 구현됨 (`auth/token_store.py`)
- 에버그린 소재: 200개 (`content/evergreen_topics.json`)
- **현재 가동 상태**: 미가동 (daily_queue 비어있음, cron 미등록)

## 작업 범위

### 1. 파이프라인 점검 (먼저 수행)

토큰 유효성 확인:
```python
# auth/token_store.py의 load_token(), is_token_expired() 호출
```

API 연결 테스트:
```python
# api/client.py로 실제 API 호출 테스트 (GET /me 등)
```

이미지 서버 확인:
```bash
# 현재 돌고 있음: python3 -m http.server 8080 + tailscale funnel
curl http://127.0.0.1:8080/  # 로컬 접근 가능 확인
```

콘텐츠 생성 1건 테스트:
```python
# content_generator_v2.py로 1개 콘텐츠 생성 → 렌더링 → 확인
```

### 2. 10개 → 20개 확대

#### 2.1 `scheduler/auto_publisher.py` 수정

골든타임 슬롯 확대:
```python
# 현재
GOLDEN_SLOTS = [
    {"start": 7, "end": 9, "count": 3, "label": "출근시간"},
    {"start": 12, "end": 13, "count": 2, "label": "점심시간"},
    {"start": 19, "end": 22, "count": 2, "label": "퇴근후"},
]
NON_GOLDEN_COUNT = 3
# 합계: 10개

# 변경 (골든타임 70% = 14개, 비골든 30% = 6개)
GOLDEN_SLOTS = [
    {"start": 7, "end": 9, "count": 5, "label": "출근시간"},
    {"start": 12, "end": 13, "count": 3, "label": "점심시간"},
    {"start": 19, "end": 22, "count": 6, "label": "퇴근후"},
]
NON_GOLDEN_COUNT = 6
# 합계: 20개
```

MIN_INTERVAL_MINUTES는 유지(10분). 20개/일이면 평균 48분 간격이므로 충분.

#### 2.2 `content/topic_selector.py` 수정

DAILY_MIX 확대:
```python
# 현재
DAILY_MIX = {
    "고민공감": 3,
    "정보제공": 3,
    "사회적증거": 2,
    "업계동향": 1,
    "CTA": 1,
}  # 합계 10

# 변경
DAILY_MIX = {
    "고민공감": 6,
    "정보제공": 6,
    "사회적증거": 4,
    "업계동향": 2,
    "CTA": 2,
}  # 합계 20
```

#### 2.3 `scheduler/daily_runner.py` 확인

daily_runner가 DAILY_MIX에 따라 동적으로 생성 수를 결정하는지 확인.
하드코딩된 "10"이 있으면 DAILY_MIX 합계를 참조하도록 수정.

### 3. 파이프라인 테스트 실행

dry-run 모드로 1회 실행:
```bash
cd /home/jay/projects/ThreadAuto
python3 scheduler/daily_runner.py  # 콘텐츠 20개 생성 + 렌더링
```

결과 확인:
- `scheduler/daily_queue/{오늘날짜}.json` 생성 확인
- 20개 슬롯이 모두 content + image_paths를 가지는지 확인
- 시간표가 합리적인지 (겹침 없음, 최소 10분 간격)

### 4. 발행 워커 시작

publish_worker 데몬 모드로 시작:
```bash
cd /home/jay/projects/ThreadAuto
nohup python3 scheduler/publish_worker.py --daemon --interval 60 > /tmp/publish_worker.log 2>&1 &
echo "PID: $!"
```

### 5. daily_runner cron 등록

시스템 cron 또는 cokacdir --cron으로 매일 새벽 5시 실행:
- 방법 A: 시스템 crontab
- 방법 B: cokacdir --cron (권장 - 모니터링 가능)

```bash
# 방법 B 예시 (dispatch 내에서 직접 등록하지 말 것 - 보고서에 명시만)
# cokacdir --cron "ThreadAuto 일일 콘텐츠 20개 생성 실행: cd /home/jay/projects/ThreadAuto && python3 scheduler/daily_runner.py" --at "0 5 * * *" --chat 6937032012 --key c119085addb0f8b7
```

### 6. 모니터링 확인

- `scheduler/publish_log.json`이 정상 기록되는지
- 발행 성공/실패 통계
- 토큰 만료 전 갱신이 정상 동작하는지

## 테스트 요구사항

1. 기존 테스트 전체 PASS 유지
2. auto_publisher가 20개 시간표를 정상 생성하는지 단위 테스트
3. topic_selector가 20개 소재를 정상 선택하는지 단위 테스트
4. daily_runner dry-run 성공 확인

## 주의사항

1. **토큰 만료**: 토큰이 만료됐으면 갱신 필요. 갱신 불가 시 보고서에 명시.
2. **API Rate Limit**: Threads 일일 250건 한도. 20개면 여유 있음.
3. **Claude CLI 호출**: 20개 콘텐츠 생성 시 ~40분 소요 예상. 새벽 5시 시작이면 6시 전 완료.
4. **에버그린 소재 재사용**: 쿨다운 7일. 200개 소재면 10일분. 소재 부족 시 보고서에 경고.
5. **이미지 서버**: tailscale funnel이 이미 돌고 있으므로 건드리지 말 것.