# rb8001 레벨 1 표시 문제 해결 ## 작성일: 2025-08-23 ## 작성자: happybell80 with Claude --- ## 1. 문제 상황 ### 증상 - DB에 rb8001의 레벨이 20으로 저장되어 있음 - 프론트엔드에서는 계속 레벨 1로 표시됨 - `/api/stats/rb8001` 요청시 기본값(레벨 1) 반환 ### 영향 - 사용자가 로빙의 실제 성장 상태를 확인할 수 없음 - Gmail 아이템 등 레벨 기반 기능 사용 제한 --- ## 2. 원인 분석 ### 2.1 Gateway의 하드코딩 문제 **위치**: `robeing-gateway/app/main.py:267` ```python # 문제 코드 response = await http_client.get( f"http://192.168.219.52:10508/api/stats/{robeing_id}" # 항상 rb10508_micro로! ) ``` **문제점**: - 모든 stats 요청을 rb10508_micro(포트 10508)로 강제 라우팅 - 사용자별 로빙 무시 ### 2.2 프론트엔드 헤더 누락 **위치**: `frontend-customer/src/services/robeing-api.ts:447` ```typescript // 문제 코드 const response = await fetch(`${ROBEING_API_URL}/api/stats/${robeingId}`); // X-User-Id 헤더 없음! ``` **문제점**: - Gateway가 사용자를 식별할 수 없음 - 기본값 반환 ### 2.3 잘못된 엔드포인트 경로 **실제 엔드포인트**: - rb8001: `/stats` (api 없음) - rb10508_micro: `/stats/{robeing_id}` (api 없음) **Gateway 요청**: - `/api/stats/{robeing_id}` → 404 에러 ### 2.4 서버 위치 오류 **Gateway 설정**: - rb8001: `http://localhost:8001` → 51123 서버에 없음 **실제 위치**: - rb8001: `http://192.168.219.52:8001` (51124 서버) ### 2.5 ~~State Service 연결 실패~~ (제거됨 - State Service 사용 안 함) - ~~State Service는 더 이상 사용하지 않음~~ - rb8001이 직접 DB 접근하여 스탯 조회 --- ## 3. 해결 과정 ### 3.1 Gateway 사용자별 라우팅 구현 ```python # robeing-gateway/app/main.py @app.get("/api/stats/{robeing_id}") async def get_stats( robeing_id: str, x_user_id: Optional[str] = Header(None) # 사용자 식별 추가 ): # 사용자별 로빙 정보 조회 robeing_info = await get_robeing_info(x_user_id) # 로빙별 올바른 서버로 라우팅 if robeing_id == "rb8001": target_url = f"http://192.168.219.52:8001/stats" elif robeing_id == "rb10508_micro": target_url = f"http://192.168.219.52:10508/stats/{robeing_id}" ``` ### 3.2 프론트엔드 헤더 추가 ```typescript // frontend-customer/src/services/robeing-api.ts const headers: HeadersInit = { 'X-User-Id': userId, 'Authorization': `Bearer ${authToken}` }; const response = await fetch(`${ROBEING_API_URL}/api/stats/${robeingId}`, { headers }); ``` ### 3.3 응답 형식 정규화 ```python # rb8001 응답 형식 변환 if robeing_id == "rb8001" and "stats" in data: return { "robeing_id": robeing_id, "level": data.get("level", 1), "experience": stats_data.get("experience", 0), # ... 표준 형식으로 변환 } ``` --- ## 4. 남은 문제 ### ~~rb8001의 State Service 미연결~~ (해결됨) - State Service는 더 이상 사용하지 않음 - rb8001이 직접 DB에서 스탯 조회하도록 변경함 --- ## 5. 교훈 ### 아키텍처 일관성 - 모든 로빙이 동일한 API 경로 규칙을 따라야 함 - `/api/stats` vs `/stats` 혼용 문제 ### 헤더 전달 중요성 - 프론트엔드는 항상 사용자 식별 헤더 포함 필요 - X-User-Id, Authorization 등 ### 환경변수 관리 - 필수 서비스 URL은 반드시 설정 - 누락시 fallback 처리 필요 ### 디버깅 체인 1. 프론트엔드 요청 확인 2. Gateway 라우팅 확인 3. 실제 서비스 엔드포인트 확인 4. 서비스 내부 로직 확인 --- ## 6. 참고 파일 - `robeing-gateway/app/main.py` - `frontend-customer/src/services/robeing-api.ts` - `rb8001/main.py` - `rb8001/app/router/router.py` - `rb8001/docker-compose.yml`