docs: Coldmail Slack Lists 컬럼 매핑 및 IR 대표 이름 추출 스펙 문서 추가
- 251122_coldmail_slack_lists_column_mapping_spec.md: 컬럼 매핑 스펙 및 검증 시나리오 - 251122_ir_representative_name_extraction_spec.md: IR 문서 대표 이름 추출 설계
This commit is contained in:
parent
b33691964e
commit
5f28de18fa
@ -0,0 +1,131 @@
|
|||||||
|
# Coldmail Slack Lists 컬럼 매핑 스펙
|
||||||
|
|
||||||
|
**날짜**: 2025-11-22
|
||||||
|
**작성자**: Claude
|
||||||
|
**관련 파일**:
|
||||||
|
- `rb8001/app/services/coldmail_processor.py`
|
||||||
|
- `rb8001/app/services/ir_analyzer.py`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Slack Lists 실제 컬럼 구조
|
||||||
|
|
||||||
|
**확인 방법**: Slack Lists UI에서 확인 (이미지 참조)
|
||||||
|
|
||||||
|
| 컬럼 이름 | 타입 | 용도 | 현재 코드 매핑 |
|
||||||
|
|-----------|------|------|----------------|
|
||||||
|
| 회사설명 | rich_text | 회사명 저장 | ❌ business_area 저장 중 |
|
||||||
|
| 날짜 | date | 이메일 수신일 | ✅ 정상 |
|
||||||
|
| 대표 | rich_text | 대표 이름 저장 | ❌ From 헤더 발신자 이름 |
|
||||||
|
| 이메일 | email | 이메일 주소 | ✅ 정상 |
|
||||||
|
| IR Deck | attachment | PDF 파일 첨부 | ✅ 정상 (attach_id) |
|
||||||
|
| 확인 | checkbox | 체크박스 | ❌ deck_id에 혼재 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 요구사항 (테스트 기준)
|
||||||
|
|
||||||
|
### 1. "회사설명" 컬럼
|
||||||
|
- **저장 값**: `company_name` (IR 문서 또는 휴리스틱으로 추론한 회사명)
|
||||||
|
- **현재**: `business_area` 또는 제목 저장 (수정 필요)
|
||||||
|
- **검증**: Slack Lists에서 "회사설명" 컬럼에 회사명이 표시되어야 함
|
||||||
|
|
||||||
|
### 2. "대표" 컬럼
|
||||||
|
- **저장 값**: 대표 이름 (`representative_name`)
|
||||||
|
- **우선순위**:
|
||||||
|
1. IR 문서에서 추출한 대표 이름
|
||||||
|
2. From 헤더에서 파싱한 발신자 이름 (fallback)
|
||||||
|
3. 없으면 "없음" (현재 정책 유지)
|
||||||
|
- **검증**: IR 문서에 대표 이름이 있으면 IR 우선, 없으면 From 헤더 사용
|
||||||
|
|
||||||
|
### 3. "IR Deck" 컬럼
|
||||||
|
- **저장 값**: PDF 파일 (attachment 타입)
|
||||||
|
- **매핑**: `attach_id` 사용 (현재 정상)
|
||||||
|
- **컬럼 이름 매칭**: "ir deck", "irdeck", "ir 덱" 등
|
||||||
|
- **검증**: IR PDF 파일이 "IR Deck" 컬럼에 첨부되어야 함
|
||||||
|
|
||||||
|
### 4. "확인" 컬럼
|
||||||
|
- **저장 값**: 체크박스 (기본 False)
|
||||||
|
- **매핑**: `check_id` 별도 컬럼
|
||||||
|
- **컬럼 이름 매칭**: "확인"만 (IR Deck과 분리)
|
||||||
|
- **검증**: "확인" 컬럼에 체크박스가 표시되어야 함 (IR Deck과 별도)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IR 문서 추출 필드 스펙
|
||||||
|
|
||||||
|
### 현재 추출 필드 (ir_analyzer.py:257-265, 296-304)
|
||||||
|
- company_name
|
||||||
|
- business_area
|
||||||
|
- investment_stage
|
||||||
|
- revenue
|
||||||
|
- growth_rate
|
||||||
|
- team_size
|
||||||
|
- tech_advantage
|
||||||
|
|
||||||
|
### 추가 필요 필드
|
||||||
|
- **representative_name**: 대표이사/CEO 이름
|
||||||
|
- RAG 쿼리: "이 회사의 대표이사 또는 CEO 이름은 무엇인가?"
|
||||||
|
- LLM 프롬프트 키: `representative_name`
|
||||||
|
- 형식: "홍길동" (이름만)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 우선순위 정책
|
||||||
|
|
||||||
|
### 회사명 (company_name)
|
||||||
|
1. IR 문서 `company_name` (유효하면 사용)
|
||||||
|
2. 휴리스틱 `_derive_company_name` (제목/발신 도메인)
|
||||||
|
3. `business_area` (fallback)
|
||||||
|
|
||||||
|
### 대표 이름 (representative_name)
|
||||||
|
1. IR 문서 `representative_name` (추출 시)
|
||||||
|
2. From 헤더 `contact_name` (발신자 이름)
|
||||||
|
3. "없음" (둘 다 없을 때)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 검증 시나리오
|
||||||
|
|
||||||
|
### 시나리오 1: IR 문서에 대표 이름 있는 경우
|
||||||
|
- **IR 문서**: 대표이사 "김철수" 명시
|
||||||
|
- **From 헤더**: "홍길동 <hong@company.com>"
|
||||||
|
- **예상 결과**: "대표" 컬럼 = "김철수" (IR 우선)
|
||||||
|
|
||||||
|
### 시나리오 2: IR 문서에 대표 이름 없는 경우
|
||||||
|
- **IR 문서**: 대표 이름 정보 없음
|
||||||
|
- **From 헤더**: "홍길동 <hong@company.com>"
|
||||||
|
- **예상 결과**: "대표" 컬럼 = "홍길동" (From 헤더 fallback)
|
||||||
|
|
||||||
|
### 시나리오 3: 둘 다 없는 경우
|
||||||
|
- **IR 문서**: 대표 이름 정보 없음
|
||||||
|
- **From 헤더**: "hong@company.com" (이름 없음)
|
||||||
|
- **예상 결과**: "대표" 컬럼 = "없음"
|
||||||
|
|
||||||
|
### 시나리오 4: 회사설명 컬럼 검증
|
||||||
|
- **IR 문서**: company_name="(주)테크스타트업"
|
||||||
|
- **예상 결과**: "회사설명" 컬럼 = "(주)테크스타트업" (company_name)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 구현 완료 조건
|
||||||
|
|
||||||
|
- [ ] IR analyzer에서 `representative_name` 추출 구현
|
||||||
|
- [ ] Coldmail processor에서 회사설명 컬럼에 `company_name` 저장
|
||||||
|
- [ ] 대표 컬럼에 IR 우선순위 적용
|
||||||
|
- [ ] IR Deck과 확인 컬럼 분리 매핑
|
||||||
|
- [ ] 검증 시나리오 1-4 모두 통과
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 교훈
|
||||||
|
|
||||||
|
### 문서화 부족
|
||||||
|
- Slack Lists 컬럼 구조가 코드에 휴리스틱으로만 존재
|
||||||
|
- 실제 컬럼 이름과 매핑 정책이 명시적으로 문서화되지 않음
|
||||||
|
- 교훈: UI와 코드 매핑은 항상 문서로 정리하고 동기화
|
||||||
|
|
||||||
|
### 필드 이름 일관성
|
||||||
|
- IR 추출 필드명 (`representative_name`)과 사용처 필드명 (`contact_name`) 혼재
|
||||||
|
- 교훈: 필드 이름은 추출 단계부터 사용 단계까지 일관성 유지
|
||||||
|
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
# IR 문서 대표 이름 추출 스펙
|
||||||
|
|
||||||
|
**날짜**: 2025-11-22
|
||||||
|
**작성자**: Claude
|
||||||
|
**관련 파일**:
|
||||||
|
- `rb8001/app/services/ir_analyzer.py`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 요구사항
|
||||||
|
|
||||||
|
IR 문서에서 대표이사/CEO 이름을 추출하여 coldmail processor에서 "대표" 컬럼에 저장.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 현재 상태
|
||||||
|
|
||||||
|
### 추출 필드 목록 (ir_analyzer.py:257-265)
|
||||||
|
- company_name
|
||||||
|
- business_area
|
||||||
|
- investment_stage
|
||||||
|
- revenue
|
||||||
|
- growth_rate
|
||||||
|
- team_size
|
||||||
|
- tech_advantage
|
||||||
|
|
||||||
|
**대표 이름 필드 없음**
|
||||||
|
|
||||||
|
### LLM 프롬프트 (ir_analyzer.py:296-304)
|
||||||
|
- `exact keys` 목록에 `representative_name` 없음
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 설계
|
||||||
|
|
||||||
|
### 1. RAG 쿼리 추가
|
||||||
|
**위치**: `ir_analyzer.py:257-265` queries 딕셔너리
|
||||||
|
|
||||||
|
**추가 쿼리**:
|
||||||
|
```python
|
||||||
|
"representative_name": "이 회사의 대표이사 또는 CEO 이름은 무엇인가? (예: 홍길동, 김철수)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. LLM 프롬프트 키 추가
|
||||||
|
**위치**: `ir_analyzer.py:296-304` prompt의 `exact keys` 목록
|
||||||
|
|
||||||
|
**추가 키**:
|
||||||
|
```python
|
||||||
|
- representative_name: 대표이사 또는 CEO 이름 (예: "홍길동", "김철수")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 반환 형식
|
||||||
|
**타입**: `str`
|
||||||
|
**형식**: 이름만 (예: "홍길동", "김철수")
|
||||||
|
**없을 때**: "N/A"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 우선순위 정책
|
||||||
|
|
||||||
|
**coldmail_processor.py에서 사용**:
|
||||||
|
1. IR 문서 `representative_name` (유효하면)
|
||||||
|
2. From 헤더 `contact_name` (fallback)
|
||||||
|
3. "없음" (둘 다 없을 때)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 검증 기준
|
||||||
|
|
||||||
|
### 성공 케이스
|
||||||
|
- IR 문서에 "대표이사: 홍길동" 명시 → `representative_name = "홍길동"`
|
||||||
|
- IR 문서에 "CEO: 김철수" 명시 → `representative_name = "김철수"`
|
||||||
|
|
||||||
|
### 실패 케이스
|
||||||
|
- IR 문서에 대표 이름 정보 없음 → `representative_name = "N/A"`
|
||||||
|
- IR 문서 파싱 실패 → `representative_name = "N/A"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 구현 완료 조건
|
||||||
|
|
||||||
|
- [ ] RAG 쿼리에 `representative_name` 추가
|
||||||
|
- [ ] LLM 프롬프트에 `representative_name` 키 추가
|
||||||
|
- [ ] 실제 IR 문서로 테스트 (대표 이름 있는 경우/없는 경우)
|
||||||
|
- [ ] coldmail processor에서 IR `representative_name` 우선 사용
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user