docs: 콜드메일 자동 감지 시스템 구현 완료 상태로 업데이트
- 상태: 계획 → 구현 완료 - skill-email: 메일 상세 조회, 첨부파일 다운로드 구현 사실 기록 - rb8001: 6개 서비스 + 스케줄러 구현 사실 기록 (커밋 해시 포함) - 환경변수: COLDMAIL_BRIEFING_ENABLED, COLDMAIL_CHANNEL_ID, SLACK_LIST_ID, NAVERWORKS_COMPANY_EMAIL 설정 완료 - 구현된 처리 흐름 10단계 기록 - 테스트 실행 방법 추가 - 의사코드, 예측, 민감정보 제거 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
d533219b4d
commit
3d87ef8c28
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## 날짜: 2025-09-30
|
## 날짜: 2025-09-30
|
||||||
## 작성자: Claude (로컬 개발자)
|
## 작성자: Claude (로컬 개발자)
|
||||||
## 상태: 계획
|
## 상태: 구현 완료
|
||||||
|
|
||||||
## 목표
|
## 목표
|
||||||
NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시:
|
NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시:
|
||||||
@ -13,20 +13,26 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 현재 상태 (2025-09-30 코드 확인)
|
## 구현 완료 (2025-09-30)
|
||||||
|
|
||||||
### 구현 완료
|
### skill-email (커밋: a535732)
|
||||||
- skill-email: `list_messages` (naverworks_provider.py:152), `get_message` (naverworks_provider.py:288), 토큰 갱신 (naverworks_provider.py:356)
|
- GET /messages/{message_id}: routers/mail_detail_router.py 생성, main.py:311-312 등록
|
||||||
- skill-rag-file: POST /api/upload (upload.py:29), 포트 8508, PDF/DOCX/DOC/TXT/MD 지원 (config.py:33)
|
- GET /messages/{message_id}/attachments/{attachment_id}: routers/mail_detail_router.py
|
||||||
- rb8001: Slack 파일 → skill-rag-file 전송 (slack_handler.py:52-147, 비동기 병렬)
|
- download_attachment 메서드: services/naverworks_provider.py:357-388
|
||||||
- rb8001: NAVER WORKS 일일 브리핑 (naverworks_briefing.py:36-256, 긴급/계약/결제 키워드)
|
- attachments 필드 추가: services/naverworks_provider.py:326
|
||||||
|
|
||||||
### 미구현 (코드 확인)
|
### rb8001 (커밋: 19304ea, 1980a4e, d88615e)
|
||||||
- ~~skill-email: `download_attachment` 메서드 없음~~ → 구현 완료
|
- app/services/coldmail_filter.py: Incremental Naive Bayes 필터, initialize_seed_data(), is_coldmail(), update_classifier()
|
||||||
- rb8001: 콜드메일(투자/IR) 필터 로직 없음 (현재는 일반 중요 키워드만) → 구현 완료
|
- app/services/naverworks_file_processor.py: download_naverworks_attachment(), upload_to_rag_file(), process_naverworks_attachments()
|
||||||
- ~~rb8001: NAVER WORKS 첨부파일 다운로드→rag-file 경로 없음~~ → 구현 완료
|
- app/services/ir_analyzer.py: extract_ir_metrics(), query_rag(), call_llm()
|
||||||
- skill-slack: Slack 메시지 전송 API 존재 (POST /api/v1/send, messages.py:19), rb8001에서 HTTP로 호출
|
- app/services/startup_valuation.py: valuate_startup(), get_prior_by_stage(), calculate_posterior(), save_valuation()
|
||||||
- **Slack Lists API**: lists:write, lists:read 스코프 설정 완료, 구현 필요
|
- app/services/slack_lists_client.py: create_list_item(), update_list_item(), create_coldmail_list_item(), update_ir_feedback()
|
||||||
|
- app/scheduler/jobs/coldmail_briefing.py: _run_coldmail_briefing(), register() (cron: 5 9 * * mon-fri)
|
||||||
|
- main.py:197-198: coldmail_briefing.register(scheduler)
|
||||||
|
- app/skills/naverworks_briefing.py:17: NAVERWORKS_COMPANY_EMAIL 환경변수 사용, 하드코딩 제거
|
||||||
|
- app/state/database.py:118-147: get_naverworks_user_uuid() 함수 (이미 존재)
|
||||||
|
- tests/test_coldmail_briefing.py: 9개 테스트 함수
|
||||||
|
- Dockerfile:30: COPY ./tests /code/tests 추가
|
||||||
|
|
||||||
### API 스펙 확인 완료 (2025-09-30)
|
### API 스펙 확인 완료 (2025-09-30)
|
||||||
|
|
||||||
@ -52,63 +58,51 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시:
|
|||||||
|
|
||||||
**구현 가능성**: 100% (API 스펙 및 실제 응답 구조 검증 완료)
|
**구현 가능성**: 100% (API 스펙 및 실제 응답 구조 검증 완료)
|
||||||
|
|
||||||
### 환경 설정 확인 (2025-09-30)
|
### 환경 설정 완료 (2025-09-30, 51124 서버)
|
||||||
- **Slack 워크스페이스**: 유료 플랜 (Lists API 제약 없음)
|
- **DB 테이블**: coldmail_classifier, startup_valuation (51123 서버)
|
||||||
- **DB 테이블 생성 완료** (51123 서버):
|
- **환경변수** (rb8001 .env):
|
||||||
- `coldmail_classifier`: word VARCHAR, coldmail_count INT, normal_count INT
|
- COLDMAIL_BRIEFING_ENABLED=true
|
||||||
- `startup_valuation`: team_id UUID FK, startup_name VARCHAR, valuation_median NUMERIC, valuation_lower NUMERIC, valuation_upper NUMERIC, confidence FLOAT, metadata JSONB
|
- COLDMAIL_BRIEFING_SCHEDULE=5 9 * * mon-fri
|
||||||
- **환경변수**: `COLDMAIL_CHANNEL_ID` (51124 서버 rb8001 .env)
|
- COLDMAIL_CHANNEL_ID=C09HR9BMT51
|
||||||
- **구현 범위**: 전체 13단계 구현
|
- SLACK_LIST_ID=F09J1HPPQJG
|
||||||
|
- NAVERWORKS_COMPANY_EMAIL (하드코딩 제거됨)
|
||||||
|
- **Slack 앱 스코프**: lists:write, lists:read, files:read
|
||||||
|
- **배포**: docker-compose.yml env_file: .env (line 6-7), Dockerfile COPY ./tests (line 30)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 구현 계획
|
## 구현된 처리 흐름
|
||||||
|
|
||||||
### 콜드메일 필터링 (Incremental Naive Bayes)
|
### 스케줄러 실행
|
||||||
1. **초기 Prior**: DB `coldmail_classifier` 테이블 (word, coldmail_count, normal_count), 도메인(`*.vc`: 0.9), 키워드(`투자`: 0.8) 시드
|
- 평일 9시 5분 (월요일: 72시간, 화~금: 24시간 조회)
|
||||||
2. **특징 추출**: 제목+발신자 도메인 → 토큰화
|
- coldmail_briefing.py:75-189
|
||||||
3. **확률 계산**: P(콜드메일|단어) = P(단어|콜드메일) × P(콜드메일) / P(단어), 임계값 > 0.7
|
|
||||||
4. **Slack 피드백**: "IR 맞음 ✅" / "아님 ❌" 버튼, 클릭 시 DB 카운터 업데이트
|
|
||||||
5. **Prior 갱신**: 평일 9시 5분 스케줄러, 피드백 반영 후 재분류
|
|
||||||
6. **첨부파일 조건**: PDF 우선 처리
|
|
||||||
|
|
||||||
### 처리 흐름
|
### 처리 단계
|
||||||
1. 평일 9시 5분 rb8001 스케줄러 (cron: `5 9 * * mon-fri`) → skill-email list_messages (월요일 72시간, 화~금 24시간)
|
1. NAVERWORKS_COMPANY_EMAIL → get_naverworks_user_uuid() → user_id 조회
|
||||||
2. 콜드메일 필터링 (rb8001, Naive Bayes), 첨부파일 있는 것만
|
2. skill-email GET /messages (startSearchDate, endSearchDate)
|
||||||
3. 첨부파일 다운로드 (NAVER WORKS API) → skill-rag-file 업로드
|
3. is_coldmail() 필터링 (Naive Bayes, coldmail_classifier 테이블)
|
||||||
4. **IR 파일 파싱** (skill-rag-file): PDF/DOCX → 텍스트 추출 → semantic chunking → 임베딩 → ChromaDB 저장
|
4. 첨부파일 있는 메일만 선택
|
||||||
5. **핵심 지표 추출** (rb8001, LLM + RAG): 사업 분야, 투자 단계, 매출, 성장률, 팀 구성, 기술 우위
|
5. skill-email GET /messages/{message_id} → attachments 정보
|
||||||
6. **가치 평가** (rb8001, Bayesian VC Method):
|
6. process_naverworks_attachments() → PDF만 선택 → skill-rag-file POST /api/upload
|
||||||
- Prior: 동일 업종/단계 평균 밸류에이션 (DB 조회)
|
7. extract_ir_metrics() → skill-rag-file RAG 쿼리 6회 → LLM 요약
|
||||||
- Likelihood: IR 지표 반영 (성장률, 특허, 시장점유율)
|
8. valuate_startup() → Bayesian VC Method (Prior × Likelihood = Posterior) → startup_valuation 테이블 저장
|
||||||
- Posterior: 밸류에이션 분포 계산 (중간값, 신뢰구간, 불확실성)
|
9. create_coldmail_list_item() → Slack Lists API (lists.items.create)
|
||||||
- DB 저장: `startup_valuation` 테이블
|
10. skill-slack POST /api/v1/send → 처리 완료 요약 메시지
|
||||||
7. **Slack Lists 생성/업데이트** (slackLists.items.create):
|
|
||||||
- 컬럼: 회사명, 담당자, 제안내용, 첨부파일, 밸류에이션, IR여부(피드백)
|
### Naive Bayes 학습 루프
|
||||||
- 피드백: slackLists.items.update로 업데이트
|
- initialize_seed_data(): *.vc 도메인, 투자/IR 키워드 시드
|
||||||
8. **학습 루프**: 피드백 수집 → Prior 업데이트 → 모델 개선
|
- update_classifier(): Slack 피드백 시 DB 카운터 업데이트 (현재 수동 호출)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 다음 단계
|
## 테스트
|
||||||
|
|
||||||
### FastAPI 구조 원칙
|
### 테스트 파일
|
||||||
- **main.py**: 앱 생성, 라우터 등록만
|
- tests/test_coldmail_briefing.py (9개 함수)
|
||||||
- **routers/**: 엔드포인트별 분리
|
|
||||||
- **services/**: 비즈니스 로직
|
|
||||||
- **settings.py**: 환경변수, URL 생성
|
|
||||||
|
|
||||||
### 구현 순서
|
### 실행 방법
|
||||||
1. ~~**메일 상세 조회 API 테스트**~~: attachments 필드 확인 완료
|
- 51124 서버: docker exec -it rb8001 python tests/test_coldmail_briefing.py --test [db|filter|email|attachment|ir|valuation|lists|scheduler]
|
||||||
2. **Slack 앱 매니페스트 수정**: lists:write, lists:read, files:read 스코프 추가 → 앱 재설치
|
- 로컬: python tests/test_coldmail_briefing.py
|
||||||
3. skill-email: GET /messages/{message_id} 엔드포인트 추가 (main.py 라우팅)
|
|
||||||
4. skill-email: `download_attachment` 메서드 추가 (services/naverworks_provider.py, Base64 디코딩)
|
### 필수 환경변수
|
||||||
5. ~~PostgreSQL 테이블~~: `coldmail_classifier`, `startup_valuation` 생성 완료 (51123 서버)
|
- COLDMAIL_BRIEFING_ENABLED, COLDMAIL_CHANNEL_ID, SLACK_LIST_ID, NAVERWORKS_COMPANY_EMAIL, SLACK_BOT_TOKEN, DATABASE_URL, SKILL_EMAIL_URL, SKILL_SLACK_URL, SKILL_RAG_FILE_URL
|
||||||
6. rb8001: Naive Bayes 필터 구현 (services/coldmail_filter.py, 도메인/키워드 시드)
|
|
||||||
7. rb8001: NAVER WORKS 첨부파일 처리 (services/naverworks_file_processor.py, slack_handler.py:52-147 참고)
|
|
||||||
8. rb8001: IR 지표 추출 (services/ir_analyzer.py, LLM + RAG)
|
|
||||||
9. rb8001: Bayesian 가치 평가 (services/startup_valuation.py, scipy.stats)
|
|
||||||
10. rb8001: Slack Lists 클라이언트 (services/slack_lists_client.py, slackLists API)
|
|
||||||
11. rb8001: 스케줄러 작업 등록 (scheduler/jobs/coldmail_briefing.py, cron: `5 9 * * mon-fri`)
|
|
||||||
12. rb8001: main.py에 스케줄러 작업만 등록
|
|
||||||
13. rb8001: .env에 `COLDMAIL_CHANNEL_ID` 사용
|
|
||||||
Loading…
x
Reference in New Issue
Block a user