DOCS/troubleshooting/250827_UUID_username_혼용_CRITICAL.md

220 lines
6.1 KiB
Markdown

# UUID vs Username 혼용 - CRITICAL 시스템 전체 ID 체계 혼란
## 작성일: 2025-08-27
## 작성자: 51123 서버 관리자
## 상태: 🔴 CRITICAL - 즉시 해결 필요
## 영향 범위: 전체 시스템 (Auth, Gateway, Frontend, rb8001, DB)
## 위험 수준: 매우 높음
---
## 1. 문제 요약
### 🚨 핵심 문제
**시스템 전체가 UUID와 username을 구분하지 못해 데이터 무결성 파괴**
- JWT `sub` 클레임에 UUID 대신 username 저장
- Frontend가 하드코딩된 문자열 사용 ('test_user', 'default_user')
- DB에 UUID 대신 username/slack_id 저장되어 외래키 제약 위반
### 실제 사례
- User: happybell80
- UUID: 1e16e9d5-59f3-54da-a661-8abeabff4230 (UUID4 랜덤 생성)
- JWT sub: "happybell80" (username, UUID 아님)
- ChromaDB user_id: "happybell80" (username으로 저장됨)
- PostgreSQL: "Non-UUID user_id" 로그 발생
- conversation_logs: user_id NULL, slack_user_id에 우회 저장
---
## 2. 영향 분석
### 2.1 auth-server (51123)
```python
# /home/admin/auth-server/app/providers/gmail.py:208-209
jwt_token = create_access_token(data={
"sub": username, # 🔴 UUID 대신 username
"email": user_email,
"name": user_name,
"username": username,
})
```
**문제**: JWT 표준에서 `sub`는 unique identifier여야 하는데 username 사용
### 2.2 robeing-gateway (51123) - 확인 완료
```python
# /home/admin/robeing-gateway/app/main.py:232-235
user_info = await get_user_by_username(x_user_id)
if user_info:
user_uuid = user_info['user_id'] # DB 조회로 UUID 획득
# database.py:184
SELECT id::text as user_id # PostgreSQL UUID를 문자열로 변환
```
**확인된 사항**:
- username → UUID 변환은 DB 조회로만 수행 (계산된 변환 없음)
- UUID4 형식만 사용 (UUID5 사용 안 함)
- users 테이블에 username 없으면 변환 실패
### 2.3 rb8001 (51124) - 확인 완료
```python
# auth.py:36
user_id = payload.get("sub") # JWT sub(username)를 그대로 사용
# UUID 변환 없이 ChromaDB에 저장
metadata={"user_id": user_id} # username이 저장됨
```
**확인된 문제**:
- ChromaDB에 "happybell80" (username) 형식으로 저장
- PostgreSQL 저장 시 "Non-UUID user_id" 에러 로그 발생
- user_id NULL, slack_user_id로 우회 저장
### 2.4 Frontend - 확인 완료
```typescript
// robeing-api.ts:157
const userId = localStorage.getItem('user_id') || 'default_user';
// localStorage의 'user_id'는 Slack ID (U0925SXQFDK 형식)
```
**확인된 문제**:
- localStorage 'user_id' = Slack ID (예: U0925SXQFDK)
- JWT sub도 아니고 UUID도 아님
- 완전히 다른 체계 사용 중
### 2.5 Database
```sql
-- conversation_logs 테이블
user_id UUID -- UUID 타입 요구
slack_user_id VARCHAR(100) -- username이 여기 저장됨
-- 실제 데이터
user_id: NULL -- UUID 아니라서 저장 실패
slack_user_id: 'happybell80' -- 우회 저장
```
---
## 3. 근본 원인
### 3.1 설계 문제
- user_id, username, slack_id 개념 미구분
- UUID 사용 표준 부재
- 타입 검증 없는 문자열 전달
### 3.2 구현 문제 (확인 완료)
- auth-server: JWT `sub`에 username 사용 (UUID 대신)
- Gateway: DB 조회로만 UUID 변환 (실패 시 원래 값 전달)
- Frontend: localStorage에 Slack ID 저장 (UUID도 username도 아님)
- rb8001: JWT `sub`를 변환 없이 그대로 user_id로 사용
- skill-email: slack_user_id 컬럼으로 Slack ID 조회
---
## 4. 해결 방안
### 4.1 긴급 조치 (Phase 1)
#### auth-server 수정
```python
# gmail.py:208 수정 필요
jwt_token = create_access_token(data={
"sub": str(user.id), # UUID 사용
"username": username, # username은 별도 필드
"email": user_email,
"name": user_name,
})
```
#### Gateway username → UUID 매핑
```python
# 이미 구현되어 있음 (get_user_by_username)
# 하지만 JWT sub가 UUID면 불필요
```
### 4.2 중기 개선 (Phase 2)
#### Frontend localStorage 정리
```typescript
// JWT 디코딩 후
const payload = jwt_decode(token);
localStorage.setItem('user_id', payload.sub); // UUID
localStorage.setItem('username', payload.username);
```
#### rb8001 JWT 처리 수정
```python
# auth.py 수정
user_uuid = payload.get("sub") # UUID
username = payload.get("username") # username
```
### 4.3 장기 개선 (Phase 3)
- 전체 시스템 ID 타입 표준화
- UUID 전용 타입 클래스 생성
- 타입 검증 미들웨어 추가
---
## 5. 테스트 시나리오
### 5.1 현재 상태 확인 (검증 완료)
```bash
# JWT payload 확인
curl -X POST http://localhost:9000/auth/gmail/login
# sub: "happybell80" (username)
# DB 확인
SELECT id, username FROM users WHERE username='happybell80';
# UUID: 1e16e9d5-59f3-54da-a661-8abeabff4230 (UUID4)
# conversation_logs 확인
SELECT user_id, slack_user_id FROM conversation_logs;
# user_id: NULL (UUID 타입이라 username 저장 실패)
# slack_user_id: 'happybell80' (우회 저장)
# PostgreSQL 로그
# "Non-UUID user_id" 에러 발생
```
### 5.2 수정 후 검증
- JWT `sub` 필드가 UUID 형식 (36자)
- conversation_logs.user_id에 UUID 저장
- ChromaDB metadata.user_id가 UUID
---
## 6. 영향도 및 우선순위
| 컴포넌트 | 영향도 | 우선순위 | 담당 |
|---------|-------|---------|-----|
| auth-server JWT | 🔴 극심 | 1 | 로컬 개발자 |
| Frontend localStorage | 🔴 극심 | 2 | 로컬 개발자 |
| rb8001 JWT 처리 | 🟡 높음 | 3 | 로컬 개발자 |
| Gateway 매핑 | 🟢 중간 | 4 | 이미 구현됨 |
---
## 7. 관련 문서
- [ID 체계 정리 (250826)](./250826_id_체계_정리_및_conversation_logs_문제_해결.md)
- [JWT 인증 구현 (250827)](./250827_JWT_인증_구현_COMPLETED.md)
- [Slack ID 표준화 (250826)](./250826_slack_id_column_standardization.md)
---
## 8. 결론
**현재 시스템은 UUID와 username을 구분하지 못해 데이터 무결성이 깨진 상태**
### 즉시 필요한 조치
1. auth-server: JWT `sub`에 UUID 사용
2. Frontend: localStorage에 UUID 저장
3. rb8001: UUID와 username 구분 처리
### 예상 작업 시간
- auth-server 수정: 30분
- Frontend 수정: 1시간
- rb8001 수정: 30분
- 테스트 및 검증: 1시간
- **총 예상: 3시간**
---
*작성 완료: 2025-08-27 15:45*