docs: 일일 브리핑 시퀀스 및 로빙 stats 표시 문제 트러블슈팅 추가
- daily_briefing_sequences.md: rb8001 매일 9시 브리핑 시스템 완전 문서화 - 정상 작동 시퀀스, 현재 실패 시퀀스, 토큰 갱신 플로우 포함 - Gmail 토큰 NULL 문제로 이메일 수집 실패 상황 명시 - 250825_robeing_stats_display_issue.md: 프론트엔드 로빙 상태 미표시 문제 - 프론트엔드 하드코딩, 51124 서버 DB 미조회 문제 분석 - 문제 플로우 다이어그램 및 해결 방안 제시
This commit is contained in:
parent
e5bf338974
commit
5f2c2c98ca
257
300_architecture/sequences/daily_briefing_sequences.md
Normal file
257
300_architecture/sequences/daily_briefing_sequences.md
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
# 일일 브리핑 시스템 시퀀스 다이어그램
|
||||||
|
|
||||||
|
## 작성일: 2025-08-25
|
||||||
|
## 작성자: 서버 관리자 with Claude
|
||||||
|
## 상태: 구현 완료 (Gmail 토큰 문제로 부분 작동)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 목차
|
||||||
|
1. [시스템 개요](#1-시스템-개요)
|
||||||
|
2. [정상 작동 시퀀스](#2-정상-작동-시퀀스)
|
||||||
|
3. [현재 실패 시퀀스](#3-현재-실패-시퀀스)
|
||||||
|
4. [토큰 갱신 플로우](#4-토큰-갱신-플로우-미구현)
|
||||||
|
5. [구현 상태 요약](#5-구현-상태-요약)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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_tokens<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_tokens
|
||||||
|
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_tokens
|
||||||
|
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. 토큰 갱신 플로우 (미구현)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant Email as skill-email
|
||||||
|
participant Auth as auth-server<br/>(51123:9000)
|
||||||
|
participant DB as PostgreSQL
|
||||||
|
participant Google as Google OAuth
|
||||||
|
|
||||||
|
Note over Email: 현재 미구현 상태<br/>구현 필요한 플로우
|
||||||
|
|
||||||
|
rect rgb(255, 255, 230)
|
||||||
|
Note over Email: 토큰 만료 감지
|
||||||
|
Email->>Email: check_token_expiry()
|
||||||
|
|
||||||
|
alt 토큰 만료됨
|
||||||
|
Email->>Auth: POST /api/gmail/refresh
|
||||||
|
Note over Auth: 엔드포인트는 구현됨<br/>(gmail_refresh.py)
|
||||||
|
|
||||||
|
Auth->>Google: POST /token<br/>grant_type=refresh_token
|
||||||
|
Google-->>Auth: 새 access_token
|
||||||
|
|
||||||
|
Auth->>DB: UPDATE gmail_tokens<br/>SET access_token = ?
|
||||||
|
Auth-->>Email: {access_token, expires_at}
|
||||||
|
|
||||||
|
Email->>Email: 토큰 캐시 갱신
|
||||||
|
Email->>Email: Gmail API 재시도
|
||||||
|
else 토큰 유효
|
||||||
|
Email->>Email: 기존 토큰으로 진행
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Note over Email: 이 로직 추가 시<br/>자동 갱신 가능
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 구현 상태 요약
|
||||||
|
|
||||||
|
### 5.1 완료된 구현 ✅
|
||||||
|
- **크론 설정**: Gateway에서 매일 9시 실행
|
||||||
|
- **API 엔드포인트**: `/api/cron/daily-summary` (main.py:229)
|
||||||
|
- **DM 스킬**: `send_daily_summary_dm()` (dm_skill.py:384)
|
||||||
|
- **뉴스 서비스**: skill-news 독립 서비스 (포트 8505)
|
||||||
|
- **Slack 전송**: 정상 작동
|
||||||
|
|
||||||
|
### 5.2 문제점 ⚠️
|
||||||
|
| 문제 | 원인 | 영향 | 해결 방안 |
|
||||||
|
|------|------|------|-----------|
|
||||||
|
| Gmail 토큰 NULL | 사용자 미인증 | 이메일 수집 실패 | 사용자 재인증 필요 |
|
||||||
|
| 자동 갱신 미구현 | skill-email 로직 부재 | 토큰 만료 시 실패 | refresh 로직 추가 |
|
||||||
|
| 사용자 하드코딩 | DB 연동 미구현 | 확장성 제한 | DB 조회로 변경 |
|
||||||
|
|
||||||
|
### 5.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_tokens;"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 개선 제안
|
||||||
|
|
||||||
|
### 단기 (즉시 적용 가능)
|
||||||
|
1. skill-email에 토큰 만료 체크 로직 추가
|
||||||
|
2. 에러 발생 시에도 뉴스만이라도 전송하도록 graceful degradation
|
||||||
|
|
||||||
|
### 중기 (1-2주)
|
||||||
|
1. 사용자 목록 DB 연동
|
||||||
|
2. Gmail refresh_token 자동 갱신 구현
|
||||||
|
3. 브리핑 커스터마이징 (사용자별 선호도)
|
||||||
|
|
||||||
|
### 장기 (1개월+)
|
||||||
|
1. 웹 UI에서 브리핑 설정 관리
|
||||||
|
2. 브리핑 시간 개인화
|
||||||
|
3. 다양한 데이터 소스 추가 (캘린더, 태스크 등)
|
||||||
243
troubleshooting/250825_robeing_stats_display_issue.md
Normal file
243
troubleshooting/250825_robeing_stats_display_issue.md
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
# 로빙 상태(Stats) 표시 안됨 문제 트러블슈팅
|
||||||
|
|
||||||
|
## 작성일: 2025-08-25
|
||||||
|
## 작성자: 서버 관리자
|
||||||
|
## 상태: 미해결 (51124 서버 코드 수정 필요)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 문제 요약
|
||||||
|
사용자가 로그인 후 프론트엔드에서 로빙의 실제 상태(레벨, 경험치, 스탯)가 표시되지 않고 하드코딩된 기본값만 표시됨
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 증상
|
||||||
|
- 프론트엔드에서 항상 "LV.12", "350 코인", "75% 경험치" 표시 (하드코딩)
|
||||||
|
- 실제 DB에는 rb8001이 레벨 20이지만 UI에 반영 안됨
|
||||||
|
- 게이트웨이 로그: `/api/stats/undefined` 호출 (robeing_id 미전달)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 문제 분석
|
||||||
|
|
||||||
|
### 1. 프론트엔드 문제 (51123 서버)
|
||||||
|
|
||||||
|
#### 1.1 하드코딩된 UI
|
||||||
|
**위치**: `/home/admin/frontend-customer/src/components/game-layout.tsx:97-101`
|
||||||
|
```jsx
|
||||||
|
<div className="bg-amber-400 text-black px-1.5 py-0.5 rounded text-xs font-bold">
|
||||||
|
LV.12 // 하드코딩
|
||||||
|
</div>
|
||||||
|
<div className="bg-violet-600 text-white px-1.5 py-0.5 rounded text-xs font-bold">
|
||||||
|
<span>💎</span> 350 // 하드코딩
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2 Stats API 호출 누락
|
||||||
|
- 프론트엔드에서 `/api/stats/{robeing_id}` 호출 로직 없음
|
||||||
|
- useEffect나 데이터 fetching 코드 부재
|
||||||
|
- SimpleStatsPanel도 props 기본값만 사용
|
||||||
|
|
||||||
|
#### 1.3 Robeing ID 미전달
|
||||||
|
- 게이트웨이 로그 확인:
|
||||||
|
```
|
||||||
|
GET /api/stats/undefined HTTP/1.0" 200 OK
|
||||||
|
Stats request from user: happybell80 for robeing: undefined
|
||||||
|
```
|
||||||
|
- 프론트엔드가 사용자의 robeing_id를 가져오지 못함
|
||||||
|
|
||||||
|
### 2. 게이트웨이 동작 (51123 서버) - 정상
|
||||||
|
|
||||||
|
#### 2.1 사용자-로빙 매핑 정상
|
||||||
|
```sql
|
||||||
|
-- DB 확인 결과
|
||||||
|
happybell80 (goeun2dc@gmail.com) → rb8001 정상 매핑
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 프록시 정상 작동
|
||||||
|
```bash
|
||||||
|
# 직접 테스트 시 정상 응답
|
||||||
|
curl http://localhost:8100/api/stats/rb8001
|
||||||
|
→ 51124 서버로 정상 프록시
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 51124 서버 문제 (rb8001 서비스)
|
||||||
|
|
||||||
|
#### 3.1 하드코딩된 응답
|
||||||
|
**문제 위치**: `rb8001/main.py:116`
|
||||||
|
```python
|
||||||
|
@app.get("/stats")
|
||||||
|
async def get_stats():
|
||||||
|
# DB 조회 없이 하드코딩된 값 반환
|
||||||
|
return {
|
||||||
|
"level": 1, # 항상 1
|
||||||
|
"experience": 0,
|
||||||
|
"stats": {
|
||||||
|
"memory": 10,
|
||||||
|
"compute": 10,
|
||||||
|
"empathy": 10,
|
||||||
|
"leadership": 10,
|
||||||
|
"ethics": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 State Service 미연결
|
||||||
|
- `state_service.py`에 `/api/stats/{robeing_id}` 정의됨
|
||||||
|
- 하지만 `main.py`에서 import/mount 안함
|
||||||
|
- 결과: 엔드포인트 접근 불가 (404)
|
||||||
|
|
||||||
|
#### 3.3 DB 값과 불일치
|
||||||
|
```sql
|
||||||
|
-- DB의 실제 값
|
||||||
|
robeing_stats 테이블:
|
||||||
|
- robeing_id: rb8001
|
||||||
|
- level: 20
|
||||||
|
- experience: 2000
|
||||||
|
|
||||||
|
-- API 응답값
|
||||||
|
- level: 1
|
||||||
|
- experience: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 문제 플로우 다이어그램
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as 사용자<br/>(goeun2dc)
|
||||||
|
participant Frontend as 프론트엔드<br/>(51123)
|
||||||
|
participant Gateway as 게이트웨이<br/>(51123:8100)
|
||||||
|
participant RB8001 as rb8001<br/>(51124:8001)
|
||||||
|
participant DB as PostgreSQL<br/>(51123:5432)
|
||||||
|
|
||||||
|
User->>Frontend: 로그인
|
||||||
|
Frontend->>Frontend: auth_token 저장
|
||||||
|
Note over Frontend: ❌ robeing_id 가져오기 누락
|
||||||
|
|
||||||
|
Frontend->>Frontend: game-layout 렌더링
|
||||||
|
Note over Frontend: ❌ 하드코딩된 값 표시<br/>LV.12, 350코인, 75%
|
||||||
|
|
||||||
|
Frontend->>Gateway: GET /api/stats/undefined ❌
|
||||||
|
Note over Gateway: robeing_id가 undefined
|
||||||
|
|
||||||
|
Gateway->>Gateway: 캐시에서 사용자 조회<br/>happybell80 → rb8001
|
||||||
|
Gateway->>RB8001: GET /stats (rb8001로 프록시)
|
||||||
|
|
||||||
|
RB8001->>RB8001: ❌ DB 조회 없음
|
||||||
|
RB8001-->>Gateway: 하드코딩된 응답<br/>level: 1, 모든 스탯: 10
|
||||||
|
Gateway-->>Frontend: 응답 전달
|
||||||
|
|
||||||
|
Frontend->>Frontend: ❌ 응답 무시<br/>여전히 하드코딩 표시
|
||||||
|
|
||||||
|
Note over DB: 실제 값 (미사용):<br/>level: 20<br/>experience: 2000
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 해결 방안
|
||||||
|
|
||||||
|
### 단기 (즉시 적용 가능) - 51123 서버
|
||||||
|
|
||||||
|
#### 1. 프론트엔드 수정 필요
|
||||||
|
```typescript
|
||||||
|
// game-layout.tsx 수정 예시
|
||||||
|
const [stats, setStats] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchStats = async () => {
|
||||||
|
const userId = localStorage.getItem('user_id');
|
||||||
|
// 1. 먼저 사용자의 robeing_id 가져오기
|
||||||
|
const robeingResponse = await fetch(`/api/user/${userId}/robeing`);
|
||||||
|
const { robeing_id } = await robeingResponse.json();
|
||||||
|
|
||||||
|
// 2. stats 가져오기
|
||||||
|
const statsResponse = await fetch(`/api/stats/${robeing_id}`);
|
||||||
|
const statsData = await statsResponse.json();
|
||||||
|
setStats(statsData);
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchStats();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 하드코딩 대신 동적 표시
|
||||||
|
<div>LV.{stats?.level || 1}</div>
|
||||||
|
<div>💎 {stats?.coins || 0}</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 중기 (51124 서버 수정 필요)
|
||||||
|
|
||||||
|
#### 1. rb8001 서비스 수정
|
||||||
|
- `main.py`에서 `state_service` import 및 mount
|
||||||
|
- `/stats` 엔드포인트가 DB 조회하도록 수정
|
||||||
|
- `robeing_stats` 테이블과 동기화
|
||||||
|
|
||||||
|
#### 2. State Service 활성화
|
||||||
|
```python
|
||||||
|
# main.py 수정 필요
|
||||||
|
from app.services import state_service
|
||||||
|
|
||||||
|
# 라우터 마운트
|
||||||
|
app.include_router(state_service.router, prefix="/api")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 임시 해결책 (권장하지 않음)
|
||||||
|
|
||||||
|
### DB 직접 수정
|
||||||
|
```sql
|
||||||
|
-- rb8001의 레벨을 1로 낮추기 (비추천)
|
||||||
|
UPDATE robeing_stats
|
||||||
|
SET level = 1, experience = 0
|
||||||
|
WHERE robeing_id = 'rb8001';
|
||||||
|
```
|
||||||
|
→ 근본 해결 아님, API가 여전히 DB 무시
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 관련 파일
|
||||||
|
- **프론트엔드**:
|
||||||
|
- `/home/admin/frontend-customer/src/components/game-layout.tsx`
|
||||||
|
- `/home/admin/frontend-customer/src/components/simple-stats-panel.tsx`
|
||||||
|
- `/home/admin/frontend-customer/src/contexts/auth-context.tsx`
|
||||||
|
|
||||||
|
- **게이트웨이**:
|
||||||
|
- `/home/admin/robeing-gateway/app/main.py` (정상)
|
||||||
|
|
||||||
|
- **51124 서버** (수정 필요):
|
||||||
|
- `rb8001/main.py:116` - 하드코딩된 /stats
|
||||||
|
- `rb8001/app/services/state_service.py` - 미연결
|
||||||
|
|
||||||
|
- **DB 테이블**:
|
||||||
|
- `robeing_stats` - 실제 스탯 저장
|
||||||
|
- `workspace_members` - 사용자-로빙 매핑
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 모니터링 명령어
|
||||||
|
```bash
|
||||||
|
# 게이트웨이 로그 확인
|
||||||
|
docker logs robeing-gateway --tail 50 | grep stats
|
||||||
|
|
||||||
|
# DB 상태 확인
|
||||||
|
PGPASSWORD=robeings psql -h localhost -U robeings -d main_db \
|
||||||
|
-c "SELECT * FROM robeing_stats WHERE robeing_id = 'rb8001';"
|
||||||
|
|
||||||
|
# API 직접 테스트
|
||||||
|
curl http://localhost:8100/api/stats/rb8001
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 참고 문서
|
||||||
|
- [일일 브리핑 시퀀스](/home/admin/DOCS/300_architecture/sequences/daily_briefing_sequences.md) - 비슷한 DB 연동 문제
|
||||||
|
- [OAuth 스코프 문제](/home/admin/DOCS/troubleshooting/250824_gmail_oauth_scope_issue.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 추가 확인 사항
|
||||||
|
1. 프론트엔드에서 사용자의 robeing_id를 어떻게 가져올지 결정 필요
|
||||||
|
2. stats 업데이트 주기 (실시간 vs 폴링)
|
||||||
|
3. 캐싱 전략 (게이트웨이 캐시 활용)
|
||||||
Loading…
x
Reference in New Issue
Block a user