diff --git a/troubleshooting/250827_claude_conversation_log_user_mapping.md b/troubleshooting/250827_claude_conversation_log_user_mapping.md index e227c2f..0b8e2e2 100644 --- a/troubleshooting/250827_claude_conversation_log_user_mapping.md +++ b/troubleshooting/250827_claude_conversation_log_user_mapping.md @@ -1,130 +1,45 @@ -# 대화 로그 사용자 매핑 불일치 문제 +# 대화 로그 사용자 매핑 불일치 -## 발생일시 -2025-08-27 18:09 KST +## 상태: 해결 방안 제시 (2025-08-27) -## 문제 상황 -동일한 사용자(김종태/happybell80)가 서로 다른 채널(Slack/웹)로 접속 시 conversation_logs 테이블에 별개 사용자로 저장되는 문제 +## 문제 +같은 사용자가 Slack/웹 접속 시 각각 다른 ID로 저장 -### 증상 -```sql --- conversation_logs 테이블 데이터 -ID 51: Slack=U0925SXQFDK, UUID=None, Channel=C0920L68267 -ID 52: Slack=None, UUID=1e16e9d5-59f3-54da-a661-8abeabff4230, Channel=web -``` +### 현상 +- **Slack**: slack_user_id만 저장 (UUID NULL) +- **웹**: user_id(UUID)만 저장 (slack_user_id NULL) +- **결과**: 동일 사용자가 2명으로 분리 -같은 사용자임에도: -- Slack 접속: `slack_user_id`만 저장, `user_id`는 NULL -- 웹 접속: `user_id`(UUID)만 저장, `slack_user_id`는 NULL +## 원인 +- **Slack 경로**: JWT 없이 Slack ID만 사용 +- **웹 경로**: JWT에서 UUID만 추출 +- **State Service**: 두 ID를 연결하는 매픹 로직 없음 -## 원인 분석 +## 영향 +- 동일 사용자 통계 분리 +- 채널 간 대화 기록 단절 +- 개인화 컨텍스트 손실 -### 1. State Service 저장 로직 -State Service가 사용자 식별자를 통합하지 않고 있음: -- Slack 이벤트: slack_user_id만 전달 -- 웹 요청: JWT의 UUID만 전달 -- 두 식별자를 연결하는 매핑 로직 부재 +## 해결 방안: 분리 운영 -### 2. UUID 생성 규칙 -```python -# Slack ID → UUID 변환 규칙 -namespace = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') -user_uuid = str(uuid.uuid5(namespace, slack_user_id)) +### 선택한 방안 +- **Slack과 웹을 별도 체계로 운영** +- Slack: Slack ID + Slack 서명 검증 +- 웹: UUID + JWT 검증 -# 예시 -U0925SXQFDK → 1e16e9d5-59f3-54da-a661-8abeabff4230 -``` +### 구현 +1. conversation_logs 테이블 현 구조 유지 + - slack_user_id: Slack 사용자만 + - user_id: 웹 사용자만 -### 3. 데이터 흐름 -``` -Slack 경로: -Slack Event → rb8001 → State Service → DB (slack_user_id만) +2. 통계 조회 시 JOIN + - slack_user_mapping 테이블 활용 + - WHERE user_id = ? OR slack_user_id IN (SELECT...) -웹 경로: -Browser → Gateway → rb8001 → State Service → DB (UUID만) -``` - -## 영향도 -- **통계 불일치**: 동일 사용자가 2명으로 계산 -- **대화 연속성 손실**: 채널 간 대화 기록 분리 -- **개인화 실패**: 사용자별 컨텍스트 유지 실패 - -## 해결 방안 - -### Option 1: State Service에서 매핑 (권장) -```python -# State Service의 save_conversation 수정 -async def save_conversation(...): - # slack_user_id가 있으면 UUID로 변환 - if slack_user_id and not user_id: - user_id = slack_id_to_uuid(slack_user_id) - - # UUID가 있으면 slack_user_id 조회 - elif user_id and not slack_user_id: - slack_user_id = await get_slack_id_from_uuid(user_id) -``` - -### Option 2: rb8001에서 사전 변환 -```python -# rb8001의 state_client.save_conversation 호출 전 -if slack_user_id: - user_uuid = slack_id_to_uuid(slack_user_id) -else: - user_uuid = jwt_user_id - slack_user_id = await lookup_slack_id(user_uuid) - -await state_client.save_conversation( - user_id=user_uuid, - slack_user_id=slack_user_id, - ... -) -``` - -### Option 3: DB 트리거로 자동 채우기 -```sql -CREATE OR REPLACE FUNCTION fill_user_mapping() -RETURNS TRIGGER AS $$ -BEGIN - -- slack_user_id만 있으면 user_id 채우기 - IF NEW.slack_user_id IS NOT NULL AND NEW.user_id IS NULL THEN - -- UUID 생성 로직 - NEW.user_id = generate_uuid_from_slack(NEW.slack_user_id); - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; -``` - -## 검증 쿼리 -```sql --- 불일치 건수 확인 -SELECT COUNT(*) as total, - COUNT(user_id) as has_uuid, - COUNT(slack_user_id) as has_slack, - COUNT(*) FILTER (WHERE user_id IS NULL) as missing_uuid, - COUNT(*) FILTER (WHERE slack_user_id IS NULL) as missing_slack -FROM conversation_logs -WHERE timestamp > NOW() - INTERVAL '7 days'; - --- 동일 사용자 중복 확인 -SELECT u.username, u.email, - COUNT(DISTINCT cl.user_id) as uuid_count, - COUNT(DISTINCT cl.slack_user_id) as slack_count -FROM users u -LEFT JOIN conversation_logs cl ON u.id = cl.user_id -GROUP BY u.username, u.email -HAVING COUNT(DISTINCT cl.slack_user_id) > 1; -``` - -## 교훈 -1. **다채널 시스템에서는 사용자 식별자 통합이 필수** -2. **State Service는 모든 채널의 사용자 매핑을 처리해야 함** -3. **DB 설계 시 다중 식별자 고려 필요** - -## 참고 -- users 테이블: UUID 기반 사용자 정보 -- slack_user_mapping 테이블: Slack-UUID 매핑 (활용 안됨) -- conversation_logs: 실제 대화 저장 테이블 +## 결론 +- 분리 운영이 가장 현실적 +- 각 채널 특성에 맞는 인증 체계 유지 +- 필요 시 slack_user_mapping 테이블로 통합 조회 --- *작성: Claude*