# 일일 브리핑 시스템 시퀀스 다이어그램

## 작성일: 2025-08-25
## 작성자: 서버 관리자 with Claude
## 상태: 구현 완료 (Gmail 토큰 문제로 부분 작동)

---

## 목차
1. [시스템 개요](#1-시스템-개요)
2. [정상 작동 시퀀스](#2-정상-작동-시퀀스)
3. [현재 실패 시퀀스](#3-현재-실패-시퀀스)
4. [구현 상태 요약](#4-구현-상태-요약)

---

## 1. 시스템 개요

### 1.1 아키텍처
- **크론 서버**: 51123 (Gateway)
- **실행 서버**: 51124 (rb8001, skill-email, skill-news)
- **실행 시간**: 매일 오전 9시 (KST)
- **대상 사용자**: 슬랙 워크스페이스 멤버 3명

### 1.2 서비스 구성
| 서비스 | 포트 | 역할 | 상태 |
|--------|------|------|------|
| robeing-gateway | 8100 | 크론 실행 | ✅ |
| rb8001 | 8001 | 브리핑 생성 | ✅ |
| skill-email | 8501 | 이메일 수집 | ⚠️ |
| skill-news | 8505 | 뉴스 수집 | ✅ |

---

## 2. 정상 작동 시퀀스

```mermaid
sequenceDiagram
    participant Cron as Gateway Cron<br/>(51123:8100)
    participant RB as rb8001<br/>(51124:8001)
    participant DM as dm_skill<br/>(rb8001 내부)
    participant Email as skill-email<br/>(51124:8501)
    participant News as skill-news<br/>(51124:8505)
    participant DB as PostgreSQL<br/>(51123:5432)
    participant Auth as auth-server<br/>(51123:9000)
    participant LLM as Gemini Service<br/>(rb8001 내부)
    participant Slack as Slack API
    participant User as 사용자 DM

    %% 크론 트리거
    Note over Cron: 매일 09:00:00 KST
    Cron->>RB: POST /api/cron/daily-summary<br/>Authorization: Bearer cron-secret-2024
    
    %% 인증 및 초기화
    RB->>RB: 토큰 검증<br/>(main.py:229)
    RB->>DM: send_daily_summary_dm()<br/>(dm_skill.py:384)
    
    %% 사용자 목록
    Note over DM: 하드코딩된 사용자:<br/>U091UNVE41M (전희재)<br/>U0925SXQFDK (김종태)<br/>U092F7FQ55L (HanYong)
    
    %% 병렬 데이터 수집
    par 이메일 수집
        loop 각 사용자별
            DM->>Email: GET /messages<br/>?user_id={slack_id}<br/>&limit=5<br/>&query=category:primary
            
            %% 토큰 체크 및 갱신
            Email->>DB: SELECT * FROM gmail_token<br/>WHERE user_id = ?
            DB-->>Email: token_data, refresh_token
            
            alt 토큰 만료
                Email->>Auth: POST /api/gmail/refresh<br/>Body: {user_id, refresh_token}
                Auth->>Auth: Google OAuth 토큰 갱신
                Auth->>DB: UPDATE gmail_token
                Auth-->>Email: 새 access_token
            end
            
            Email->>Email: Gmail API 호출<br/>Primary 탭 이메일 조회
            Email-->>DM: 이메일 목록 (최대 5개)
        end
    and 뉴스 수집
        DM->>News: POST /api/news/search<br/>Body: {<br/>  keywords: ["AI", "스타트업",<br/>  "기술", "혁신", "투자"]<br/>}
        News->>News: Google News API 호출
        News->>News: 결과 필터링 및 정렬
        News-->>DM: 최신 뉴스 5개
    end
    
    %% LLM 요약 생성
    DM->>DM: 데이터 통합<br/>- 이메일: 사용자별 5개<br/>- 뉴스: 공통 5개
    
    DM->>LLM: 요약 생성 요청
    Note over LLM: 프롬프트:<br/>"한국어로 오늘의 브리핑 작성<br/>1. 중요 이메일 요약<br/>2. 주요 뉴스 요약<br/>3. 액션 아이템 추출"
    LLM-->>DM: 구조화된 브리핑 텍스트
    
    %% Slack 전송
    loop 각 사용자별
        DM->>DM: 개인화 메시지 생성
        DM->>Slack: POST /api/chat.postMessage<br/>Body: {<br/>  channel: {user_dm_id},<br/>  text: "🌅 모닝 브리핑",<br/>  blocks: [...]<br/>}
        Slack-->>DM: 전송 성공
        Slack->>User: 📨 개인 DM 수신
    end
    
    %% 완료
    DM-->>RB: 브리핑 전송 완료
    RB-->>Cron: 200 OK<br/>Body: {status: "success"}
```

---

## 3. 현재 실패 시퀀스

```mermaid
sequenceDiagram
    participant Cron as Gateway Cron<br/>(51123)
    participant RB as rb8001<br/>(51124)
    participant DM as dm_skill
    participant Email as skill-email
    participant News as skill-news
    participant DB as PostgreSQL
    participant Slack as Slack API
    participant User as 사용자

    Note over Cron: 09:00:00 트리거 ✅
    Cron->>RB: POST /api/cron/daily-summary ✅
    RB->>DM: send_daily_summary_dm() ✅
    
    %% 이메일 수집 실패
    rect rgb(255, 230, 230)
        Note over DM,Email: 이메일 수집 실패
        DM->>Email: GET /messages
        Email->>DB: SELECT gmail_token
        DB-->>Email: token_data: NULL ❌
        Email-->>DM: 500 Internal Server Error
        Note over DM: 이메일 데이터 = []
    end
    
    %% 뉴스는 정상
    rect rgb(230, 255, 230)
        Note over DM,News: 뉴스 수집 성공
        DM->>News: POST /api/news/search ✅
        News-->>DM: 뉴스 5개 반환 ✅
    end
    
    %% 불완전한 브리핑
    DM->>DM: 부분 데이터로 요약 생성
    Note over DM: 이메일 섹션 비어있음
    
    loop 각 사용자
        DM->>Slack: 불완전한 브리핑 전송
        Slack->>User: 📨 뉴스만 있는 브리핑
        Note over User: "이메일 요약: 없음<br/>뉴스 요약: 5개 항목"
    end
```

---

---

## 4. 구현 상태 요약

### 4.1 완료된 구현 ✅
- **크론 설정**: Gateway에서 매일 9시 실행
- **API 엔드포인트**: `/api/cron/daily-summary` (main.py:229)
- **DM 스킬**: `send_daily_summary_dm()` (dm_skill.py:384)
- **뉴스 서비스**: skill-news 독립 서비스 (포트 8505)
- **Slack 전송**: 정상 작동

### 4.2 현재 상태
| 항목 | 상태 |
|------|------|
| Gmail 토큰 | 사용자별 저장 |
| 토큰 갱신 | auth-server API 구현됨 |
| 사용자 조회 | 하드코딩 |

### 4.3 관련 파일
```
51123 서버:
├── /home/admin/robeing-gateway/app/crontab.py (크론 설정)
├── /home/admin/auth-server/app/api/gmail_refresh.py (토큰 갱신 API)
└── /home/admin/DOCS/troubleshooting/250824_*.md (트러블슈팅)

51124 서버:
├── /home/admin/ivada_project/rb8001/
│   ├── main.py:229 (크론 엔드포인트)
│   └── app/skills/dm_skill.py:384 (브리핑 생성)
├── /home/admin/ivada_project/skill-email/ (이메일 서비스)
└── /home/admin/ivada_project/skill-news/ (뉴스 서비스)
```

### 5.4 모니터링 포인트
```bash
# 크론 실행 확인
docker exec robeing-gateway crontab -l | grep briefing

# 서비스 상태 확인
docker ps | grep -E "rb8001|skill-email|skill-news"

# 로그 확인
docker logs rb8001 --tail 100 | grep daily-summary
docker logs skill-email --tail 50 | grep ERROR

# DB 토큰 상태
psql -U robeings -d main_db -c "SELECT user_id, token_data IS NOT NULL as has_token FROM gmail_token;"
```

---

## 개선 제안

### 단기 (즉시 적용 가능)
1. skill-email에 토큰 만료 체크 로직 추가
2. 에러 발생 시에도 뉴스만이라도 전송하도록 graceful degradation

### 중기 (1-2주)
1. 사용자 목록 DB 연동
2. Gmail refresh_token 자동 갱신 구현
3. 브리핑 커스터마이징 (사용자별 선호도)

### 장기 (1개월+)
1. 웹 UI에서 브리핑 설정 관리
2. 브리핑 시간 개인화
3. 다양한 데이터 소스 추가 (캘린더, 태스크 등)