- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동 - book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서) - 빈 폴더 제거 (journey/assets/*)
4.8 KiB
4.8 KiB
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 문제 상황
# 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 문제 상황
# rb8001 응답
{"detail": "Invalid authentication credentials"} # 401 Unauthorized
4.2 원인
- Gateway가 X-User-Id 헤더만 전달
- Authorization 헤더 전달 안 함
- rb8001은 JWT 토큰 검증 필요
4.3 해결
# 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 해결 방법
-- 잘못된 문법
WHERE user_id = :user_id::uuid
-- 올바른 문법 (괄호로 분리)
WHERE user_id = (:user_id)::uuid
6. Frontend 응답 형식 불일치
6.1 Frontend 기대 형식
{
messages: Array<{
id: string;
text: string;
sender: 'user' | 'robeing';
timestamp: string;
}>;
has_more: boolean;
}
6.2 rb8001 초기 반환 형식
{
"user_message": "...",
"robeing_response": "...",
"timestamp": "..."
}
6.3 해결
- DB 각 row를 2개 메시지로 분리 (user, robeing)
- text, sender, timestamp 형식으로 변환
7. 전체 작업 순서 (실제)
7.1 rb8001 백엔드
- ✅ config.py 환경변수 추가 (MESSAGE_BATCH_SIZE=30)
- ✅ database.py get_paginated_conversations() 구현
- ❌
/api/messages잘못 추가 → ✅/api/history로 수정 - ✅ SQL 문법 수정:
(:user_id)::uuid
7.2 Gateway
- ✅
/api/history라우팅 추가 - ✅ UUID 변환 제거 (JWT sub 직접 사용)
- ✅ Authorization 헤더 전달 추가
7.3 Frontend
- 수정 불필요 (이미 250818에 구현됨)
8. 교훈
8.1 문서 확인의 중요성
- 기존 구현 문서 먼저 상세히 읽기
- Frontend 코드 확인 후 백엔드 작업
- Gateway 라우팅 구조 먼저 파악
8.2 테스트 우선
- curl로 직접 테스트
- JWT 토큰 생성해서 확인
- 로그 확인 필수
8.3 추측 금지
- DB 스키마는 직접 확인
- 에러 메시지 정확히 읽기
- 문서화된 내용 신뢰
9. 최종 작동 확인
9.1 테스트 결과
# 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 (신규 작성)