- gmail_tokens → gmail_token (33 files) - companies → company (17 files) - conversation_logs → conversation_log (27 files) - workspace_members → workspace_member (28 files) All table names now match the actual PostgreSQL schema
9.8 KiB
9.8 KiB
rb8001 PostgreSQL 대화 저장 UUID 타입 에러
작성일: 2025-08-26
작성자: 51124 서버 담당
상태: ✅ 완전 해결 (ChromaDB ✅, PostgreSQL ✅, Foreign key ✅)
영향: PostgreSQL conversation_log 정상 저장
최종 업데이트: 2025-08-26 19:30
1. 문제 상황
1.1 증상
- PostgreSQL: UUID 타입 에러로 저장 실패
- ChromaDB: 정상 저장 성공 ✅
- 대화 이력: ChromaDB는 저장되나 PostgreSQL 조회 불가
- 영향 범위: 모든 비-UUID 형식 user_id 사용자
1.2 실제 테스트 결과
# 테스트 요청
curl -X POST http://localhost:8001/api/message \
-d '{"text": "테스트 저장 확인", "user_id": "test_user_123"}'
# 로그 확인
INFO: ChromaDB: Conversation saved for user test_user_123
ERROR: PostgreSQL save failed: invalid input syntax for type uuid: "test_user_123"
# 실제 에러
psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type uuid: "test_user_123"
LINE 1: ... VALUES ('rb8001', 'test_user_123', 'web', ...
2. 원인 분석
2.1 실제 저장 로직 구현 상태
| 구성요소 | 상태 | 실제 동작 |
|---|---|---|
| router.py:290-297 | _save_conversation() 호출됨 |
✅ 정상 호출 |
| router.py:309-365 | _save_conversation() 구현됨 |
✅ 구현 완료 |
| memory_manager.store_memory() | ChromaDB 저장 | ✅ 성공 |
| PostgreSQL 저장 | UUID 타입 체크 | ❌ 타입 에러 |
2.2 ChromaDB 상태
- 정상 작동:
robeing_rb8001_memories 컬렉션에 저장 성공→ 개선됨:rb8001_{user_uuid}사용자별 컬렉션 (2025-08-28) - 로그: "Stored memory: 852cb2556eb911413dfa2d33b76d04d1"
- 컬렉션 격리: ✅ 사용자별 분리 완료 (250828_UUID_통합_및_사용자_격리_계획.md)
- None 값 처리: ⚠️ ChromaDB는 metadata에 None 값 허용 안 함 → 필터링 필요 (250828_ChromaDB_metadata_None_error.md)
2.3 PostgreSQL 스키마 문제
-- conversation_log 테이블 스키마
user_id UUID -- 문제: UUID 타입만 허용
slack_user_id VARCHAR(100) -- 추가됨 (250826 문서)
-- 실제 저장 시도
INSERT INTO conversation_log (user_id, ...)
VALUES ('test_user_123', ...) -- 실패: UUID 형식 아님
3. 코드 분석
3.1 실제 구현된 저장 코드
# rb8001/app/router/router.py:290-297
async def _call_internal_llm(...):
# LLM 호출
result = await self.llm_service.process_request(llm_request)
# 저장 함수 호출 (실제로 구현됨)
if result.get("success") and result.get("content"):
await self._save_conversation(
message=message,
response=result.get("content"),
user_id=user_id, # 여기서 "test_user_123" 같은 문자열 전달
channel=channel,
intent=task_type,
confidence=result.get("confidence", 0.8)
)
return result
# router.py:338-344
conversation_log = ConversationLog(
robeing_id=settings.ROBEING_ID,
user_id=user_id, # UUID 타입 필요한데 문자열 전달 -> 에러
channel_id=channel,
message=message,
response=response,
...
)
3.2 robeing-monitor 엔드포인트도 404
curl -X POST http://localhost:9024/api/logs/rb8001/conversation
# 404 Not Found
4. 영향도
4.1 기능 영향
- 대화 이력 조회: 불가능
- 컨텍스트 유지: 불가능 (매 대화가 새 대화)
- 학습/개선: 불가능 (데이터 없음)
- 감사 로그: 없음
4.2 서비스별 상태
| 서비스 | 대화 기능 | ChromaDB 저장 | PostgreSQL 저장 |
|---|---|---|---|
| Slack (U091UNVE41M) | ✅ 작동 | ✅ 성공 | ❌ UUID 에러 |
| Frontend (test_user) | ✅ 작동 | ✅ 성공 | ❌ UUID 에러 |
| DM | ✅ 작동 | ✅ 성공 | ❌ UUID 에러 |
5. 해결 방안
5.1 즉시 필요한 작업
- UUID 변환 로직 추가: Slack ID나 일반 문자열을 UUID로 변환
- slack_user_id 필드 활용: user_id 대신 slack_user_id 사용
- 스키마 수정 고려: user_id를 nullable로 만들기
5.2 코드 수정 예시
# rb8001/app/router/router.py의 _save_conversation() 수정
import uuid
async def _save_conversation(self, ...):
# UUID 변환 로직 추가
try:
# UUID 형식 체크
uuid.UUID(user_id)
user_uuid = user_id
except ValueError:
# UUID가 아니면 생성 또는 None
namespace = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
user_uuid = str(uuid.uuid5(namespace, user_id))
# PostgreSQL 저장 시
conversation_log = ConversationLog(
robeing_id=settings.ROBEING_ID,
user_id=user_uuid, # UUID 사용
slack_user_id=user_id if not is_uuid else None, # 원본 ID 저장
channel_id=channel,
message=message,
response=response,
...
)
6. 검증 방법
6.1 저장 확인
# 테스트 메시지 전송
curl -X POST http://localhost:8001/api/message \
-H "Content-Type: application/json" \
-d '{"text": "테스트", "user_id": "test_user"}'
# PostgreSQL 확인
psql -h localhost -p 5433 -U robeings -d main_db \
-c "SELECT * FROM conversation_log ORDER BY timestamp DESC LIMIT 1;"
# ChromaDB 확인 (수정 후)
docker exec rb8001 python -c "
from chromadb import PersistentClient
client = PersistentClient('/code/chroma_db')
print('Collections:', client.list_collections())
"
7. 주의사항
7.1 ChromaDB 복구
- 백업 없이 초기화 시 기존 데이터 손실
- 메타데이터 수동 복구 어려움
- 재생성이 더 안전할 수 있음
7.2 대용량 처리
- 저장 로직 추가 시 응답 지연 가능
- 비동기 처리 고려 필요
- 에러 시 응답은 정상 반환되도록
8. 관련 파일
51124 서버
/home/admin/ivada_project/rb8001/app/brain/state_client.py- 저장 함수/home/admin/ivada_project/rb8001/app/memory/manager.py- ChromaDB 관리/home/admin/ivada_project/rb8001/app/router/router.py- 라우팅 로직/home/admin/ivada_project/rb8001/main.py- 엔드포인트
데이터 위치
- ChromaDB:
/home/admin/ivada_project/rb8001/chroma_db/ - PostgreSQL:
main_db.conversation_log테이블
9. 예상 소요 시간
- 코드 수정: 30분
- 테스트: 30분
- ChromaDB 복구: 1시간 (재생성 시)
10. 우선순위
중간 - ChromaDB는 정상 작동하므로 기본 기능은 유지됨. PostgreSQL 저장만 실패
11. 수정 후 상태 (2025-08-26 19:00 업데이트)
- ChromaDB: ✅ 정상 저장 및 조회 가능
- PostgreSQL: ✅ UUID 변환 로직 추가로 정상 저장
12. 📊 테스트 결과 (2025-08-26 18:30)
12.1 ✅ 해결된 이슈
- 채팅 API: 정상 작동 (응답 받음)
- Stats API: rb8001 스탯 정상 조회 (undefined 없음)
- PostgreSQL 직접 삽입: UUID 형식으로 수동 삽입시 성공
12.2 ⚠️ 남은 문제
-
51124 서버 rb8001:
- conversation_log 저장 안됨 (최근 데이터 14시간 전)
- UUID 타입 에러로 PostgreSQL 저장 실패 중
- ChromaDB만 저장되고 PostgreSQL은 실패
-
✅ Gateway JWT 에러 (정상 동작 확인됨):
- "Not enough segments" - 잘못된 토큰 형식 거부
- 올바른 보안 동작 (잘못된 토큰 차단)
- 기본 사용자(default)로 처리되어 서비스 영향 없음
12.3 📝 확인 내역
| 항목 | 상태 | 결과 |
|---|---|---|
| 채팅 API | ✅ | 응답: "안녕하세요, 사용자님..." |
| Stats API | ✅ | rb8001 레벨 1, 경험치 0 |
| DB 직접 삽입 | ✅ | ID 23번으로 저장 성공 |
| 51124 자동 저장 | ❌ | 14시간 전 이후 저장 안됨 |
12.4 핵심 문제
51124 서버의 rb8001이 UUID 형식이 아닌 user_id를 보내서 PostgreSQL 저장 실패
12.5 해결 과정
1차 시도 (2025-08-26 19:00) - UUID 변환
✅ 적용된 해결책
- router.py:309-378 UUID 변환 로직 추가
- UUID가 아닌 경우 slack_user_mapping 테이블 조회
- 문제 발견: Foreign key 제약 위반 (users 테이블에 없는 UUID)
2차 해결 (2025-08-26 19:30) - Foreign key 처리
✅ 최종 해결책
-
router.py:344-391 users 테이블 확인 로직 추가
- UUID 형식 & users 테이블 존재 → user_id에 저장
- UUID 형식 & users 테이블 없음 → user_id는 NULL, slack_user_id에 저장
- 비-UUID (Slack ID, 문자열) → user_id는 NULL, slack_user_id에 저장
-
database.py:56 스키마 수정 유지
- slack_user_id 컬럼 (VARCHAR) - 원본 ID 보존
- user_id (UUID/NULL) - Foreign key 제약 준수
-
Git 커밋 및 배포
- 1차 커밋: 84d124a (UUID 변환)
- 2차 커밋: 5a0af8a (Foreign key 해결)
- Gitea Actions 자동 배포 → 51124 서버
12.6 최종 처리 로직
| 케이스 | users 테이블 | user_id 저장 | slack_user_id 저장 |
|---|---|---|---|
| 등록된 UUID 사용자 | ✅ 존재 | UUID 값 | NULL |
| 미등록 UUID | ❌ 없음 | NULL | UUID 값 |
| Slack ID (U0925SXQFDK) | - | NULL | U0925SXQFDK |
| 문자열 (test_user) | - | NULL | test_user |
| happybell80 | - | NULL | happybell80 |
12.7 검증된 장점
- ✅ Foreign key 제약 유지
- ✅ 모든 대화 저장 가능
- ✅ users 테이블 오염 방지
- ✅ slack_user_id로 사용자 추적 가능
- ✅ 나중에 사용자 등록 시 매핑 가능
12.8 ✅ 해결 완료
- 모든 이슈 해결됨:
- PostgreSQL UUID 저장: ✅ 해결 (Foreign Key 처리 완료)
- ChromaDB 저장: ✅ 정상 작동
- Gateway JWT: ✅ 정상 보안 동작 확인 (2025-08-26 21:40)