# Slack Lists 첨부파일 업로드 구현 **날짜**: 2025-10-14 **작성자**: happybell80 **관련 파일**: `rb8001/app/scheduler/jobs/coldmail_briefing.py` **전체 시나리오**: 251014_coldmail_ir_analysis_scenario.md --- ## 문제 상황 - coldmail_briefing.py:204: attachment 필드에 document_id 문자열 전달 - Slack Lists API는 file_id 필요 (skill-slack/tests/test_slack_lists.py:112) - 전체 목표: IR PDF 분석 → 기업 평가 → 베이지안 확률 → Slack 보고서 --- ## 우선 해결: 파일 영속성 문제 (2025-10-14 해결) ### 문제 - skill-rag-file 컨테이너가 파일을 `/mnt/51123data/documents/`에 저장 - SSHFS `user_id=1001`, 컨테이너 `root (UID 0)` 권한 불일치 - 컨테이너 재시작 시 파일 손실 ### 해결 1. `/etc/fuse.conf`: `user_allow_other` 활성화 2. SSHFS 재마운트: `allow_other,default_permissions` 옵션 추가 3. `docker-compose.yml`: `/mnt/51123data:/mnt/51123data:rw` 볼륨 추가 ### 결과 - ✅ 컨테이너 → 호스트 파일 동기화 - ✅ 51123 서버 HDD 영구 저장 - ✅ 재시작 후에도 파일 유지 **상세**: 251014_skill-rag-file_sshfs_allow_other_해결.md --- ## 현재 상태 ### skill-rag-file - main.py:54: POST /api/upload 존재 - upload.py:108: storage_path에 파일 저장 - 다운로드 API 없음 ### skill-slack - lists.py:47: POST /lists/items 존재 (slackLists.items.create) - messages.py:19: POST /send 존재 (chat_postMessage) - files_upload_v2 통합 없음 ### test_slack_lists.py (검증된 동작) - 81-88줄: files_upload_v2(channel, file, title) → file_id 반환 - 112줄: attachment 필드에 [file_id] 전달 - 192줄: channel 파라미터 있으면 메시지 생성, 없으면 업로드만 --- ## 해결 방안 ### 우선순위 0: skill-rag-file 파일 영속성 (✅ 완료) - SSHFS allow_other 설정 - docker-compose.yml 볼륨 마운트 추가 - 상세: 251014_skill-rag-file_sshfs_allow_other_해결.md ### 우선순위 1: skill-rag-file 다운로드 API **파일**: skill-rag-file/app/api/download.py (신규) - GET /api/download/{document_id} - TeamDocument.query(id=document_id) → storage_path, filename 조회 - from fastapi.responses import FileResponse - return FileResponse(path=storage_path, filename=filename) **파일**: skill-rag-file/app/main.py:55 - from app.api import download - app.include_router(download.router, prefix="/api", tags=["download"]) **DB**: app/models/database.py:7-28 - TeamDocument.storage_path (Text) - TeamDocument.filename (String(255)) ### 우선순위 2: skill-slack 파일 업로드 API **파일**: skill-slack/app/api/endpoints/files.py (신규) - POST /api/v1/files/upload (multipart/form-data) - from slack_sdk import WebClient - client = WebClient(token=token) - result = client.files_upload_v2(file=file, title=title) - return {"file_id": result['file']['id']} **참고**: messages.py:17 (WebClient 초기화), test_slack_lists.py:81-88 ### 우선순위 3: coldmail_briefing.py 통합 **위치**: rb8001/app/scheduler/jobs/coldmail_briefing.py:159-204 - GET {SKILL_RAG_FILE_URL}/api/download/{document_id} - 파일 /tmp/{filename} 저장 - POST {SKILL_SLACK_URL}/api/v1/files/upload (multipart) - 204줄: attachment: [file_id] --- ## 교훈 ### 파일 영속성 검증 누락 - 컨테이너 내부에만 파일 존재, 호스트/51123 서버 저장 안됨 - SSHFS allow_other 옵션 미사용으로 권한 불일치 - 교훈: 파일 저장 시스템 구축 시 영속성 테스트 필수 ### 테스트 파일 확인 누락 - test_slack_lists.py에 완전한 구현 예시 존재 - 문서만 보고 추측으로 작성 - 교훈: 테스트 파일 우선 확인 필수 ### API 스펙 미확인 - attachment 필드 타입 확인 안 함 - document_id 문자열 전달 (오류) - 교훈: Slack API 필드 타입 사전 확인 필수 ### FUSE 권한 모델 이해 부족 - SSHFS 마운트는 기본적으로 마운트한 사용자만 접근 - Docker 컨테이너는 다른 UID로 실행되어 접근 불가 - 교훈: FUSE 기반 파일시스템 사용 시 allow_other 옵션 검토 필수