# UUID 체계 전환 및 대화 저장 오류 해결

## 작성일: 2025-09-11
## 최종 수정일: 2025-09-24
## 작성자: happybell80

---

## 문제 상황
1. **PostgreSQL 테이블명 단수형 통일 후 발생한 연쇄 문제**
   - conversation_log 테이블 id 자동증가 미작동
   - Slack ID를 UUID 필드에 저장 시도로 타입 오류
   - Gateway와 rb8001 간 UUID 전달 미구현

2. **주요 오류 메시지**
   ```
   - null value in column "id" of relation "conversation_log" violates not-null constraint
   - invalid input syntax for type uuid: "U09C98KBGHX"
   - 'MemoryManager' object has no attribute 'collection_name'
   - 'RobeingRouter' object has no attribute 'is_valid_uuid'
   ```

## 해결 과정

### 1. rb8001 UUID 체계 전환
- app/router/router.py: X-User-Id 헤더 우선 사용 처리

### 2. conversation_log id 자동증가 해결
- 테이블에 SERIAL 없어 MAX(id)+1로 수동 생성 (`ensure_conversation_log_sequence_aligned()` 도입, rb8001/app/state/database.py)
- 2025-12-04: save_conversation()에서 이 함수를 동기 호출하도록 정리 (await 제거), 향후에는 앱 시작 시 1회 + APScheduler 주기 실행으로 이동 예정

### 3. Gateway Slack ID→UUID 변환
- oauth_id와 oauth_provider='slack' 조건으로 조회

### 4. Slack Handler UUID 처리
- X-User-Id 헤더에서 UUID 추출 및 context 저장

## 데이터 흐름 정리

### Frontend → Gateway → rb8001
1. JWT에서 UUID 추출: `3550cef6-63e1-4ceb-8802-a25c9d1c6917`
2. X-User-Id 헤더로 전달
3. 정상 저장 및 조회

### Slack → Gateway → rb8001  
1. Slack ID: `U09C98KBGHX`
2. Gateway에서 oauth_id로 UUID 조회: `53529291-5050-4daa-89fb-008b546feb63`
3. X-User-Id 헤더로 전달
4. 정상 저장 및 조회

## 수정된 파일
- rb8001/app/router/router.py
- rb8001/app/state/database.py
- rb8001/app/router/slack_handler.py
- robeing-gateway/app/main.py

## 결과 확인
- **총 545개 대화 저장**, NULL user_id 0개
- **오늘 2개 저장**: 김종태(53529291-5050-4daa-89fb-008b546feb63), frontend 사용자
- **Gateway UUID 변환 성공**: Slack ID → UUID 정상 작동

## 추가 수정 사항
### 뉴스 중복 방지
- skill-news fallback 제거: 새 뉴스 없을 때 API 호출 제거

### 헬스체크 로그 레벨 조정
- DEBUG 레벨로 변경하여 로그 노이즈 감소

## 교훈
- DB 스키마와 코드 모델 일치 필수
- UUID 체계 전환 시 모든 경로 점검
- 헤더 기반 인증 정보는 일관된 위치에서 처리

---

## 2025-09-24 Gateway UUID 변환 실패 시 403 차단

### 구현 방안: 라우터 분리

#### 파일 구조
```
robeing-gateway/app/
├── routers/slack.py         # Slack 엔드포인트
├── services/slack_proxy.py  # UUID 변환 및 포워딩
└── exceptions.py            # UserNotRegisteredError
```

#### 핵심 로직
- **url_verification**: 항상 200 반환 (UUID 체크 제외)
- **이벤트/인터랙티브**: UUID 변환 실패 시 403 반환
- **X-User-Id 헤더**: UUID 변환 성공 시에만 추가

### 영향 범위
- **변경 없음**: nginx, Slack 앱 설정, rb8001
- **필수 작업**: user 테이블에 oauth_id 사전 등록

---

## 2025-09-24 UUID 중심 원칙 확립

### 원칙
- 모든 내부 로직은 UUID만 사용
- Gateway가 UUID 변환 책임
- UUID 없으면 403 차단

### 영향받는 서비스
- **rb8001:8001**: X-User-Id 헤더 필수
- **Slack 인터랙티브**: UUID 없으면 버튼 액션 실패
- **예외**: url_verification은 200 반환 필수

### 필수 작업
1. Gateway에서 UUID 변환 실패 시 403 반환
2. user 테이블에 Slack 사용자 사전 등록
3. ChromaDB 검색 시 UUID만 사용
- 디버깅 시간 단축 (명확한 에러로 원인 파악 용이)

### 관련 문제
- Slack 요청은 OAuth 인증 없이 직접 `/slack/events`로 전송
- JWT 토큰 없이 Slack 웹훅이 직접 호출
- DB에서 oauth_id로 UUID 조회 시 oauth_provider='slack' 조건 필수
