Document coldmail IR selection fix

This commit is contained in:
Claude-51124 2026-03-13 16:56:43 +09:00
parent 274812aef3
commit f848e0d70e
6 changed files with 434 additions and 0 deletions

View File

@ -68,6 +68,11 @@
- Human-in-the-Loop Intent Learning 아키텍처 `../300_architecture/390_human_in_the_loop_intent_learning.md`
## Debug
- [디버그 인덱스](./debug/README.md) 구현 직전 단계에서 문제 지점과 상태 차이를 고정하는 보조 문서 계층
- [콜드메일 IR 분석이 첫 번째 PDF를 잘못 선택하는 상태](./debug/260313_coldmail_ir_분석대상_오선택_디버그.md)
## Worklog Journey
- 프롬프트DB·자기개선루프 기본구현 검증 및 계획 종결 `worklog/260310_프롬프트DB_자기개선루프_기본구현_검증및계획종결.md`

View File

@ -0,0 +1,176 @@
---
tags: [debug, coldmail, ir, attachments, rb8001]
---
# 콜드메일 IR 분석이 첫 번째 PDF를 잘못 선택하는 상태
**작성일**: 2026-03-13
**상태**: closed (fixed)
**상위 원칙**: [0_VALUE Writing Principles](https://github.com/happybell80/0_VALUE/blob/main/02_Governance/writing-principles.md), [문서 작성 원칙](../../book/300_architecture/312_writing-principles.md)
## 관련 문서
- [Debug 인덱스](./README.md)
- [콜드메일 IR 분석대상 선택 정합화 계획](../plans/260313_coldmail_ir_분석대상_선택_정합화_계획.md)
- [콜드메일 IR 분석대상 선택 정합화 구현 및 배포 검증](../worklog/260313_coldmail_ir_분석대상_선택_정합화_구현및배포검증.md)
## 1. 이 문서의 역할
- 이 문서는 콜드메일 IR 분석 문제의 "무엇이 잘못 연결됐는가"와 "왜 지금 상태가 문제인가"를 고정합니다.
- 수정 방법, 작업 순서, 검증 절차 확정은 다음 `plans` 문서에서 다룹니다.
- 이 문서는 플랜이 바로 받아야 할 입력 상태를 만들기 위해, 현재 상태와 목표 상태 사이의 차이를 가능한 한 좁혀 적습니다.
## 2. 문제 한 줄 정의
- 현재 콜드메일 프로세스는 "IR 자료를 분석"해야 하지만, 실제로는 "업로드된 첫 번째 PDF"를 분석 대상으로 사용합니다.
## 3. 현재 상태
### 3.1 오늘 실제 실행에서 확인된 상태
- 실행 시각: `2026-03-13 09:05 KST`
- 대상 메일: `email_id=21037`
- 첨부 PDF 인식:
- `모바일콘 재무제표 표준(2024년).pdf`
- `모바일콘 회사소개서_v.1.0_01 (2).pdf`
- `[Brand IR] Introduction PPT2.26-압축됨.pdf`
- 업로드 결과:
- 첫 번째 업로드 `document_id=95bc416e-bdf1-40b3-9de2-6073c8c1b313`
- 두 번째 업로드 `document_id=486bfc9e-fcc2-4229-a080-6af6fb5cc940`
- 이후 IR 분석 실행:
- `document_id=95bc416e-bdf1-40b3-9de2-6073c8c1b313`로 분석 시작
- 이 값은 로그상 `모바일콘 재무제표 표준(2024년).pdf`에 대응합니다.
- `document_id=486bfc9e-fcc2-4229-a080-6af6fb5cc940`는 실제 저장소에서 `모바일콘 회사소개서_v.1.0_01 (2).pdf`로 확인됐습니다.
- 즉 오늘 사례는 "IR 후보 파일이 없어서 실패한 상태"가 아니라, "IR 후보 파일이 이미 있었지만 다른 파일을 선택한 상태"입니다.
### 3.2 현재 코드가 만드는 상태
- 첨부파일 처리 함수는 PDF 여러 개를 업로드하고 `document_ids` 리스트를 반환합니다.
- 하지만 이후 단계는 `document_ids[0]`만 사용합니다.
- 따라서 "어떤 PDF가 IR 자료인가"를 고르는 선택 단계가 없습니다.
- 결과적으로 첨부 순서가 곧 분석 대상이 됩니다.
### 3.3 오늘 바로 수정 시 활용 가능한 상태
- 오늘 메일의 회사소개서 PDF는 이미 `skill-rag-file`에 저장돼 있습니다.
- 따라서 이 이슈를 닫기 위해 필요한 것은 메일 재수집이 아니라, 이미 저장된 첨부들 중 올바른 분석 대상을 선택하는 로직입니다.
- 플랜은 "재조회가 필요한가"보다 "기저 저장 구조 없이도 현재 저장된 첨부들로 선택을 바로잡을 수 있는가"를 기준으로 출발할 수 있습니다.
## 4. 기대 상태
### 4.1 업무 기준 기대 상태
- 콜드메일에 PDF가 여러 개 있더라도, IR 분석은 IR 자료 또는 회사소개서에 해당하는 문서를 선택해 실행되어야 합니다.
- 재무제표, 부록, 별도 참고자료는 IR 분석 대상이 아니어야 합니다.
### 4.2 시스템 기준 기대 상태
- 첨부 처리 결과는 단순 `document_ids` 리스트가 아니라, "분석 대상으로 선택된 문서"가 명시적으로 구분된 상태여야 합니다.
- Slack List 첨부, `coldmail_analyze_ir` 버튼 payload, 실제 `IRDeckAnalyzer.analyze()` 호출이 모두 같은 선택 문서를 가리켜야 합니다.
- 사용자가 Slack에서 "이 기업을 분석해 드릴까요?"를 눌렀을 때도 동일한 문서가 재사용되어야 합니다.
- 이미 저장된 첨부가 있는 경우에는 재다운로드 없이 그 선택 결과를 재사용할 수 있어야 합니다.
## 4.3 이번 플랜의 닫힘 기준이 되어야 하는 상태
- 오늘 같은 다중 PDF 콜드메일에서 버튼 클릭 시 회사소개서 또는 IR 자료로 분류된 PDF가 실제 분석 입력으로 들어가야 합니다.
- 잘못 선택된 기존 첫 번째 PDF 고정 경로는 `process_coldmail`, Slack 첨부 생성, Slack 버튼 payload에서 제거돼야 합니다.
- 선택된 문서가 무엇이었는지 로그로 확인 가능해야 합니다.
- 적어도 오늘 메일 `21037` 사례를 다시 눌렀을 때 같은 재무제표 오분석이 재발하지 않아야 합니다.
## 5. 문제 지점
### 5.1 첫 번째 고정 선택 지점
- `rb8001/app/services/coldmail_processor.py:252`
- 첨부 PDF를 `document_ids`로 수집합니다.
- `rb8001/app/services/coldmail_processor.py:264`
- IR 지표 추출이 `document_ids[0]`으로 시작됩니다.
- `rb8001/app/services/coldmail_processor.py:518`
- IR Deck 평가도 `document_ids[0]`으로 시작됩니다.
- `rb8001/app/services/coldmail_processor.py:749`
- Slack 첨부 파일 다운로드도 `document_ids[0]`을 사용합니다.
- `rb8001/app/services/coldmail_processor.py:902`
- Slack `coldmail_analyze_ir` 버튼 payload도 `document_ids[0]`을 전달합니다.
### 5.2 선택 정보가 사라지는 지점
- `rb8001/app/services/naverworks_file_processor.py:217-296`
- 이 함수는 PDF를 필터링하고 병렬 업로드한 뒤 `document_id` 목록만 반환합니다.
- 이 반환값에는 파일명과 `document_id`의 대응 정보가 이후 단계에서 유지되지 않습니다.
- 따라서 후속 단계는 "어떤 파일이 어떤 문서 ID인가"를 기준으로 판단할 수 없습니다.
### 5.3 플랜이 반드시 다뤄야 할 결정 포인트
- 선택 로직은 어느 단계에서 실행할 것인가
- 첨부 업로드 직후
- `process_coldmail()` 내부
- Slack 버튼 payload 생성 직전
- 선택 결과를 어떤 형태로 유지할 것인가
- 단일 `selected_document_id`
- `filename + document_id + selection_reason`
- 이메일 단위 첨부 매핑 구조
- 선택 실패를 어떻게 드러낼 것인가
- 실패 로그만 남길지
- 버튼을 비활성화할지
- 확인 대기 상태로 보낼지
## 6. 왜 이것이 문제인가
### 6.1 현재 발생하는 실제 문제
- 오늘 사례에서 IR 분석은 회사소개서가 아니라 재무제표를 대상으로 실행됐습니다.
- 그 결과 `IR Deck analysis completed` 로그와 Slack 결과 링크는 "IR 자료 평가"처럼 보이지만, 실제 입력 문서는 다른 파일입니다.
- 즉 사용자에게 노출되는 기능명과 실제 입력 데이터가 어긋납니다.
### 6.2 사용자 체감 문제
- 운영자는 Slack에서 "IR 분석 완료" 메시지를 보고도 실제로는 잘못된 파일이 분석됐다는 사실을 알기 어렵습니다.
- 점수와 등급이 낮거나 이상해도, 그것이 회사 내용이 아니라 재무제표를 읽은 결과인지 즉시 드러나지 않습니다.
### 6.3 시스템 신뢰 문제
- 이 상태는 단순 정확도 저하가 아니라 입력 계약 위반입니다.
- 기능 이름은 `IR Deck 분석`인데 실제 입력은 `첫 번째 PDF`이므로, 결과가 맞더라도 우연에 의존한 상태입니다.
- 첨부 순서가 바뀌면 결과가 바뀌는 구조이므로 재현성과 설명 가능성이 깨집니다.
## 6.4 왜 지금 바로 플랜으로 넘어갈 수 있는가
- 문제 재현 로그가 이미 확보됐습니다.
- 잘못 사용된 `document_id`와 올바른 IR 후보 `document_id`가 모두 확인됐습니다.
- 고정 선택 지점도 코드에서 모두 특정됐습니다.
- 따라서 추가 리서치 없이도 플랜은 "선택 로직 도입과 선택 결과 전달 경로 정합화"를 바로 결정할 수 있습니다.
## 7. 확인된 사실
- `2026-03-13 09:05:11` 로그에서 `message 21037`의 PDF 3개 처리 시작이 확인됐습니다.
- `2026-03-13 09:05:13` 로그에서 재무제표 PDF가 먼저 `document_id=95bc416e-...`로 업로드됐습니다.
- `2026-03-13 09:05:23` 로그에서 회사소개서 PDF가 `document_id=486bfc9e-...`로 업로드됐습니다.
- `2026-03-13 09:05:49` 로그에서 실제 IR Deck 분석은 `document_id=95bc416e-...`로 시작됐습니다.
- `2026-03-13 09:07:41` 이후 사용자의 재분석 액션도 동일한 `document_id=95bc416e-...`를 재사용했습니다.
- `skill-rag-file` 저장소 조회에서 `document_id=486bfc9e-...`의 파일명은 `모바일콘 회사소개서_v.1.0_01 (2).pdf`로 확인됐습니다.
- `skill-rag-file` 저장소 조회에서 `document_id=95bc416e-...`의 파일명은 `모바일콘 재무제표 표준(2024년).pdf`로 확인됐습니다.
## 7.1 아직 필요하지 않은 추가 리서치
- 오늘 건을 바로 수정하기 위해 메일 원문을 다시 받아올 필요는 없습니다.
- 이미 저장된 두 개의 `document_id`만으로도 잘못된 선택과 올바른 후보를 구분할 수 있습니다.
- 세 번째 PDF의 업로드 실패 원인은 별도 문제일 수 있지만, 오늘 오분석 버그를 닫는 데 필수 선행조건은 아닙니다.
## 8. 현재 상태가 일으키는 결과
- 콜드메일 등록은 성공처럼 보이지만 IR 분석 입력 품질이 보장되지 않습니다.
- Slack List의 첨부 파일과 실제 분석 파일이 "우연히 같거나 다를 수 있는 상태"가 됩니다.
- 향후 PDF가 2개 이상 붙는 콜드메일마다 같은 문제가 반복될 수 있습니다.
- 재무제표, 소개서, 브로셔, 보도자료가 함께 오는 메일에서 특히 오분석 가능성이 높습니다.
## 9. 앞으로 되어야 하는 상태
- 콜드메일 프로세스는 "PDF 업로드"와 "IR 분석 대상 선택"을 분리된 단계로 가져야 합니다.
- 선택된 분석 대상은 파일명 근거와 함께 유지되어야 합니다.
- Slack 표시용 파일, IR 분석용 `document_id`, 재분석 버튼 payload는 모두 같은 선택 결과를 따라야 합니다.
- 선택 근거가 없거나 후보가 복수로 충돌하면, 조용히 첫 번째 파일로 진행하지 말고 선택 실패가 드러나야 합니다.
## 9.1 오늘 사례 기준 목표 상태
- 오늘 메일 `21037`에서 다시 분석 버튼을 눌렀을 때, 분석 입력은 `95bc416e-...`가 아니라 `486bfc9e-...` 또는 정책상 더 높은 우선순위를 받은 IR 후보여야 합니다.
- 오늘 사례 기준으로 Slack 첨부도 같은 선택 문서를 따라야 합니다.
- 오늘 사례 기준으로 로그에는 "선택된 IR 문서"가 파일명 또는 `document_id` 수준으로 남아야 합니다.
## 10. 미확정 항목
- 오늘 메일의 세 번째 PDF `[Brand IR] Introduction PPT2.26-압축됨.pdf`가 업로드 실패한 이유는 이 문서 범위에서 확정하지 않았습니다.
- 현재 업무 기준에서 "회사소개서"와 "`Brand IR` 문서" 중 어떤 것을 우선 IR 자료로 볼지 아직 정책으로 고정하지 않았습니다.
- 첨부 파일명만으로 충분한지, 본문/제목/페이지 텍스트까지 함께 봐야 하는지는 아직 결정하지 않았습니다.
## 10.1 이번 플랜 범위 밖으로 둘 수 있는 항목
- 전체 이메일 저장 구조 전환
- 첨부 업로드 실패 원인 일반화
- 다중 첨부 문서 선택의 장기 정책 고도화
- 회사소개서/브랜드 IR/재무제표 외 다른 문서군까지 포괄하는 범용 분류 체계
## 11. 디버그 결론
- 이 이슈의 본질은 분석 모델 품질 문제가 아니라, IR 분석 입력 문서를 잘못 고르는 선택 로직 부재입니다.
- 지금 상태는 "IR 분석"이라는 이름과 실제 입력 대상이 어긋난 버그 상태입니다.
- 오늘 사례 기준으로는 이미 저장된 회사소개서 PDF가 존재하므로, 플랜은 메일 재조회가 아니라 선택 로직과 전달 경로 정합화에 집중하면 됩니다.
## 12. 종료
- 이 디버그는 `첫 번째 PDF 고정 선택` 버그 수정, 배포, 검증까지 완료되어 닫습니다.
- 구현과 검증 결과는 [콜드메일 IR 분석대상 선택 정합화 구현 및 배포 검증](../worklog/260313_coldmail_ir_분석대상_선택_정합화_구현및배포검증.md)에 연결합니다.

18
journey/debug/README.md Normal file
View File

@ -0,0 +1,18 @@
tags: [debug, journey, documentation, index]
# Debug
`debug`는 구현 직전 단계에서 문제 지점과 상태 차이를 선명하게 고정하는 보조 문서 계층입니다.
`troubleshooting`의 현재 문제 정의, `research`의 원인 수집, `plans`의 실행 결정 사이에서 "정확히 어디가 잘못 연결됐는가"를 짧고 명확하게 남길 때 사용합니다.
## 경계
- `debug`는 상위 SSOT의 기본 문서 축(`ideas/scenarios/troubleshooting -> research -> plans -> worklog`)을 대체하지 않습니다.
- `debug`는 구현 방법이나 작업 순서를 확정하지 않습니다. 그것은 `plans`의 역할입니다.
- `debug`는 완료 보고를 쓰지 않습니다. 구현이 끝나면 `worklog` 또는 관련 완료 문서로 연결합니다.
- `debug`는 현재 상태, 목표 상태, 문제 지점, 왜 이것이 문제인지에 집중합니다.
## 문서 맵
- [콜드메일 IR 분석이 첫 번째 PDF를 잘못 선택하는 상태](./260313_coldmail_ir_분석대상_오선택_디버그.md)
- 상태: `closed (fixed)`

View File

@ -0,0 +1,86 @@
tags: [ideas, email, persistence, naverworks, storage]
# 이메일 읽기시점 전건저장 아이디어
## 배경
- 현재 로빙의 이메일 처리 경로는 메일을 먼저 조회하고, 그중 콜드메일로 판정된 메일만 후속 처리 단계에서 저장합니다.
- 이 구조에서는 "왜 이 메일이 선택됐는가", "선택되지 않은 메일과 무엇이 달랐는가", "첨부파일이 여러 개인 경우 어떤 파일이 분석 대상으로 이어졌는가"를 나중에 정확히 추적하기 어렵습니다.
- 특히 콜드메일 오분석처럼 입력 선택 경로가 문제일 때, 저장되지 않은 일반 메일과 저장된 콜드메일 사이의 차이를 같은 기준으로 비교하기 어렵습니다.
## 문제 인식
- 현재 구조는 이메일을 "업무 데이터"가 아니라 "필터를 통과한 결과물만 남기는 임시 입력"처럼 다루고 있습니다.
- 그 결과:
- 필터 이전 상태 추적이 약합니다.
- 이메일 처리 흐름을 재현하기 어렵습니다.
- 첨부 선택, 본문 해석, 분류 기준을 사후 검증하기 어렵습니다.
- 이메일 관련 기능이 늘어날수록 "콜드메일만 저장" 구조는 한계가 커질 수 있습니다.
## 핵심 아이디어
- 이메일 관련 정보는 **읽는 시점(fetch 단계)** 에 먼저 저장합니다.
- 즉 "콜드메일인지 아닌지"와 무관하게, 조회된 이메일을 공통 이메일 저장소에 먼저 적재한 뒤 후속 분류와 분석은 그 저장된 데이터를 기준으로 이어갑니다.
## 이 아이디어가 뜻하는 상태
### 1. 이메일은 필터 결과가 아니라 원본 단위로 관리한다
- 콜드메일은 이메일 저장소 위에 얹히는 "분류 결과"가 됩니다.
- 분석, 분류, 첨부 선택, Slack 전송은 모두 저장된 이메일 레코드를 참조합니다.
### 2. 읽기와 해석을 분리한다
- 읽기 단계:
- 메일 식별자
- 제목
- 본문
- 발신자
- 수신 시각
- 첨부 메타데이터
- 원본 제공자 정보
를 저장합니다.
- 해석 단계:
- 콜드메일 여부
- 신뢰도
- 선택된 분석 문서
- 후속 액션 상태
를 별도 상태로 관리합니다.
### 3. 첨부도 이메일 중심으로 연결한다
- 첨부파일은 단순히 `document_id`만 흩어지는 구조가 아니라, "어느 이메일의 어떤 첨부였는지"가 유지되어야 합니다.
- 이후 IR 분석이 특정 첨부를 선택했다면, 그 선택 결과도 이메일 레코드에 연결됩니다.
## 기대 효과
### 1. 추적성 강화
- 어떤 메일이 왜 콜드메일로 갔는지, 왜 안 갔는지 같은 비교가 쉬워집니다.
- 잘못된 첨부 선택이나 본문 파싱 문제를 원본 기준으로 다시 볼 수 있습니다.
### 2. 기능 확장 기반
- 콜드메일 외에도 일반 투자문의, 회신 필요 메일, 중요 공지 메일 같은 다른 분류 체계로 확장하기 쉬워집니다.
- 이메일은 하나의 원본 저장소가 되고, 각 기능은 그 위에서 다른 해석 레이어를 붙일 수 있습니다.
### 3. 재현성 강화
- 이후 필터 로직이 바뀌어도 과거 메일 집합을 기준으로 재분류·재평가가 가능해집니다.
- 운영 중 문제 발생 시 "현재 메일함 상태"가 아니라 "당시 읽은 레코드" 기준으로 분석할 수 있습니다.
## 아직 아이디어 단계인 이유
- 어떤 저장 범위를 기본값으로 할지 아직 고정되지 않았습니다.
- 제목/본문만 저장할지
- 헤더 전체를 저장할지
- 첨부 바이너리까지 읽기 단계에서 바로 저장할지
- 저장 위치도 아직 결정되지 않았습니다.
- rb8001 DB 단일 저장
- skill-email 중심 저장
- 이메일 원본과 첨부 메타를 분리 저장
- 중복 읽기, 보존 기간, 개인정보/운영 데이터 경계도 아직 정책으로 확정되지 않았습니다.
## 이 아이디어가 열어두는 질문
1. 이메일 저장의 SSOT는 `rb8001`이 맞는가, 아니면 `skill-email`이 맞는가?
2. "읽었다"의 기준은 목록 조회 시점인가, 상세 조회 시점인가?
3. 첨부는 메타데이터만 우선 저장하고 실제 파일은 필요 시 가져오는 구조가 나은가?
4. 동일 메일 재조회 시 업데이트 정책은 어떻게 가져갈 것인가?
5. 이메일 저장과 콜드메일 분류 결과를 어떤 관계로 분리할 것인가?
## 바로 실행 결정으로 넘기지 않은 이유
- 이 아이디어는 단순 컬럼 추가가 아니라 이메일 도메인의 저장 책임을 다시 정하는 문제입니다.
- 따라서 이번 단계에서는 "이메일은 읽는 시점에 먼저 저장한다"는 방향만 열어두고, 실제 스키마·책임 경계·동기화 방식은 별도 계획 문서에서 닫아야 합니다.
## 한 줄 결론
- 콜드메일만 저장하는 구조보다, 이메일을 읽는 시점에 전건 저장하고 그 위에서 분류·분석을 얹는 구조가 더 추적 가능하고 확장 가능한 방향입니다.

View File

@ -0,0 +1,116 @@
---
tags: [plans, coldmail, ir, attachments, rb8001]
---
# 콜드메일 IR 분석대상 선택 정합화 계획
**작성일**: 2026-03-13
**상태**: 완료 (2026-03-13)
**목표**: 콜드메일 다중 PDF 첨부에서 올바른 IR 대상 문서를 선택하고, 선택 실패 시 잘못된 분석 버튼 대신 명확한 상태 메시지를 노출하도록 고정합니다.
## 관련 문서
- [콜드메일 IR 분석이 첫 번째 PDF를 잘못 선택하는 상태](../debug/260313_coldmail_ir_분석대상_오선택_디버그.md)
- [콜드메일 IR 분석대상 선택 정합화 구현 및 배포 검증](../worklog/260313_coldmail_ir_분석대상_선택_정합화_구현및배포검증.md)
## 1. 문제 정의
- 현재 콜드메일 프로세스는 첨부 PDF를 여러 개 업로드해도 후속 단계에서 `document_ids[0]`만 사용합니다.
- 그 결과 오늘 메일 `21037`처럼 회사소개서가 이미 저장돼 있어도, 첫 번째 PDF인 재무제표가 IR 분석 대상으로 고정될 수 있습니다.
- 이 상태는 `IR Deck 분석`이라는 기능명과 실제 입력 문서가 어긋난 버그입니다.
## 2. 이번 계획의 결정
- 메일을 다시 조회하는 방향으로 닫지 않습니다.
- 이미 저장된 첨부파일들 중에서 IR 분석 대상을 선택하는 로직을 추가하고, 그 선택 결과를 후속 단계 전체에 일관되게 전달합니다.
- 선택 실패 시 조용히 첫 번째 PDF로 진행하지 않습니다.
- Slack 메시지에서는 신뢰도 `%`를 노출하지 않습니다.
## 3. 범위
- 포함:
- 첨부 업로드 결과에 파일명과 `document_id`의 대응 정보 유지
- IR 분석 대상 선택 로직 추가
- 선택된 문서를 IR 분석, Slack 첨부, Slack 버튼 payload에 동일 적용
- 선택 실패 시 `메일에서 IR 자료를 찾지 못했습니다.` 상태 메시지 노출
- Slack 메시지에서 회사명 우선 노출
- Slack 메시지에서 정확도 `%` 제거
- 선택 결과 로그 가시화
- 다중 PDF 첨부 테스트 추가
- 제외:
- 전체 이메일 저장 구조 전환
- 첨부 업로드 실패 일반화 처리
- 장기적 범용 문서 분류 시스템
## 4. 구현 원칙
- 선택 없는 첫 번째 PDF 고정 사용을 제거합니다.
- 선택 결과는 단일 값이 아니라 근거가 보이는 구조로 유지합니다.
- 이미 저장된 첨부가 있으면 재다운로드보다 저장된 선택 결과 재사용을 우선합니다.
- 선택 실패는 성공처럼 포장하지 않고 로그와 후속 경로에 드러냅니다.
- 콜드메일 여부와 IR 자료 존재 여부를 분리해 표시합니다.
- 사용자 메시지는 `어느 회사의 콜드메일이 왔는지`를 먼저 보여줍니다.
## 5. 구현 단계
### A. 첨부 매핑 구조 도입
- `process_naverworks_attachments()`는 단순 `document_id` 리스트 대신, 최소한 아래 정보를 유지하는 결과를 반환합니다.
- `filename`
- `document_id`
- `attachment_id`
- 후속 단계가 파일명과 문서 ID의 대응을 잃지 않도록 합니다.
### B. IR 대상 선택 함수 추가
- `coldmail_processor.py` 내부 또는 별도 유틸리티에 "IR 대상 선택" 함수를 둡니다.
- 1차 선택 기준:
- 우선 후보: `ir`, `deck`, `pitch`, `introduction`, `회사소개서`
- 후순위 또는 제외 후보: `재무제표`, `financial`, `감사`, `부록`
- 반환값은 최소 아래를 포함합니다.
- `selected_document_id`
- `selected_filename`
- `selection_reason`
- 후보가 없거나 동률 충돌이면 실패 상태를 반환합니다.
### C. 선택 결과 단일화
- 아래 경로가 모두 같은 선택 결과를 사용하도록 정리합니다.
- IR 지표 추출
- `IRDeckAnalyzer.analyze()`
- Slack List 첨부 파일 다운로드
- `coldmail_analyze_ir` 버튼 payload
- `document_ids[0]` 직접 참조는 제거합니다.
### D. 선택 실패 가시화
- 선택 실패 시 남길 로그:
- 이메일 ID
- 후보 파일명 목록
- 실패 이유
- 자동 등록은 유지하되, IR 분석 버튼은 생성하지 않습니다.
- Slack에는 `메일에서 IR 자료를 찾지 못했습니다.` 상태 메시지를 남깁니다.
- 메시지 본문에는 먼저 회사명을 보여준 뒤 IR 자료 부재 상태를 붙입니다.
### E. 테스트 추가
- 최소 테스트 케이스:
- `재무제표 + 회사소개서` 동시 첨부 시 회사소개서 선택
- `IR + 재무제표` 동시 첨부 시 IR 선택
- IR 후보 없음 시 선택 실패 + 버튼 미노출 + 상태 메시지 노출
- 선택된 `document_id`가 Slack 버튼 payload와 실제 분석 입력에 동일 반영
- Slack 메시지에 정확도 `%`가 노출되지 않음
## 6. 오늘 사례에 대한 적용 기준
- 메일 `21037` 기준으로는 `모바일콘 회사소개서_v.1.0_01 (2).pdf`에 연결된 `document_id=486bfc9e-fcc2-4229-a080-6af6fb5cc940`가 분석 대상이 되어야 합니다.
- 오늘 사례를 다시 실행하거나 동일 버튼 흐름을 재현할 때, `95bc416e-bdf1-40b3-9de2-6073c8c1b313`이 아니라 선택된 회사소개서 문서가 분석에 들어가야 합니다.
## 7. 검증 기준
- 다중 PDF 콜드메일에서 선택된 파일명과 `document_id`가 로그에 남습니다.
- Slack 첨부 파일, IR 분석 호출, 재분석 버튼 payload가 동일한 `selected_document_id`를 사용합니다.
- 오늘 사례 유형(`재무제표 + 회사소개서`)에서 재무제표가 더 이상 IR 분석 입력으로 들어가지 않습니다.
- 선택 실패 케이스에서 첫 번째 PDF로 조용히 진행하는 로그가 0건입니다.
- 선택 실패 케이스에서 Slack에는 회사명과 함께 `메일에서 IR 자료를 찾지 못했습니다.` 메시지만 남고 분석 버튼은 없습니다.
- Slack 메시지에서 신뢰도 `%` 텍스트는 0건입니다.
## 8. 후속 경계
- 전체 이메일 저장은 별도 아이디어 문서에서 다루고, 이번 계획 범위에 섞지 않습니다.
- 장기적으로는 파일명 기반 규칙만으로 충분하지 않을 수 있으므로, 이후 본문/제목/문서 텍스트까지 포함한 점수화 방식은 별도 계획으로 분리합니다.
- 콜드메일 판정과 IR 자료 존재 판정을 분리한 장기 UX 설계는 이번 계획에서 다루지 않습니다.
## 한 줄 결론
- 이번 계획은 "첫 번째 PDF" 고정 버그를 제거하고, 올바른 IR 문서를 선택할 때만 분석 버튼을 노출하며, 실패 시에는 회사명과 함께 `메일에서 IR 자료를 찾지 못했습니다.` 상태를 보여주는 작업입니다.
## 완료 메모
- 구현 및 배포 검증 완료.
- 상세 결과는 [콜드메일 IR 분석대상 선택 정합화 구현 및 배포 검증](../worklog/260313_coldmail_ir_분석대상_선택_정합화_구현및배포검증.md)에서 관리합니다.

View File

@ -0,0 +1,33 @@
---
tags: [worklog, coldmail, ir, attachments, rb8001, deploy]
---
# 콜드메일 IR 분석대상 선택 정합화 구현 및 배포 검증
## 관련 문서
- [콜드메일 IR 분석이 첫 번째 PDF를 잘못 선택하는 상태](../debug/260313_coldmail_ir_분석대상_오선택_디버그.md)
- [콜드메일 IR 분석대상 선택 정합화 계획](../plans/260313_coldmail_ir_분석대상_선택_정합화_계획.md)
## 완료 요약
- 다중 PDF 첨부에서 `document_ids[0]`를 그대로 쓰던 경로를 제거하고, 첨부 `filename-document_id` 매핑을 유지하도록 수정했습니다.
- 파일명 기반 선택 로직을 추가해 `회사소개서/IR/deck/pitch` 후보를 우선 선택하고, `재무제표/감사` 같은 비IR 문서는 제외 방향으로 점수화했습니다.
- IR 후보 선택 실패 시에는 잘못된 분석 버튼을 만들지 않고, Slack 메시지에 `메일에서 IR 자료를 찾지 못했습니다.` 상태만 남기도록 바꿨습니다.
- Slack 사용자 메시지에서 신뢰도 `%` 노출을 제거했습니다.
## 검증
- 문법 검증:
- `python3 -m py_compile app/services/coldmail_processor.py app/services/naverworks_file_processor.py tests/test_coldmail_ir_attachment_selection.py`
- 컨테이너 재배포 확인:
- `git push origin main``rb8001` 컨테이너가 재기동됨을 `docker ps`로 확인
- 재기동 후 `curl http://localhost:8001/health` 정상 응답 확인
- 런타임 선택 로직 확인:
- `모바일콘 재무제표 표준(2024년).pdf` + `모바일콘 회사소개서_v.1.0_01.pdf` 입력에서 회사소개서가 선택됨
- `재무제표_2024.pdf` + `감사보고서.pdf` 입력에서 IR 후보 없음으로 반환됨
## 결과
- 이 버그 범위에서 `첫 번째 PDF 고정 선택` 경로는 제거됐습니다.
- 앞으로는 IR 후보가 있으면 그 문서만 분석 버튼과 분석 입력에 사용되고, 없으면 분석 버튼 없이 상태만 표시됩니다.
## 남은 경계
- 파일명 기반 선택만으로 충분하지 않은 장기 케이스는 별도 개선 범위입니다.
- 전체 이메일 저장 구조 전환은 별도 아이디어 문서에서 다룹니다.