DOCS/troubleshooting/250901_rb8001_chat_history_implementation_issues.md

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 백엔드

  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 테스트 결과

# 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 (신규 작성)