--- tags: [workflow, admin, diary, scheduler] type: workflow last_updated: 2026-04-06 --- # diary_reflection_pipeline 워크플로우 ## 목적 매일 오전 2시에 전날의 로빙 일기를 자동 생성하고, DB에 저장하며, DOCS 레포에 마크다운 파일로 커밋·푸시한다. ## 아키텍처 - **스케줄러**: APScheduler (DB 기반). `db_loader.py`가 `scheduler_jobs` 테이블에서 `job_type=diary_generator` 잡을 로드하여 등록. - **기본 스케줄**: `settings.DIARY_GENERATOR_SCHEDULE` = `0 2 * * *` (매일 02:00). - **활성화 플래그**: `settings.DIARY_GENERATOR_ENABLED` (기본 `True`). - **n8n 미사용**. systemd로 rb8001이 직접 실행. ## 코드 SSOT - `rb8001/app/scheduler/jobs/diary_generator.py` — 잡 래퍼 + 일기 생성 로직 - `rb8001/app/services/diary/aggregator.py` — `DiaryAggregator` (데이터 집계) - `rb8001/app/services/diary/generator.py` — `DiaryGenerator` (LLM 일기 생성) - `rb8001/app/state/diary_repository.py` — `save_diary()` (DB 저장) - `rb8001/app/router/diary_endpoint.py` — 일기 조회 API - `rb8001/app/scheduler/db_loader.py` — DB 잡 로더 (`JOB_TYPE_MAP["diary_generator"]`) ## 흐름 ``` APScheduler cron trigger (0 2 * * *) → db_loader가 등록한 guarded_job (schedule_policy 평가) → _run_diary_generator_with_logging() → _generate_diary() 1. draft_watcher 선행 실행 (non-blocking) 2. DiaryAggregator.aggregate(target_date, robeing_id) — 전날 활동 데이터 집계 3. DiaryGenerator.generate(target_date, robeing_id, aggregated_data) — LLM 일기 생성 4. save_diary() — DB 저장 (full_content, summary, dominant_emotion, stats) 5. _save_diary_to_git() — DOCS 레포에 마크다운 저장 + git add/commit/push 6. ActivityLogger.log_scheduler_job() — 스케줄러 작업 로그 기록 ``` ## 일기 조회 API (현행) | 메서드 | 경로 | 설명 | |--------|------|------| | `GET` | `/api/diary/{target_date}?robeing_id=rb8001` | 특정 날짜 일기 조회 | | `GET` | `/api/diary/list?robeing_id=rb8001&limit=100` | 일기 목록 조회 | **주의**: `/api/diary/generate` 엔드포인트는 코드에 존재하지 않는다. 일기 생성은 APScheduler 잡이 내부적으로 `DiaryGenerator.generate()`를 직접 호출한다. ## 일기 저장 경로 - **DB**: `diary` 테이블 (`date`, `robeing_id`, `full_content`, `summary`, `dominant_emotion`, `stats`) - **Git**: `$DOCS_REPO_PATH/book/700_for_robeing/diary/{YYYY-MM-DD}.md` - `DOCS_REPO_PATH` 환경변수, 기본값: `$WORKSPACE_ROOT/robeing/DOCS` ## 선행 작업 - 일기 생성 전 `draft_watcher`를 실행하여 NAS 드래프트 변경사항을 activity_log에 기록한다 (실패 시 non-blocking). ## 실패 분기 - `DiaryGenerator.generate()`가 `None`을 반환하면 `RuntimeError` 발생. - DB 저장 실패 시 에러 로그 + ActivityLogger에 `status=error` 기록. - Git push 실패 시 에러 로그만 남기고 계속 진행 (non-blocking). ## 환경변수 - `DIARY_GENERATOR_ENABLED` — 일기 생성 활성화 여부 (settings 경유, 기본 `True`). - `DIARY_GENERATOR_SCHEDULE` — cron 표현식 (settings 경유, 기본 `0 2 * * *`). - `DOCS_REPO_PATH` — DOCS 레포 경로 (환경변수, 기본 `$WORKSPACE_ROOT/robeing/DOCS`). - `ROBEING_ID` — 로빙 식별자 (settings 경유). ## 관련 문서 - [service_health_check (레거시, _archive 이동됨)](../_archive/service_health_check.md)