docs: NAVER WORKS 콜드메일 자동 감지 계획 추가 및 Tailwind 모바일 반응형 이슈 해결

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
happybell80 2025-09-30 21:53:24 +09:00
parent 56f0360844
commit 220d9b77d7
3 changed files with 151 additions and 143 deletions

View File

@ -1,143 +0,0 @@
# NAVER WORKS → Slack 연동 [3/3] 콜드메일 리스트업
## 날짜: 2025-09-19
## 작성자: Claude (51123 서버 관리자)
## 관련 서비스: rb8001, skill-email, skill-slack(선택)
## 상태: 미구현 (02 문서 변경사항 반영)
## 관련 문서
- [1/3 기본 구성](./250919_naverworks_slack_01_base_configuration.md)
- [2/3 일일 브리핑](./250919_naverworks_slack_02_daily_briefing.md)
---
## 1. 콜드메일 리스트업 개요
### 목적
스타트업 콜드메일을 자동으로 수집하여 Slack 리스트 형식으로 전달
### 핵심 기능
- 콜드메일 패턴 감지 (발신자 도메인, 제목 키워드)
- 구조화된 리스트 생성 (회사명, 담당자, 제안내용)
- 첨부파일 정보 표시
- Slack 지정 채널 자동 포스팅
---
## 2. 구현 방식
### 2.1 트리거 방식 (권장: 푸시 알림)
- **현재 계획**: 주기적 폴링
- **권장 변경**: NAVER WORKS 푸시 알림
- Developer Console에서 Webhook URL 등록
- 새 메일 수신 시 즉시 알림
- API 호출 최소화
### 2.2 처리 흐름 (현행 기준 + 계획)
1. 새 메일 수신 이벤트 발생 (또는 주기적 체크)
2. rb8001이 skill-email 호출
- 현행: GET `/messages?provider=naverworks&user_id={UUID}&limit=100` 후 클라이언트(receivedTime) 기준 24시간 필터
- 계획: POST `/cold-mail-list` (필터·구조화까지 일괄 처리)
3. 콜드메일 필터링/구조화
- 현행: rb8001에서 키워드/도메인 기반 필터 후 목록 구성
- 계획: skill-email 내부 `filter_cold_mails()`로 위임
4. Slack 포맷팅 후 전송
- 현행: rb8001이 Block Kit 직접 구성 후 전송(WebClient)
- 계획: skill-slack POST `/format-cold-mail`로 포맷 위임
5. 전송 대상: 네이버웍스 등록 사용자 DM(기본) — 필요 시 전용 채널 옵션
---
## 3. 콜드메일 필터링 규칙
### 3.1 발신자 도메인 패턴
```python
COLD_MAIL_DOMAINS = [
"*.vc", # VC 도메인
"*capital.com", # 투자사
"*ventures.com", # 벤처 캐피털
"*startup.com" # 스타트업
]
```
### 3.2 제목 키워드
```python
COLD_MAIL_KEYWORDS = [
"투자", "제안", "협업", "파트너십",
"investment", "proposal", "partnership"
]
```
---
## 4. 구현 파일 구조
### skill-email 현황/계획
- 현행: GET `/messages`로 NAVER WORKS 메일 조회 (날짜 파라미터 미지원 → 클라이언트 필터 필요)
- 계획:
- `routers/naverworks_mail.py`: POST `/cold-mail-list` 엔드포인트
- `services/naverworks_mail_service.py`: `filter_cold_mails()`
- `schemas/naverworks_schemas.py`: ColdMailRequest/Response
- (선택) `models/repositories`로 캐시 테이블 분리
### skill-slack 현황/계획
- 현행: 전용 포맷터 엔드포인트 없음 (rb8001이 직접 Block Kit 구성)
- 계획: POST `/format-cold-mail` — 테이블 Block Kit(회사명 | 담당자 | 제안 | 첨부)
### rb8001 오케스트레이션
- 콜드메일 감지 시 skill-email에서 데이터 조회 → (현행) rb8001이 필터/포맷 → Slack 전송
- 라우팅: 기본은 등록 사용자 DM, 필요 시 전용 채널 라우팅 옵션화
---
## 5. 구현 체크리스트
### 5.1 skill-email 구현
- [ ] 응답 후 receivedTime 기준 클라이언트 필터 구현(타임존/RFC3339 주의)
- [ ] 콜드메일 필터링/패턴 매칭 알고리즘 (`filter_cold_mails()`)
- [ ] 메일 정보 구조화(회사/담당/제안/첨부)
- [ ] (선택) POST `/cold-mail-list` 일괄 처리 엔드포인트
- [ ] 네이버웍스 등록 사용자 조회(DB)로 대상자 결정
- [ ] skill-email `/messages` 호출 시 provider=naverworks만 전달(날짜 파라미터 제거), 클라이언트 필터 적용
- [ ] Block Kit 포맷/전송 (현행) 또는 skill-slack 포맷터 연계(계획)
- [ ] 라우팅 정책: DM 기본, 채널 옵션 지원
### 5.3 푸시 알림 설정 (권장)
- [ ] NAVER WORKS Webhook URL 등록
- [ ] 이벤트 수신 엔드포인트 구현
- [ ] 실시간 처리 로직
---
## 6. 보안 및 개선사항
### 6.1 정보 최소화
- **문제**: 메일 본문 전체 노출 위험
- **해결**:
- 발신자, 제목, 회사명만 표시
- 첨부파일은 파일명/크기만
- 상세 내용은 원본 메일 링크
### 6.2 첨부파일 처리
- **문제**: 악성코드 위험
- **해결**:
- 직접 다운로드 금지
- "첨부파일 있음" 표시만
- 파일 형식과 크기 정보만 제공
---
## 7. 예상 출력 형식
```
📨 새로운 콜드메일 (3건)
━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌─────────────┬──────────┬─────────────────┬────────┐
│ 회사명 │ 담당자 │ 제안 내용 │ 첨부 │
├─────────────┼──────────┼─────────────────┼────────┤
│ ABC Ventures│ 김대표 │ 시리즈A 투자제안│ PDF 2개│
│ XYZ Capital │ 이과장 │ 협업 미팅 요청 │ - │
│ 123 Startup │ 박매니저 │ 파트너십 제안 │ PPT 1개│
└─────────────┴──────────┴─────────────────┴────────┘
```

View File

@ -0,0 +1,70 @@
# Tailwind CSS 도입 및 모바일 반응형 문제 해결
## 문제
- Space Times 홈페이지 모바일(375px)에서 TabSection 등 컴포넌트들이 가로로 넘침
- 사용자가 의도하지 않은 가로 스크롤 발생
## 시도한 해결책들
### 1차: 개별 컴포넌트 CSS 수정
- TabSection.css에 미디어 쿼리 추가
- width: 100%, overflow-x: hidden 적용
- 문제: 일시적으로 해결됐다가 다시 발생
### 2차: 전역 CSS 해결
- index.css에 전역 스타일 추가
```css
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body, html {
overflow-x: hidden !important;
max-width: 100% !important;
}
```
- 문제: CSS 우선순위 충돌로 불완전한 해결
## 최종 해결: Tailwind CSS v3 도입
### 설치
```bash
npm install -D tailwindcss@^3 autoprefixer postcss
```
### 설정 파일
- tailwind.config.js: content 경로 설정
- postcss.config.js: tailwindcss, autoprefixer 플러그인 설정
- index.css: @tailwind 디렉티브 추가
### 주요 변경사항
1. 모든 컴포넌트를 Tailwind 버전(TW suffix)으로 재작성
- TabSection → TabSectionTW
- ServiceCards → ServiceCardsTW
- ContentSection → ContentSectionTW
- Sidebar → SidebarTW
- HeroCarousel → HeroCarouselTW
- SearchSection → SearchSectionTW
2. CSS 파일 제거, 유틸리티 클래스로 대체
- 반응형: sm:, md:, lg: 프리픽스 사용
- 그리드: grid grid-cols-1 sm:grid-cols-3
- 플렉스박스: flex flex-col sm:flex-row
### Tailwind v4 → v3 다운그레이드
- 초기 Tailwind v4 설치 시 PostCSS 플러그인 호환 문제 발생
- v3로 다운그레이드하여 안정성 확보
### SNS 버튼 브랜드 색상 적용
- 카카오톡: #FEE500 (공식 노란색)
- 인스타그램: gradient from-[#833ab4] via-[#fd1d1d] to-[#fcb045]
- 유튜브: #FF0000 (공식 빨간색)
## 결과
- 375px 모바일 화면에서 가로 스크롤 완전 제거
- 모든 컴포넌트가 뷰포트 내에 정상 표시
- 깔끔한 유틸리티 클래스 기반 스타일링
## 교훈
- CSS 충돌 문제는 근본적인 해결책(Tailwind 같은 유틸리티 프레임워크)이 효과적
- Tailwind v4는 아직 불안정, 프로덕션은 v3 사용 권장
- 브랜드 색상은 hex 코드로 직접 지정 ([#색상코드] 형식)

View File

@ -0,0 +1,81 @@
# NAVER WORKS → Slack 연동 [3/3] 콜드메일 자동 감지 및 IR 파일 분석
## 날짜: 2025-09-30
## 작성자: Claude (로컬 개발자)
## 상태: 계획
## 목표
NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시:
1. 자동 감지 및 필터링
2. Slack 전용 채널에 리스트 포스팅 + 첨부파일 업로드
3. 첨부파일(IR 자료) skill-rag-file 자동 학습
4. AI 분석 요약 생성 후 채널 공유
---
## 현재 상태 (2025-09-30 코드 확인)
### 구현 완료
- skill-email: `list_messages` (naverworks_provider.py:152), `get_message` (naverworks_provider.py:288), 토큰 갱신 (naverworks_provider.py:356)
- skill-rag-file: POST /api/upload (upload.py:29), 포트 8508, PDF/DOCX/DOC/TXT/MD 지원 (config.py:33)
- rb8001: Slack 파일 → skill-rag-file 전송 (slack_handler.py:52-147, 비동기 병렬)
- rb8001: NAVER WORKS 일일 브리핑 (naverworks_briefing.py:36-256, 긴급/계약/결제 키워드)
### 미구현 (코드 확인)
- skill-email: `download_attachment` 메서드 없음
- rb8001: 콜드메일(투자/IR) 필터 로직 없음 (현재는 일반 중요 키워드만)
- rb8001: NAVER WORKS 첨부파일 다운로드→rag-file 경로 없음
- skill-slack: files_upload_v2 사용 없음 (chat_postMessage만 사용, messages.py:49)
- **Slack Lists API**: lists:write, lists:read 스코프 미설정, 구현 없음 (2025년 9월 공개)
---
## 구현 계획
### 콜드메일 필터링 (Incremental Naive Bayes)
1. **초기 Prior**: DB `coldmail_classifier` 테이블 (word, coldmail_count, normal_count), 도메인(`*.vc`: 0.9), 키워드(`투자`: 0.8) 시드
2. **특징 추출**: 제목+발신자 도메인 → 토큰화
3. **확률 계산**: P(콜드메일|단어) = P(단어|콜드메일) × P(콜드메일) / P(단어), 임계값 > 0.7
4. **Slack 피드백**: "IR 맞음 ✅" / "아님 ❌" 버튼, 클릭 시 DB 카운터 업데이트
5. **Prior 갱신**: 매일 8시 스케줄러, 피드백 반영 후 재분류
6. **첨부파일 조건**: PDF 우선 처리
### 처리 흐름
1. 매일 8시 rb8001 스케줄러 → skill-email list_messages (최근 24시간)
2. 콜드메일 필터링 (rb8001, Naive Bayes), 첨부파일 있는 것만
3. 첨부파일 다운로드 (NAVER WORKS API) → skill-rag-file 업로드
4. **IR 파일 파싱** (skill-rag-file): PDF/DOCX → 텍스트 추출 → semantic chunking → 임베딩 → ChromaDB 저장
5. **핵심 지표 추출** (rb8001, LLM + RAG): 사업 분야, 투자 단계, 매출, 성장률, 팀 구성, 기술 우위
6. **가치 평가** (rb8001, Bayesian VC Method):
- Prior: 동일 업종/단계 평균 밸류에이션 (DB 조회)
- Likelihood: IR 지표 반영 (성장률, 특허, 시장점유율)
- Posterior: 밸류에이션 분포 계산 (중간값, 신뢰구간, 불확실성)
- DB 저장: `startup_valuation` 테이블
7. **Slack Lists 생성/업데이트** (slackLists.items.create):
- 컬럼: 회사명, 담당자, 제안내용, 첨부파일, 밸류에이션, IR여부(피드백)
- 피드백: slackLists.items.update로 업데이트
8. **학습 루프**: 피드백 수집 → Prior 업데이트 → 모델 개선
---
## 다음 단계
### FastAPI 구조 원칙
- **main.py**: 앱 생성, 라우터 등록만
- **routers/**: 엔드포인트별 분리
- **services/**: 비즈니스 로직
- **settings.py**: 환경변수, URL 생성
### 구현 순서
1. **Slack 앱 매니페스트 수정**: lists:write, lists:read, files:read 스코프 추가 → 앱 재설치
2. NAVER WORKS API 첨부파일 다운로드 확인
3. skill-email: `download_attachment` 메서드 추가 (services/naverworks_provider.py)
4. PostgreSQL: `coldmail_classifier` 테이블 생성 (word, coldmail_count, normal_count)
5. PostgreSQL: `startup_valuation` 테이블 생성 (startup_name, valuation_median, valuation_lower, valuation_upper, confidence, metadata JSONB)
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: 스케줄러 라우터 등록 (routers/coldmail_scheduler.py, APScheduler)
12. rb8001: main.py에 라우터만 등록 (app.include_router)