diff --git a/troubleshooting/250914_admin_robeing_monitor_schema_error.md b/troubleshooting/250914_admin_robeing_monitor_schema_error.md index e91e741..ac41580 100644 --- a/troubleshooting/250914_admin_robeing_monitor_schema_error.md +++ b/troubleshooting/250914_admin_robeing_monitor_schema_error.md @@ -50,13 +50,82 @@ monitor_url = os.getenv("MONITOR_URL", "http://192.168.219.52:9024") - `GET /healthz` - 헬스체크 (정상) ## 상태 -✅ 해결됨 - 2025-09-15 +✅ 해결됨 - 2025-09-19 -## 해결 내역 -- RobeingStats 테이블: robeing_id → robeing_container_id 수정 +## 이전 해결 시도 (2025-09-15) +- robeing 테이블 관련 코드: robeing_id → robeing_container_id 수정 시도 - ConversationLog 테이블: robeing_id → robeing_container_id 수정 -- SQLAlchemy 쿼리: 모든 참조 수정 -- API 테스트: 500 에러 없음 확인 (최근 1시간) +- SQLAlchemy 쿼리: 일부 수정 +- 결과: /api/stats는 일시적 해결, /api/items/gmail은 미해결 + +## 2025-09-19 최종 해결 + +### 해결 내역 +1. **첫 번째 수정** (커밋 9f302f0): + - gmail_token 조회 시 user 테이블과 JOIN + - WHERE `u.oauth_id = $1` 사용 + - robeing 조회 시 `robeing_container_id` 사용 + +2. **두 번째 수정** (커밋 d76f2b7): + - 엔드포인트 중복 경로 제거 (`/items/gmail` 중복 선언 제거) + - unequip API의 slack_user_id 참조도 user JOIN으로 변경 + - 모든 gmail_token 조회를 user.oauth_id 기준으로 통일 + +### 테스트 결과 +- `/api/items/gmail` 200 OK 응답 확인 +- DB 스키마 에러 없음 +- 서버 자동 배포 완료 (17:06:30) + +## 2025-09-19 문제 재발견 및 명확화 (해결 전 상태) + +### 실제로는 두 개의 별개 문제 +1. **robeing 테이블 문제** (2025-09-15 부분 해결) + - 엔드포인트: `/api/stats/{robeing_id}` + - 원인: robeing.robeing_id 컬럼 없음 (실제: id, robeing_container_id) + - 상태: 일부 해결됨 + +2. **gmail_token 테이블 문제** (2025-09-19 신규 발견) + - 엔드포인트: `/api/items/gmail` + - 에러: `asyncpg.exceptions.UndefinedColumnError` + - 원인: gmail_token.robeing_id, gmail_token.slack_user_id 컬럼 없음 + - 컨테이너 ID: 2e52e648f02f + +### 확인된 테이블 구조 (51123 서버 PostgreSQL - 2025-09-19 재확인) +```sql +-- robeing 테이블 +id | uuid (PK) +robeing_container_id | varchar(64) -- 'rb8001' 형태의 값 +level, experience, memory 등 | integer +-- robeing_id 컬럼 없음 + +-- gmail_token 테이블 (현재 0 rows) +id | uuid (PK) +user_id | uuid (user 테이블 FK) +token_data | jsonb +equipped_to | varchar(50) -- 현재 값 없음 +is_equipped | boolean +-- robeing_id, slack_user_id, robeing_container_id 컬럼 없음 + +-- user 테이블 +id | uuid (PK) +oauth_id | varchar -- Slack ID ('U'로 시작) 또는 Google ID +-- 총 14명: Slack 8명, Google 6명 +``` + +### robeing-monitor 코드 문제점 (구체적 위치) +1. `/app/state/database.py`: + - SQLAlchemy 모델이 Integer PK 정의 (실제 DB는 UUID) + - RobeingStats는 클래스명, 실제 테이블은 robeing + +2. `/app/api/items.py` 에러 발생 지점: + - 101행: SELECT에서 `robeing_id,` 조회 → 컬럼 없음 에러 + - 108행: WHERE `slack_user_id = $1` → 컬럼 없음 + - 130행: `row['robeing_id']` 접근 시도 + - 207행: `equipped_to = request.robeing_id` 설정 (이건 작동) + +3. 실제 필요한 JOIN: + - gmail_token.user_id = user.id + - WHERE user.oauth_id = {slack_id} ## 2025-09-15 업데이트 @@ -94,18 +163,34 @@ SELECT robeing.id AS robeing_id_1, robeing.robeing_id AS rob... - 존재하지 않는 robeing.robeing_id 컬럼도 조회 시도 - **원인**: robeing-monitor의 SQLAlchemy 모델에 id와 robeing_id 둘 다 정의됨 -### 해결 방안 -**robeing-monitor 수정 필요 파일**: -- `/home/admin/ivada_project/robeing-monitor/app/state/database.py` -- `/home/admin/ivada_project/robeing-monitor/app/state/state_service.py` +### 해결 방안 (2025-09-19 최종) -**수정 내용**: -1. 테이블명: `robeing_stats` → `robeing` -2. 컬럼명: `robeing_id` → `robeing_container_id` -3. SQLAlchemy 모델 정의 수정 +**즉시 수정 가능한 부분 (items.py)**: +```python +# 101행: robeing_id, 제거 또는 equipped_to로 변경 +SELECT id, user_id, equipped_to, is_equipped, token_data... + +# 108행: slack_user_id를 user JOIN으로 변경 +FROM gmail_token gt +JOIN "user" u ON gt.user_id = u.id +WHERE u.oauth_id = $1 + +# 130행: row['robeing_id'] → row.get('equipped_to')로 변경 +``` + +**구조적 개선 필요**: +- database.py: Integer → UUID 타입 수정 +- 모든 robeing_id 참조를 id 또는 robeing_container_id로 통일 + +**로컬 작업 절차**: +1. robeing-monitor 레포 clone +2. 위 수정사항 적용 +3. Git push → 51124 자동 배포 +4. 테스트: `curl http://192.168.219.52:9024/api/items/gmail` **테스트**: ```bash # 51124 서버에서 curl http://192.168.219.52:9024/api/stats/rb8001 +curl http://192.168.219.52:9024/api/items/gmail ```