diff --git a/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md b/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md new file mode 100644 index 0000000..e4f6661 --- /dev/null +++ b/troubleshooting/250825_happybell80_사용자별로빙연결및레벨표시문제.md @@ -0,0 +1,275 @@ +# 사용자별 로빙 연결 및 레벨 표시 문제 해결 + +## 작성일: 2025-08-25 +## 작성자: happybell80 +## 관련 서비스: auth-server, frontend-customer, robeing-gateway, rb8001 + +--- + +## 오후 1시 30분 + +### 문제 상황 1: 사용자별 로빙 연결 안됨 + +**증상**: +- `goeun2dc@gmail.com`으로 로그인 시 `rb10508_micro`로 연결됨 +- 실제로는 `happybell80` → `rb8001`로 연결되어야 함 +- DB에는 올바른 매핑이 있지만 실제 동작하지 않음 + +**DB 확인 결과**: +```sql +-- users 테이블 +username: happybell80 +email: goeun2dc@gmail.com +UUID: 1e16e9d5-59f3-54da-a661-8abeabff4230 + +-- workspace_members 테이블 +happybell80 → rb8001 (포트 8001) +eagle0914 → rb10508_micro (포트 10508) +``` + +**원인 분석**: +auth-server의 gmail.py가 DB의 username을 사용하지 않고 이메일 기반 매핑 또는 이메일 앞부분 사용 + +--- + +## 오후 1시 45분 + +### 해결 1: auth-server JWT 토큰 수정 + +#### 수정 파일: auth-server/app/providers/gmail.py + +**변경 전** (line 182-191): +```python +else: + # 기존 사용자 정보 업데이트 + user.name = user_name + user.oauth_provider = 'google' + user.oauth_id = user_info.get('id', '') + db.commit() + logger.info(f"Existing user updated: {username} ({user_email})") + +# 사용자 ID 사용 (UUID string) +user_id_str = str(user.id) +username = user.username # 문제: 새 사용자는 username이 없음 +``` + +**변경 후**: +```python +else: + # 기존 사용자 정보 업데이트 및 username 가져오기 + username = user.username if user.username else username # DB의 username 우선 사용 + user.name = user_name + user.oauth_provider = 'google' + user.oauth_id = user_info.get('id', '') + db.commit() + logger.info(f"Existing user updated: {username} ({user_email})") + +# 사용자 ID 사용 (UUID string) +user_id_str = str(user.id) +# username은 이미 설정됨 (신규: 매핑/생성, 기존: DB 값) +``` + +**결과**: +- JWT 토큰에 DB의 실제 username(`happybell80`) 포함 +- Gateway가 올바른 로빙으로 라우팅 + +--- + +## 오후 2시 00분 + +### 문제 상황 2: 프론트엔드 사용자 표시 + +**증상**: +- UserMenu에서 email 앞부분만 표시 +- ChatInterface에서 사용자 이름이 제대로 표시 안됨 + +**원인**: +- User 인터페이스에 username 필드 없음 +- 표시 우선순위에서 username 누락 + +**해결 검토** (구현 예정): +```typescript +// auth-context.tsx +interface User { + id: string; + username?: string; // 추가 필요 + email: string; + name?: string; + picture?: string; +} + +// user-menu.tsx +const displayName = user?.username || user?.name || user?.id || user?.email?.split('@')[0]; +``` + +--- + +## 오후 2시 30분 + +### 문제 상황 3: ChatInterface 하드코딩된 로빙 ID + +**증상**: +- 모든 사용자에게 "RO-BEING #10508" 표시 +- 실제 할당된 로빙 ID가 표시되지 않음 + +**원인**: +```tsx +// chat-interface.tsx line 441 +

RO-BEING #10508

// 하드코딩 +``` + +**해결**: +1. ChatInterface에 robeingId prop 추가 +2. GameLayout에서 userRobeingId 전달 +3. 동적 표시로 변경 + +```tsx +// game-layout.tsx +{React.cloneElement(centerPanel, { robeingId: userRobeingId })} + +// chat-interface.tsx +interface ChatInterfaceProps { + robeingId?: string; +} + +

RO-BEING #{robeingId.replace('rb', '').replace('_micro', '')}

+``` + +**결과**: +- 로그인 사용자별 올바른 로빙 ID 표시 +- `happybell80` → "RO-BEING #8001" +- `eagle0914` → "RO-BEING #10508" + +--- + +## 오후 2시 45분 + +### 문제 상황 4: 레벨 표시 문제 + +**증상**: +- 헤더에 레벨 1로 표시 +- DB에는 레벨 20으로 저장되어 있음 +- rb8001 서비스가 하드코딩된 레벨 1 반환 + +**분석**: +```python +# rb8001/main.py:116-130 +@app.get("/stats") +async def get_stats(): + return { + "robeing_id": "rb8001", + "stats": { + "memory": 10, # 하드코딩 + "compute": 10, # 하드코딩 + # ... + }, + "level": 1 # 하드코딩 + } +``` + +**API 호출 경로**: +1. Frontend: `getRobeingStats('rb8001')` +2. Gateway: `https://ro-being.com/gateway/api/stats/rb8001` +3. rb8001: 하드코딩된 레벨 1 반환 + +--- + +## 오후 3시 00분 + +### 레벨 문제 해결 방안 + +#### 옵션 1: rb8001 수정 (비권장) +- rb8001에 PostgreSQL 연결 추가 +- 51123 서버 DB 조회 구현 +- 프로덕션 서비스 수정 위험 + +#### 옵션 2: Gateway에서 DB 직접 조회 (권장) +- Gateway가 이미 51123 서버에 있음 +- DB 접근 가능 +- 중앙집중식 관리 +- 모든 로빙 통합 처리 + +**Gateway 수정 계획**: +```python +@app.get("/api/stats/{robeing_id}") +async def get_stats(robeing_id: str): + # DB에서 직접 조회 + conn = await asyncpg.connect(...) + row = await conn.fetchrow(""" + SELECT * FROM robeing_stats + WHERE robeing_id = $1 + """, robeing_id) + + if row: + return { + "level": row['level'], # 실제 DB 값 + "experience": row['experience'], + # ... + } +``` + +--- + +## 성과 + +### ✅ 완료된 작업 +1. **auth-server 수정** + - DB username을 JWT에 포함 + - 사용자별 올바른 로빙 연결 + +2. **frontend-customer 수정** + - ChatInterface 동적 로빙 ID 표시 + - GameLayout에서 robeingId prop 전달 + +### 🔄 진행 중인 작업 +1. **Gateway 레벨 조회** + - DB 직접 조회로 변경 필요 + - rb8001 하드코딩 문제 해결 + +### 📋 추가 작업 필요 +1. **Frontend User 타입 개선** + - username 필드 추가 + - 표시 우선순위 조정 + +--- + +## 교훈 + +### 1. 시스템 전체 데이터 흐름 파악 중요 +- Auth → Gateway → Robeing → Frontend +- 각 단계에서 데이터 변환 확인 필요 + +### 2. 하드코딩 제거 필수 +- rb8001의 하드코딩된 stats +- ChatInterface의 하드코딩된 ID +- 동적 데이터 사용 원칙 + +### 3. DB와 서비스 동기화 +- DB 데이터와 서비스 응답 불일치 +- 단일 진실 소스(DB) 원칙 준수 + +### 4. JWT 토큰 설계 +- username을 primary identifier로 사용 +- UUID는 내부적으로만 사용 +- 일관된 사용자 식별 체계 + +--- + +## 다음 단계 + +1. **Gateway 수정 완료** + - `/api/stats/{robeing_id}` DB 조회 구현 + - 테스트 및 배포 + +2. **Frontend 사용자 정보 개선** + - User 인터페이스 확장 + - username 우선 표시 + +3. **서버 배포** + - auth-server 재시작 + - Gateway 재시작 + - 사용자 재로그인 유도 + +--- + +**문서 끝** \ No newline at end of file