diff --git a/300_architecture/database/tables.md b/300_architecture/database/tables.md index c61dbb0..9e19152 100644 --- a/300_architecture/database/tables.md +++ b/300_architecture/database/tables.md @@ -1,7 +1,7 @@ # PostgreSQL 테이블 구조 ## 작성일: 2025-08-20 -## 최종 수정일: 2025-09-15 +## 최종 수정일: 2025-09-24 ## 데이터베이스: main_db --- @@ -11,7 +11,6 @@ ### company - **용도**: 회사 정보 - **Primary Key**: id (UUID) -- **레코드**: 2개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -24,7 +23,6 @@ ### team - **용도**: 팀 정보 - **Primary Key**: id (UUID) -- **레코드**: 2개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -37,7 +35,6 @@ ### user - **용도**: 시스템 사용자 정보 - **Primary Key**: id (UUID) -- **레코드**: 1개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -57,7 +54,6 @@ ### workspace_member - **용도**: 워크스페이스 멤버십 - **Primary Key**: id (UUID) -- **레코드**: 0개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -75,7 +71,6 @@ ### product - **용도**: 제품 정보 - **Primary Key**: id (UUID) -- **레코드**: 1개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -90,7 +85,6 @@ ### robeing - **용도**: 로빙 엔티티 정보 - **Primary Key**: id (UUID) -- **레코드**: 2개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -117,7 +111,6 @@ ### slack_workspace - **용도**: Slack 워크스페이스 정보 - **Primary Key**: id (UUID) -- **레코드**: 2개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -138,7 +131,6 @@ ### user_preference - **용도**: 사용자 개인 설정 - **Primary Key**: id (INTEGER) -- **레코드**: 0개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -155,7 +147,6 @@ ### gmail_token - **용도**: Gmail OAuth 토큰 - **Primary Key**: id (UUID) -- **레코드**: 0개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -180,7 +171,6 @@ ### conversation_log - **용도**: 대화 기록 - **Primary Key**: id (INTEGER) -- **레코드**: 0개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -198,7 +188,6 @@ ### news - **용도**: 뉴스 데이터 - **Primary Key**: id (UUID) -- **레코드**: 0개 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -208,11 +197,32 @@ | created_at | TIMESTAMPTZ | YES | CURRENT_TIMESTAMP | 생성 시각 | | updated_at | TIMESTAMPTZ | YES | CURRENT_TIMESTAMP | 수정 시각 | +### rb_news +- **용도**: 뉴스 발행 관리 +- **Primary Key**: id (UUID) + +| 컬럼명 | 타입 | NULL | 기본값 | 설명 | +|--------|------|------|--------|------| +| id | UUID | NO | gen_random_uuid() | 뉴스 ID | +| title | TEXT | NO | | 뉴스 제목 | +| url | TEXT | NO | | 뉴스 URL (UNIQUE) | +| summary | TEXT | YES | | 뉴스 요약 | +| slack_message_ts | VARCHAR(100) | YES | | Slack 메시지 타임스탬프 | +| slack_channel_id | VARCHAR(100) | YES | | Slack 채널 ID | +| is_published | BOOLEAN | YES | false | 발행 상태 | +| published_at | TIMESTAMPTZ | YES | | 발행 시각 | +| created_at | TIMESTAMPTZ | YES | now() | 생성 시각 | + +**인덱스**: +- `rb_news_pkey`: PRIMARY KEY (id) +- `rb_news_url_key`: UNIQUE (url) +- `idx_rb_news_url`: btree (url) +- `idx_rb_news_slack_message_ts`: btree (slack_message_ts) +- `idx_rb_news_created_at`: btree (created_at DESC) + ### team_document - **용도**: 팀 문서 RAG 시스템 - **Primary Key**: id (UUID) -- **레코드**: 0개 -- **생성일**: 2025-09-15 | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -238,9 +248,8 @@ ### naverworks_token - **용도**: NAVER WORKS OAuth 토큰 및 Passport 정보 - **Primary Key**: id (UUID) -- **Unique**: user_id (사용자당 하나의 토큰만) +- **Unique**: user_id - **Foreign Key**: user_id → user(id) ON DELETE CASCADE -- **레코드**: 1개 (2025-09-18 기준) | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| @@ -304,14 +313,6 @@ - **자동 갱신**: update_column_updated_at 트리거로 updated_at 자동 관리 - **UUID 기반**: 주요 테이블 모두 UUID 사용 -### 현재 데이터 상태 (2025-09-11) -- company: 2개 -- team: 2개 -- user: 1개 -- product: 1개 -- robeing: 2개 -- slack_workspace: 2개 -- 나머지 테이블: 비어있음 --- diff --git a/troubleshooting/250922_current_system_status_summary.md b/troubleshooting/250922_current_system_status_summary.md new file mode 100644 index 0000000..40d1619 --- /dev/null +++ b/troubleshooting/250922_current_system_status_summary.md @@ -0,0 +1,70 @@ +# 현재 시스템 상태 트러블슈팅 요약 + +## 일시: 2025-09-22 +## 작성자: 51123 서버 관리자 + +## 🔴 긴급 수정 필요 (Quick Wins) + +### 1. rb8001 EmailIntegration 버그 +- **위치**: `rb8001/app/skills/email_integration.py:210` +- **문제**: NaverWorks 토큰 조회 시 미정의 변수 `user_uuid` 사용 +- **수정**: `user_uuid` → `slack_id` 또는 `user_id`로 변경 +- **영향**: NaverWorks 이메일 기능 오류 + +### 2. UUID↔Slack ID 조회 엔드포인트 불일치 +- **문제**: gateway는 `/api/slack/{slack_id}/uuid`, 다른 서비스는 `/api/slack/mapping/{identifier}` 사용 +- **위치**: `robeing-gateway/app/main.py:468-515` +- **수정**: 하나의 엔드포인트로 통일 필요 + +### 3. 하드코딩 URL 제거 +- **위치**: `rb8001/app/skills/email_integration.py:39-47` +- **문제**: `http://192.168.219.45:9000` 하드코딩 +- **수정**: 환경변수로 교체 필요 + +## 🟠 시스템 로그 분석 결과 + +### nginx 문제점 +- 9월 16일 로그 권한 오류 (logrotate 시점) +- SSL handshake 오류 지속 (외부 스캔봇) +- upstream 연결 실패 (8000 vs 8100 포트 혼재) + +### 서비스 상태 +- **auth-server**: 정상 (불필요한 "default_value" 로그 출력) +- **robeing-gateway**: 정상 (과도한 헬스체크 빈도) +- **skill-news**: JSON 파일 수집 정상, DB 영속화 미동작 + +### 보안 이슈 +- Git 저장소 무단 접근 시도 (220.85.143.195) +- PHPUnit 취약점 스캔 지속 +- Slack webhook 이벤트 처리 간헐적 실패 + +## 🟡 DB 및 데이터 상태 + +### rb_news 테이블 +- 테이블 생성됨 +- skill-news JSON 파일에 데이터 있음 (컴퍼니엑스 뉴스 1건) +- DB 저장 로직 미동작 확인 필요 + +### robeing_stats +- robeing-monitor로 일원화 완료 +- rb8001 중복 구현 제거됨 + +### system_metrics +- 테이블 미존재로 수집 비활성화 +- frontend-base에서 early return 처리 + +## ✅ 완료된 항목 (검증됨) + +1. **GmailProvider 메서드 매핑**: `list_messages→get_recent_messages` 래핑 구현 +2. **Stats API 일원화**: robeing-monitor 도입 및 사용 +3. **RAG 파일 스킬**: 포트 8508, 컬렉션 명명 규칙 적용 완료 +4. **NaverWorks 통합**: skill-email에서 provider=naverworks 지원 +5. **Slack 봇 설치 플로우**: passport/install/callback 엔드포인트 구현 +6. **GEMINI CLI 타임아웃**: GEMINI_USE_CLI=False 기본값 + +## 📊 현재 운영 상태 + +- **51123 서버**: nginx, auth-server, gateway 정상 운영 +- **51124 서버**: rb8001, skill 서비스들 정상 운영 +- **포트 상태**: 8100(gateway), 9000(auth) 정상 리스닝 +- **Docker 컨테이너**: 모든 서비스 healthy 상태 \ No newline at end of file diff --git a/troubleshooting/250911_happybell80_UUID_체계_전환_및_대화저장_오류.md b/troubleshooting/250924_happybell80_UUID_체계_전환_및_대화저장_오류.md similarity index 51% rename from troubleshooting/250911_happybell80_UUID_체계_전환_및_대화저장_오류.md rename to troubleshooting/250924_happybell80_UUID_체계_전환_및_대화저장_오류.md index 17c72e2..7489b6c 100644 --- a/troubleshooting/250911_happybell80_UUID_체계_전환_및_대화저장_오류.md +++ b/troubleshooting/250924_happybell80_UUID_체계_전환_및_대화저장_오류.md @@ -1,6 +1,7 @@ # UUID 체계 전환 및 대화 저장 오류 해결 ## 작성일: 2025-09-11 +## 최종 수정일: 2025-09-24 ## 작성자: happybell80 --- @@ -22,39 +23,16 @@ ## 해결 과정 ### 1. rb8001 UUID 체계 전환 -```python -# app/router/router.py - X-User-Id 헤더 우선 사용 -if request and hasattr(request, 'headers'): - x_user_id = request.headers.get('X-User-Id') - if x_user_id and self.is_valid_uuid(x_user_id): - final_uuid = x_user_id -``` +- app/router/router.py: X-User-Id 헤더 우선 사용 처리 ### 2. conversation_log id 자동증가 해결 -```python -# 테이블에 SERIAL 없어서 명시적 생성 -max_id_result = db.execute(text("SELECT COALESCE(MAX(id), 0) FROM conversation_log")) -next_id = max_id_result.scalar() + 1 -conversation_log = ConversationLog(id=next_id, ...) -``` +- 테이블에 SERIAL 없어 MAX(id)+1로 수동 생성 ### 3. Gateway Slack ID→UUID 변환 -```sql --- 잘못된 쿼리 (username 사용) -WHERE u.username = :slack_user_id - --- 올바른 쿼리 (oauth_id 사용) -WHERE u.oauth_id = :slack_user_id AND u.oauth_provider = 'slack' -``` +- oauth_id와 oauth_provider='slack' 조건으로 조회 ### 4. Slack Handler UUID 처리 -```python -# X-User-Id 헤더에서 UUID 추출 -user_uuid = request.headers.get("X-User-Id") -if user_uuid: - context["user_uuid"] = user_uuid - context["original_slack_id"] = user_id # 원본 보존 -``` +- X-User-Id 헤더에서 UUID 추출 및 context 저장 ## 데이터 흐름 정리 @@ -82,19 +60,47 @@ if user_uuid: ## 추가 수정 사항 ### 뉴스 중복 방지 -```python -# skill-news fallback 제거 - dm_skill.py -# 새 뉴스 없을 때 /api/news/latest 호출 제거 -return ("오늘의 새로운 뉴스가 없습니다.", []) -``` +- skill-news fallback 제거: 새 뉴스 없을 때 API 호출 제거 ### 헬스체크 로그 레벨 조정 -```python -# DEBUG 레벨로 변경 - main.py -logger.debug(f"Health check passed for {settings.ROBEING_ID}") -``` +- DEBUG 레벨로 변경하여 로그 노이즈 감소 ## 교훈 - DB 스키마와 코드 모델 일치 필수 - UUID 체계 전환 시 모든 경로 점검 -- 헤더 기반 인증 정보는 일관된 위치에서 처리 \ No newline at end of file +- 헤더 기반 인증 정보는 일관된 위치에서 처리 + +--- + +## 2025-09-24 추가 수정: Slack UUID 변환 실패 시 에러 처리 + +### 문제 상황 +- Gateway에서 Slack ID를 UUID로 변환 실패 시 경고만 출력하고 요청 계속 진행 +- rb8001에서 X-User-Id 헤더 없을 때 Slack ID를 UUID로 저장 시도하여 타입 오류 발생 + +### 해결 방안 + +#### 1. /home/admin/robeing-gateway/app/main.py 수정 + +**라인 526-532** - `/slack/events` 엔드포인트: +- 현재: 경고만 출력 +- 수정: UUID 없으면 403 에러 반환 + +**라인 583-585** - `/slack/interactive` 엔드포인트: +- 동일하게 UUID 변환 실패 시 403 에러 반환 + +#### 2. /home/admin/robeing-gateway/app/database.py 수정 (선택사항) + +**라인 376-381** - `slack_user_to_uuid` 함수: +- 현재: None 반환 +- 선택적 수정: ValueError 예외 발생 + +### 기대 효과 +- Slack 사용자가 시스템에 등록되지 않은 경우 명확한 에러 메시지 반환 +- 잘못된 UUID로 인한 데이터 오염 방지 +- 디버깅 시간 단축 (명확한 에러로 원인 파악 용이) + +### 관련 문제 +- Slack 요청은 OAuth 인증 없이 직접 `/slack/events`로 전송 +- JWT 토큰 없이 Slack 웹훅이 직접 호출 +- DB에서 oauth_id로 UUID 조회 시 oauth_provider='slack' 조건 필수 \ No newline at end of file