# task-491.1 완료 보고서: ThreadAuto 승인 워크플로우 구현

## SCQA

**S**: ThreadAuto의 콘텐츠 발행 파이프라인이 daily_runner → publish_worker 흐름으로 매일 20건을 자동 발행 중이다.

**C**: 콘텐츠 품질 확인 없이 자동 발행되어 부적절한 콘텐츠가 게시될 위험이 있으며, 안정화 기간 동안 제이회장님의 개별 승인이 필요하다.

**Q**: 기존 자동 발행 로직을 깨뜨리지 않으면서, APPROVAL_MODE 토글로 승인 워크플로우를 추가할 수 있는가?

**A**: config.py에 APPROVAL_MODE 설정을 추가하고, approval_sender.py(미리보기 전송)와 approve_post.py(승인/거절 CLI)를 신규 생성하여 구현 완료. publish_worker.py에 APPROVAL_MODE 분기를 추가해 True일 때만 승인 흐름을 타고, False이면 기존 100% 동일 동작을 보장한다. pytest 113건 전체 통과, pyright 0 error.

## 작업 내용

### 생성/수정 파일

- `config.py` (수정): APPROVAL_MODE, APPROVAL_CHAT_ID, APPROVAL_KEY 3개 상수 추가
- `scheduler/approval_sender.py` (신규, 453줄): 미리보기 전송 모듈
  - `find_next_pending()`: pending + publish_time 도래 포스트 탐색
  - `format_preview()`: 텍스트/카드뉴스/영상 타입별 미리보기 포맷
  - `send_preview()`: cokacdir 명령어로 텔레그램 전송
  - `process_approval_queue()`: 전체 프로세스 (1건 제한, fcntl 파일 잠금)
- `scheduler/approve_post.py` (신규, 383줄): 승인/거절 CLI 모듈
  - `approve_current()`: awaiting_approval → approved → publish → published
  - `reject_current()`: awaiting_approval → rejected + 다음 미리보기 전송
  - CLI: `python3 approve_post.py [--reject [--reason "사유"]]`
- `scheduler/publish_worker.py` (수정): APPROVAL_MODE 분기 추가
  - `_run_approval_mode_cycle()`: 승인 모드 전용 사이클 (approved 발행 + pending 미리보기)
  - `run_worker_cycle()`: APPROVAL_MODE=True → 승인 사이클, False → 기존 동작
- `scheduler/__init__.py` (수정): 신규 모듈 exports 추가
- `tests/test_approval_sender.py` (신규): 37건 테스트
- `tests/test_approve_post.py` (신규): 16건 테스트
- `tests/test_publish_worker.py` (수정): 기존 테스트에 APPROVAL_MODE=False 패치 적용
- `pyrightconfig.json` (수정): 워크트리 extraPaths 추가

## 테스트 결과

- **pytest (본 작업 관련)**: 113 passed, 0 failed (0.34s)
  - test_approval_sender.py: 37 passed
  - test_approve_post.py: 16 passed
  - test_publish_worker.py: 60 passed (기존 전체 통과)
- **pyright**: 0 errors, 0 warnings (프로젝트 디렉토리 기준)
- **black**: 7 files passed
- **isort**: 7 files passed
- ⚠️ 기존 테스트 실패 1건 (본 작업 범위 외): `tests/test_cta_linebreak.py::TestFactDbContainsBusinessPage::test_fact_db_contains_business_page` — fact_db.md에 '사업단 페이지' 표기 부재. 메인 브랜치에서도 동일 실패 확인 (회귀 아님).

## QC 자동 검증 결과

- file_check: PASS
- data_integrity: PASS
- test_runner: FAIL (기존 test_cta_linebreak 실패 — 본 작업 범위 외)
- tdd_check: PASS (테스트 2개 + 구현 4개)
- pyright_check: WARN (qc_verify의 경로 해석 이슈, 프로젝트 내 직접 실행 시 0 error)
- style_check: PASS
- 종합: 4 PASS, 1 FAIL(기존), 3 SKIP, 1 WARN

## 이슈 / 발견사항

1. **fcntl 잠금 중복 코드**: approval_sender.py와 approve_post.py에 _acquire_lock, _load_queue_locked, _save_queue_locked 함수가 중복 존재. 향후 공통 유틸로 추출 고려.
2. **카드뉴스 이미지 전송 비동기화**: send_preview()에서 이미지가 많으면 cokacdir 호출이 순차적이라 느릴 수 있음. 현재 20건 중 1건씩이므로 즉시 영향은 없음.
3. **큐 상태 전이 정합성**: approve_post.py에서 approved → published 사이에 잠금을 해제했다 재획득하는 구간이 존재. 동시 접근 가능성은 낮지만 경합 시 이중 발행 위험 이론상 존재.

## 아누 연동 가이드

제이회장님이 텔레그램에서:
- "승인" → `python3 /home/jay/projects/ThreadAuto/scheduler/approve_post.py`
- "스킵" → `python3 /home/jay/projects/ThreadAuto/scheduler/approve_post.py --reject`

## 머지 판단

- **머지 필요**: Yes
- **브랜치**: task/task-491.1-dev1
- **워크트리 경로**: /home/jay/projects/ThreadAuto/.worktrees/task-491.1-dev1
- **머지 의견**: pytest 113건 전체 통과, pyright 0 error, APPROVAL_MODE=False 시 기존 동작 100% 보존 확인. 머지 권장.
