# 사용자별 로빙 동적 할당 및 레벨 표시 구현 ## 작성일: 2025-08-20 ## 작성자: happybell80 ## 관련 서비스: frontend-customer, rb10508_micro, robeing-monitor --- ## 오후 4시 30분 ### 문제 상황 프론트엔드 헤더에 로빙 레벨이 하드코딩되어 있어 실제 DB 값과 불일치: - game-layout.tsx: "LV.12" 하드코딩 - skills-items-panel.tsx: 기본값 20으로 설정 - 모든 사용자가 동일한 로빙(rb10508_micro) 사용 ### 시스템 구조 파악 #### 로빙 시스템 아키텍처 ``` 사용자 로그인 (Google OAuth) ↓ users 테이블 (UUID) ↓ workspace_member 테이블 (robeing_id 할당) ↓ 로빙 컨테이너 (rb8001, rb10508_micro 등) ↓ robeing-monitor (9024) (통합 상태 관리) ``` #### 핵심 테이블 관계 - **users**: 사용자 UUID 저장 - **workspace_member**: user_id → robeing_id 매핑 - **robeing_stats**: 각 로빙의 레벨, 경험치, 스탯 #### 서비스 구조 - **51123 서버**: nginx, frontend-customer, auth-server - **51124 서버**: 로빙 컨테이너들 (rb8001:8001, rb10508_micro:10508) - **robeing-monitor**: 통합 상태 관리 (포트 9024) --- ## 오후 4시 45분 ### 해결 방안 설계 #### 1. API 구조 설계 ```typescript // 필요한 API 엔드포인트 1. GET /api/user/robeing - 사용자에게 할당된 로빙 정보 2. GET /api/stats/{robeing_id} - 특정 로빙의 스탯 조회 ``` #### 2. 프론트엔드 수정 계획 - 하드코딩된 로빙 ID를 동적으로 변경 - 사용자별 로빙 정보 조회 로직 추가 - 실시간 레벨 정보 표시 --- ## 오후 4시 50분 ### 구현 작업 #### 1. robeing-api.ts 수정 ```typescript // 새로운 함수 추가 export async function getUserRobeing(): Promise<{ robeing_id: string; robeing_url: string; } | null> { // workspace_member에서 사용자의 로빙 조회 } export async function getRobeingStats(robeingId: string): Promise<{ level: number; experience: number; // ... }> { // 특정 로빙의 스탯 조회 } ``` #### 2. game-layout.tsx 수정 ```typescript // 변경 전 const [robeingLevel, setRobeingLevel] = useState(1); // 하드코딩: LV.12 // 변경 후 const [userRobeingId, setUserRobeingId] = useState('rb10508_micro'); // 동적 할당: LV.{robeingLevel} // useEffect로 사용자별 로빙 정보 조회 useEffect(() => { const fetchUserRobeing = async () => { const robeingInfo = await getUserRobeing(); if (robeingInfo) { setUserRobeingId(robeingInfo.robeing_id); } }; fetchUserRobeing(); }, [user]); ``` #### 3. rb10508_micro endpoints.py 수정 ```python @router.get("/api/stats/{robeing_id}") async def get_stats(robeing_id: str): # PostgreSQL 직접 연결 conn = await asyncpg.connect( host='192.168.0.100', port=5432, user='robeings', password='robeings', database='main_db' ) # robeing_stats 테이블 조회 query = """ SELECT level, experience, stat_points, memory, compute, empathy, leadership, ethics FROM robeing_stats WHERE robeing_id = $1 """ row = await conn.fetchrow(query, robeing_id) ``` --- ## 오후 4시 55분 ### 추가 발견 사항 #### 포트 번호 불일치 문제 - skill-embedding 서비스 포트가 문서마다 다름 - 8015 → 8515로 통일 필요 - 영향받는 파일: - DOCS/300_architecture/360_로빙_컨테이너_경량화_전략.md - robeing-monitor/README.md - robeing-monitor/docker-compose.yml - skill-embedding/.env.example --- ## 오후 5시 00분 ### Git 푸시 작업 #### 푸시된 저장소들 1. **frontend-customer** ✅ - 사용자별 로빙 동적 할당 구현 - getUserRobeing(), getRobeingStats() 함수 추가 2. **rb10508_micro** ✅ - /api/stats/{robeing_id} DB 조회 구현 - PostgreSQL 직접 연결 로직 추가 3. **DOCS** ✅ - 포트 번호 수정 (8015 → 8515) - 각종 문서 업데이트 4. **skill-embedding** ✅ - .env.example 포트 번호 수정 5. **robeing-monitor** ✅ - README.md, docker-compose.yml 포트 수정 --- ## 교훈 ### 1. 시스템 구조 이해의 중요성 - 단순한 레벨 표시 문제가 아닌 전체 아키텍처 이해 필요 - users → workspace_member → robeing_stats 관계 파악 필수 - 다중 로빙 체계와 사용자 매핑 구조 이해 ### 2. 하드코딩 제거의 필요성 - 기존: 모든 사용자가 rb10508_micro 사용 - 개선: 사용자별 동적 로빙 할당 - 원칙: FUNCTIONAL PROGRAMMING 100%, NO HARDCODING 0% ### 3. API 설계 일관성 - RESTful 패턴 준수 - 명확한 엔드포인트 네이밍 - 에러 처리 및 기본값 제공 ### 4. 문서와 코드 동기화 - 포트 번호 등 설정값 일관성 유지 - 여러 파일에 분산된 설정 통일 - 변경사항 발생 시 관련 문서 모두 업데이트 ### 5. 점진적 마이그레이션 - 기본값 제공으로 하위 호환성 보장 - API 실패 시 fallback 처리 - 사용자 경험 중단 없이 개선 --- ## 향후 개선 사항 1. **Gateway API 통합** - 현재: 프론트엔드가 직접 로빙 호출 - 개선: Gateway를 통한 라우팅 2. **캐싱 추가** - 로빙 정보는 자주 변경되지 않음 - localStorage 또는 메모리 캐싱 활용 3. **실시간 업데이트** - 현재: 30초마다 폴링 - 개선: WebSocket으로 실시간 동기화 4. **로빙 상태 모니터링** - robeing-monitor 활용도 증대 - 중앙집중식 상태 관리 강화 --- **문서 끝**