# task-3046 — 신규설계 비교를 고객중심 흐름으로 재구성

**레벨**: Lv.3 · **팀**: dev3-team · **회장 승인 완료** (2026-08-28)
**저장소**: `Jeon-Jonghyuk/InsuRo` (`/home/jay/projects/InsuRo`, 기본 브랜치 **main**)
**기반 브랜치**: `task/task-3024-dev3` (PR #259, head `cedcee1`) — **그 위에서 이어서 작업한다**

---

## ★ 회장이 확정한 흐름 (2026-08-26, ANU 정리안 승인)

> A고객이 있어.
> 1. **기존 증권분석 메뉴**에서 고객이 준비했던 증권(pdf 또는 사진)과 약관을 업로드해 현재 상황을 정리
> 2. 신규 설계안 비교는 **2가지 역할**:
>    (1) 다양한 보험사 신규 설계안의 가입제안서·약관을 업로드해 **설계안끼리 비교**해 최적안 선택(가성비 등)
>    (2) 최적안 결정 후, 기존 증권에서 **일부 또는 전체 해지한 부분 + 신규 준비분**을 종합해
>        최종적으로 어떤 보장을 받게 되는지. **1번과 비교한 보장 변화 + 보험료 합계 변화**를
>        고객 입장에서 궁금해할 내용으로 정리
> 그런데 지금은 **기존 증권을 두 번 업로드하게 유도**하고 있다. A고객을 선택하면 DB에 저장돼
> 두 번 업로드할 필요 없어야 하는데 정리가 안 돼 있다.

---

## 현재 상태 (PR #259) — ANU 실측

### 살릴 것 — 서버는 그대로 쓸 수 있다
```
server/routes/proposal_upload_v1.py   +312   POST /api/insuro/proposal/upload
                                             GET  /api/insuro/proposal/status/{job_id}
server/policy_extract/proposal_mapping.py +212  ProposalExtract → 비교 입력 변환
server/tests/test_proposal_upload_v1_task3024.py +443
server/main.py +2 (라우터 등록)
```
★ **실 PDF 로 검증 완료**돼 있다(메리츠 제안서 34담보 매핑 성공). 서버는 건드리지 마라.

### 고칠 것 — 화면 흐름
```
src/pages/NewDesignComparison.tsx
  :65   ① 기존 설계(증권 PDF/JPG/PNG) 업로드 → /api/insuro/analyze-policy → 폴링
  :265  ① 기존 설계(증권) 업로드 → 폴링
  :274  "증권 분석 API 가 고객명을 필수로 요구합니다. 고객명을 입력..."
  customer-policy-analyses 참조: 0건    ← ★ 고객별 기존 분석을 전혀 안 불러온다
```
**기존 증권을 다시 업로드시킨다.** 이것이 회장 지적의 핵심이다.

---

## 만들 것

### ① 고객 선택 → 기존 증권분석 자동 로드
```
GET /api/insuro/customer-policy-analyses/{customer_id}   ← 이미 존재 (main.py:7488)
GET /api/insuro/search-customers?q=...                   ← 이미 존재, PolicyAnalysis.tsx:155 에서 사용 중
```
- 화면 진입 시 **고객을 선택**하게 한다. 고객명 타이핑이 아니라 **선택**이다
- 선택하면 그 고객의 **완료된 증권분석을 자동으로 불러온다**. 재업로드 UI 를 제거하라
- 분석 이력이 없으면 **"먼저 증권분석을 해주세요" 안내 + 바로가기**를 보여준다.
  거기서 업로드시키지 마라 — 증권 업로드는 증권분석 메뉴의 일이다
- ★ 여러 건이면 **어느 분석을 쓸지 고르게** 하라(최신 자동선택 + 변경 가능)

### ② (1) 설계안끼리 비교 — 기존 증권 불필요
- 신규 설계안(가입제안서 PDF)을 **여러 건** 업로드해 **설계안끼리** 비교한다
- 이 단계에서는 기존 증권이 필요 없다. 고객 선택 없이도 진행 가능해야 하는지 판단하고
  근거를 남겨라(회장 흐름상 (1)은 설계안 간 비교다)
- 최적안을 **선택**할 수 있어야 한다
- ★ 가성비 계산(단위가입한도당 보험료)은 **이번 범위가 아니다.** 별도 태스크다.
  자리만 남기고 구현하지 마라

### ③ (2) 최종 종합 — 기존 + 신규
- 최적안 + 기존 증권을 종합한다
- ★ **해지분 선택**: 기존 증권 담보 목록에서 **해지할 항목을 고를 수 있어야** 한다.
  전체 해지 / 일부 해지 둘 다 가능해야 한다
- 산출물은 회장 표현 그대로다:
  **"1번과 비교한 보장 변화 + 보험료 합계 변화"** — 고객이 궁금해할 관점으로
- 기존 비교 엔진(`new_design_comparison_v1`)을 쓴다. 엔진 로직은 건드리지 마라

### ④ 실패를 드러낼 것
- 파싱 실패·부분 실패(`parse_state`, `premium_reconciled=False`, `warnings`)를 화면에 노출
- ★ 성공 문구를 기본값으로 두지 마라. 2026-07~08 에 "저장됐어요"가 4주간 실패를 가린 사고가 있었다

---

## ★ 알아둘 것 — 공식 비교표가 0행으로 나올 수 있다
ANU 가 t3024 에서 확인했다.
```
mapped coverages 34 → official_row_count 0 · excluded 35 (전량 unknown_report)
원인: 지식DB 담보 등록률 14/299 (메리츠). 배선 결함 아님
엔진이 CoverageNotice 로 정직하게 고지한다 — 설계대로다
```
**이걸 고치려 하지 마라.** 지식DB 시딩 문제이며 별건이다. 화면은 그 고지를 **사용자에게 잘 전달**하면 된다.

---

## ★ 하지 말 것
- **서버 변경 금지** (`proposal_upload_v1.py` · `proposal_mapping.py` · `main.py`)
- 비교 엔진 로직 변경 (`policy_grouping/**` · 담보 매칭 · 실손 계산은 봉인 영역)
- 증권분석 화면(`PolicyAnalysis.tsx`) 변경
- 가성비 계산 구현 (별도 태스크)
- 지식DB 시딩 시도

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "src/pages/NewDesignComparison.tsx"
    - "src/components/policy/**"
    - "src/pages/__tests__/**"
    - "src/components/**/__tests__/**"
    - "src/**/__tests__/**"
    - "memory/reports/task-3046.md"
  forbidden_paths:
    - "server/**"
    - "src/pages/PolicyAnalysis.tsx"
    - "src/pages/KeywordAnalysis.tsx"
    - "src/data/generateOptions.ts"
    - "extension/**"
    - ".github/workflows/**"
  commands: ["npm", "npx", "node", "bash", "python3", "gh"]
  merge_policy: "tiered"
  ttl_hours: 24
```
★ 테스트 경로를 넓게 열어뒀다. 그래도 부족하면 **진행하지 말고 ANU 에 보고**하라
(t3042 에서 `src/pages/__tests__/` 가 scope 밖으로 잡혀 막힌 전례가 있다 — ANU 명세 결함이었다).

## 검증 (실측 강제)
1. **재업로드 제거 실증** — 고객을 선택했을 때 기존 증권 업로드 UI 가 **나타나지 않는지**.
   스크린샷으로
2. **자동 로드 실증** — 실제 고객의 완료된 증권분석이 불러와지는지. API 응답과 화면을 함께
3. **분석 없는 고객** — "먼저 증권분석을 해주세요" 안내가 뜨는지
4. **(1) 설계안 비교** — 제안서 PDF 2건 이상으로 설계안끼리 비교가 되는지.
   ★ 샘플 PDF: `/home/jay/workspace/memory/samples/proposal_meritz_*.pdf` (t3024 에서 사용)
5. **(2) 해지분 선택** — 기존 담보에서 일부를 해지로 선택했을 때 결과가 달라지는지
6. **실패 표면화** — 깨진 PDF 를 넣었을 때 사용자에게 무엇이 보이는지
7. **회귀** — `vitest` **base 재측정 기준선**
8. **봉인** — 기존 증권 재업로드 UI 를 되살리는 변이를 만들어 테스트가 FAIL 하는지 확인·복원.
   변이가 no-op 이 아님을 `assert` 로 먼저 증명하라

## 완료 조건 (DoD)
**고객을 선택하면 기존 증권분석이 자동으로 불러와지고 재업로드가 없으며,
신규 설계안끼리 비교해 최적안을 고른 뒤, 해지분을 선택해 최종 보장·보험료 변화를 볼 수 있다.**

## ★ 세션 조기 종료 대책
시작 즉시 브랜치 + 드래프트 PR 을 먼저 열어라. **단계마다 커밋하라.**
범위가 크다 — **①고객선택·자동로드 → ②설계안 비교 → ③최종 종합** 순으로 하고 각 단계 끝에 커밋하라.
★ ANU 명세 전제가 틀렸다고 판단되면 구현하지 말고 **반증을 먼저 기록한 뒤 보고하라.**

## 운영 계약
- **기반**: `task/task-3024-dev3`(PR #259) 위에서 이어간다. 최신 `origin/main` 을 먼저 병합하라
- ★ **worktree 를 써라.** 메인 저장소는 cron 이 매일 06:00·08:00 에 직접 실행한다
- ★ `gh` 호출 시 `GH_TOKEN="$BOT_GITHUB_TOKEN"` 주입 필수 (회장 개인 PAT 금지 — 감사기록 오염)
- 워크플로우 `/home/jay/workspace/prompts/DIRECT-WORKFLOW.md` · QC `/home/jay/workspace/teams/shared/QC-RULES.md`
- `WORKSPACE_ROOT=/home/jay/workspace` · `CHAT_ID=6937032012` · 수집자 key `ANU_KEY=c119085addb0f8b7`
- 완료 경로는 `finish-task.sh` 실행이 유일하다. 수동 `.done` 금지.

## 보고
**PR 생성까지가 범위다. 머지는 ANU 가 한다. 자동 머지 금지.**
`memory/reports/task-3046.md` 작성 후 표준 완료 콜백 등록. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.
★ 봉투 첫 줄에 **"기존 증권 재업로드 제거 여부 + 고객 선택 자동로드 실증 여부"** 를 담아라.