# 사용자별 로빙 연결 및 레벨 표시 문제 해결

## 작성일: 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_member 테이블
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
<h3>RO-BEING #10508</h3>  // 하드코딩
```

**해결**:
1. ChatInterface에 robeingId prop 추가
2. GameLayout에서 userRobeingId 전달
3. 동적 표시로 변경

```tsx
// game-layout.tsx
{React.cloneElement(centerPanel, { robeingId: userRobeingId })}

// chat-interface.tsx
interface ChatInterfaceProps {
  robeingId?: string;
}

<h3>RO-BEING #{robeingId.replace('rb', '').replace('_micro', '')}</h3>
```

**결과**: 
- 로그인 사용자별 올바른 로빙 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 재시작
   - 사용자 재로그인 유도

---

**문서 끝**