# rb8001 대화 히스토리 구현 트러블슈팅 ## 작성일: 2025-09-02 ## 작성자: 51123 서버 관리자 ## 대상: rb8001 카톡 스타일 대화 히스토리 ## 최종 상태: ✅ 해결 완료 --- ## 1. 초기 계획과 실제 구현의 차이 ### 1.1 잘못된 초기 계획 - **착각**: `/api/messages` 엔드포인트 추가하려 함 - **실제**: `/api/history`가 정답 (rb10508_micro 문서 확인 미흡) - **원인**: 250818 문서를 제대로 읽지 않음 ### 1.2 놓친 문서 확인 - Frontend 응답 형식 확인 안 함 (robeing-api.ts:154-161) - Gateway 라우팅 구조 확인 안 함 - rb10508_micro 구현 내용 상세 확인 미흡 --- ## 2. Gateway 라우팅 문제 ### 2.1 문제 상황 ```bash # Frontend 요청 GET /gateway/api/history?limit=1 # 응답 {} # 빈 객체 (content-length: 2) ``` ### 2.2 원인 분석 - Gateway에 `/api/history` 라우팅 없었음 - `/api/config`는 있었지만 `/api/history`는 누락 ### 2.3 해결 - Gateway main.py에 `/api/history` → rb8001 프록시 라우팅 추가 --- ## 3. UUID 변환 문제 ### 3.1 잘못된 추측 - **추측**: users 테이블 id가 integer - **실제**: users.id는 UUID 타입 - **확인 방법**: `\d users` 명령으로 확인 필요했음 ### 3.2 Gateway UUID 변환 제거 - JWT의 sub 필드는 이미 UUID - username 변환 시도가 불필요했음 - 직접 UUID 전달로 해결 ### 3.3 변수명 혼란 (2025-09-02 추가) - **현재 상태**: Gateway에서 `x_user_id` 변수명 사용하지만 실제로는 UUID 값 저장 - **혼란 요소**: - 변수명이 `x_user_id`지만 JWT sub의 UUID를 그대로 사용 - `get_user_by_username()` 함수 정의되어 있으나 실제 사용 안 함 - 주석과 변수명이 실제 값(UUID)과 불일치 - **작동**: 정상 (UUID를 그대로 전달하므로 문제 없음) - **주의**: 향후 코드 수정 시 변수명 때문에 착각 가능 --- ## 4. JWT Authorization 헤더 미전달 ### 4.1 문제 상황 ```python # rb8001 응답 {"detail": "Invalid authentication credentials"} # 401 Unauthorized ``` ### 4.2 원인 - Gateway가 X-User-Id 헤더만 전달 - Authorization 헤더 전달 안 함 - rb8001은 JWT 토큰 검증 필요 ### 4.3 해결 ```python # Gateway main.py Line 463 headers = { "X-User-Id": x_user_id, "Authorization": request.headers.get("Authorization") # 추가 } ``` --- ## 5. SQL 파라미터 파싱 에러 ### 5.1 에러 메시지 ``` syntax error at or near ":" WHERE user_id = :user_id::uuid ``` ### 5.2 원인 분석 - SQLAlchemy text()는 `:user_id`를 파라미터로 인식 - PostgreSQL `::uuid` 캐스팅과 충돌 - `:user_id::uuid` 전체를 하나의 토큰으로 파싱 ### 5.3 해결 방법 ```sql -- 잘못된 문법 WHERE user_id = :user_id::uuid -- 올바른 문법 (괄호로 분리) WHERE user_id = (:user_id)::uuid ``` --- ## 6. Frontend 응답 형식 불일치 ### 6.1 Frontend 기대 형식 ```typescript { messages: Array<{ id: string; text: string; sender: 'user' | 'robeing'; timestamp: string; }>; has_more: boolean; } ``` ### 6.2 rb8001 초기 반환 형식 ```json { "user_message": "...", "robeing_response": "...", "timestamp": "..." } ``` ### 6.3 해결 - DB 각 row를 2개 메시지로 분리 (user, robeing) - text, sender, timestamp 형식으로 변환 --- ## 7. 전체 작업 순서 (실제) ### 7.1 rb8001 백엔드 1. ✅ config.py 환경변수 추가 (MESSAGE_BATCH_SIZE=30) 2. ✅ database.py get_paginated_conversations() 구현 3. ❌ `/api/messages` 잘못 추가 → ✅ `/api/history`로 수정 4. ✅ SQL 문법 수정: `(:user_id)::uuid` ### 7.2 Gateway 1. ✅ `/api/history` 라우팅 추가 2. ✅ UUID 변환 제거 (JWT sub 직접 사용) 3. ✅ Authorization 헤더 전달 추가 ### 7.3 Frontend - 수정 불필요 (이미 250818에 구현됨) --- ## 8. 교훈 ### 8.1 문서 확인의 중요성 - 기존 구현 문서 먼저 상세히 읽기 - Frontend 코드 확인 후 백엔드 작업 - Gateway 라우팅 구조 먼저 파악 ### 8.2 테스트 우선 - curl로 직접 테스트 - JWT 토큰 생성해서 확인 - 로그 확인 필수 ### 8.3 추측 금지 - DB 스키마는 직접 확인 - 에러 메시지 정확히 읽기 - 문서화된 내용 신뢰 --- ## 9. 최종 작동 확인 ### 9.1 테스트 결과 ```bash # Gateway 통해 요청 GET /gateway/api/history?limit=30 Authorization: Bearer {JWT_TOKEN} # 정상 응답 { "messages": [...], "has_more": true } ``` ### 9.2 Frontend - 무한 스크롤 정상 작동 - 날짜 구분선 표시 - 대화 히스토리 로드 성공 --- ## 10. 참고 문서 - plans/250901_rb8001_chat_history_implementation_plan.md (완료) - troubleshooting/250818_happybell80_대화히스토리구현.md (rb10508_micro) - 300_architecture/sequences/chat_history_flow.md (신규 작성)