diff --git a/300_architecture/311_FastAPI_구조_원칙.md b/300_architecture/311_FastAPI_구조_원칙.md index 15ce208..c920f06 100644 --- a/300_architecture/311_FastAPI_구조_원칙.md +++ b/300_architecture/311_FastAPI_구조_원칙.md @@ -93,6 +93,11 @@ utils ## 5. 코드 작성 원칙 +### LangGraph 워크플로우 +- **복잡한 다단계 처리**: LangGraph 적극 활용 +- **체크포인트 필수**: PostgresSaver로 부분 재시도 가능하게 구현 +- **stateless 금지**: 체크포인트 없는 LangGraph는 일반 함수와 동일, 프레임워크 가치 없음 + ### router 계층 ```python # ✅ 올바름 diff --git a/troubleshooting/250714_system_metrics_implementation.md b/troubleshooting/250714_system_metrics_implementation.md index 8511d95..73071b5 100644 --- a/troubleshooting/250714_system_metrics_implementation.md +++ b/troubleshooting/250714_system_metrics_implementation.md @@ -108,10 +108,12 @@ backend/ - `GET /admin/metrics/history/{period}` - 기간별 메트릭 히스토리 - `POST /admin/metrics/collect` - 수동 메트릭 수집 -## 미해결 문제 -**현재 상태**: 테이블 구조 불일치로 인한 메트릭 데이터 삽입 실패 -**증상**: `column "timestamp" of relation "system_metrics" does not exist` -**예상 원인**: 코드 내 일부 SQL 쿼리에서 여전히 `timestamp` 컬럼 참조 +## 최종 해결 (2025-07-15) + +**상태**: 메트릭 수집 비활성화 (Prometheus + Grafana로 대체) +**관련 파일**: frontend-base/backend/metrics_database.py:58-60, 78-80, 148-150 +**해결 방법**: system_metrics 테이블 사용 중단, TODO 주석 처리 +**참고**: 아래 Prometheus + Grafana 방식으로 완전 전환 ## 학습 포인트 1. **Docker 네트워크**: 컨테이너간 통신 시 서비스 이름 사용 @@ -120,13 +122,7 @@ backend/ 4. **데이터베이스 스키마**: 코드와 실제 테이블 구조 일치 중요성 5. **PostgreSQL 인증**: Docker 환경에서 비밀번호 설정 필요 -## 후속 작업 -1. 테이블 구조 불일치 문제 완전 해결 -2. 메트릭 데이터 수집 정상 동작 확인 -3. 그래프에 실제 데이터 표시 검증 -4. 성능 최적화 및 에러 핸들링 개선 - -## (*update*) `node-exporter` + `Prometheus` + `Grafana` 를 이용한 compute 자원 모니터링 +## `node-exporter` + `Prometheus` + `Grafana` 를 이용한 compute 자원 모니터링 해당 문서는 직접 개발하는 방식이 아닌 기존에 널리 쓰이는
`node-exporter` + `Prometheus` + `Grafana`를 이용하여
diff --git a/troubleshooting/251015_claude_coldmail_ir_analysis_failure.md b/troubleshooting/251015_claude_coldmail_ir_analysis_failure.md index 8f43d90..258755a 100644 --- a/troubleshooting/251015_claude_coldmail_ir_analysis_failure.md +++ b/troubleshooting/251015_claude_coldmail_ir_analysis_failure.md @@ -60,19 +60,40 @@ PDF 업로드 실패 → document_id = None → RAG 검색 0건 → IR 분석 "N **개선**: 중복 시 기존 document_id 반환 (멱등성 보장) -### 2. IR 분석 실패 감지 +### 2. Slack Lists 동적 컬럼 매핑 -**위치**: rb8001/app/services/coldmail_processor.py +**문제**: 하드코딩된 컬럼 ID (Col09HQTDUM0T 등) - Lists 필드 변경 시 코드 수정 필요 -**추가**: 모든 필드 "N/A" 시 처리 실패로 간주, 로그 기록 +**해결**: +1. skill-slack에 Lists 컬럼 조회 API 추가 (`GET /api/v1/lists/{list_id}/columns`) +2. coldmail_processor.py에서 컬럼명으로 동적 매핑 (`"회사명" → Col09HQTDUM0T`) +3. 컬럼 누락 시 해당 필드만 skip, 나머지 전송 -### 3. LangGraph 체크포인트 활성화 +**효과**: Lists 구조 변경 시 코드 수정 불필요 -**위치**: workflows/coldmail_workflow.py:145 +### 3. LangGraph 체크포인트 + LLM 기반 에러 복구 -**현재**: `workflow.compile()` (stateless) +**위치**: workflows/coldmail_workflow.py -**개선**: PostgresSaver 추가로 IR 분석 실패 시 해당 노드만 재시도 가능 +**현재 구조** (stateless): +``` +메일 조회 → PDF 업로드 → IR 분석 → Slack 전송 +``` + +**개선 구조** (체크포인트 + 에러 복구): +``` +메일 조회 → PDF 업로드 → IR 분석 → Slack 전송 + ↓ (400 에러) + LLM 에러 분석 → 페이로드 수정 → 재전송 +``` + +**구현**: +1. PostgresSaver 체크포인트 활성화 +2. Slack 전송 실패 시 에러 메시지 + 원본 payload를 LLM에게 전달 +3. LLM structured output으로 수정된 payload 받아서 재시도 +4. 각 노드별 실패 시 해당 지점부터 재시도 (처음부터 재실행 방지) + +**제약**: Slack API가 상세 에러 정보 제공해야 LLM이 수정 가능 --- diff --git a/troubleshooting/251015_slack_install_workspace_id_error.md b/troubleshooting/251015_slack_install_workspace_id_error.md new file mode 100644 index 0000000..4c03fa9 --- /dev/null +++ b/troubleshooting/251015_slack_install_workspace_id_error.md @@ -0,0 +1,57 @@ +# Slack 봇 설치 workspace_id 컬럼 오류 + +**날짜**: 2025-10-15 +**작성자**: 51123 서버 관리자 +**관련 파일**: `auth-server/app/providers/slack.py:408-418` + +--- + +## 문제 상황 + +Slack 연동 버튼 클릭 시 Internal Server Error: +``` +column "workspace_id" does not exist +LINE 2: SELECT workspace_id + FROM workspace_member +``` + +**에러 로그**: auth-server 로그에서 sqlalchemy.exc.ProgrammingError 확인 + +## 원인 분석 + +### DB 구조 +- workspace_member 테이블: workspace_id 컬럼 없음 (id, user_id, role, is_active만 존재) +- slack.py:408-413: 존재하지 않는 컬럼 조회 시도 + +### 실제 관계 +- user.team_id → team.id +- Workspace = Team (workspace.py:113) +- user.team_id가 workspace_id 역할 + +## 해결 방안 + +**수정 파일**: auth-server/app/providers/slack.py + +**수정 내용**: +- slack.py:408-413: text() 쿼리 삭제 +- slack.py:408: db.query(User).filter(User.id == user_id).first()로 변경 +- slack.py:409-410: user.team_id 존재 확인 (없으면 HTTPException 404) +- slack.py:418: workspace_id = user.team_id + +**참고**: User는 slack.py:19에 이미 import됨 + +## 교훈 + +### DB 스키마 검증 누락 +- workspace_member.workspace_id 존재 가정, 실제 컬럼 없음 +- tables.md 또는 psql \d 명령으로 테이블 구조 미확인 +- 교훈: 쿼리 작성 전 tables.md 참조 또는 DB 직접 확인 필수 + +### Raw SQL 사용 위험 +- text() 쿼리 사용 시 컴파일 타임 타입 체크 불가 +- 런타임에만 에러 발견 +- 교훈: ORM (db.query(Model)) 사용으로 타입 안전성 확보 + +### 스키마 변경 추적 부족 +- DB 스키마 변경 후 참조 코드 미검증 +- 교훈: 스키마 변경 시 Grep으로 전체 참조 검색 후 일괄 수정