# task-2888 보고서 — 생보 3대질병 계단식 SVG 재구현(승인 목업 v2 + 평가 미팅 반영)

- 팀: dev1-team (헤르메스) · 팀원: 불칸(lib), 이리스(component/SVG), 아르고스(e2e)
- 레벨: Lv.3 · merge_policy: **none**(머지·검증·CF Pages 배포는 ANU) · webapp-only(서버/확장/손보 무변경)
- worktree: `/home/jay/projects/InsuRo/.worktrees/task-2888-dev1` · branch `task/task-2888-dev1` · base `origin/main` ab7d44c

## Situation
task-2887이 생보 3대질병 계단식을 HTML 테이블 기반으로 1차 재설계했으나, 회장 승인 목업 v2(`life_staircase_mock_v2.png`) + 2차 평가 미팅 기준으로 **손보 계단식과 동일 양식의 SVG 계단식 2개 + 91%류 리드 배너 + 담보별 근거표**로 전면 재구현이 요구됨.

## Complication
- 기존 구조(baseline→cancer_only→all_three 시나리오 HTML 표)와 목표 구조(① 암 SVG 계단 · ② 3대질병 SVG 계단 · 배너 %게이지 · 근거표 비율바)가 상이 → 뷰모델·컴포넌트·테스트·e2e 전면 교체 필요.
- N%(배너)는 하드코딩 금지 — 실데이터 산출(①암만 월차액 ÷ ②3대질병 전체 월차액). ①암 최저 생보사와 ②3담보합 최저 단일 생보사가 다를 수 있음.
- 납입연수 payment_years 동적(20 하드코딩 금지), exact 원(반올림 금지), 색+부호 이중인코딩(색맹 대비), 곡선 금지.

## Question
목업 v2를 픽셀 충실하게, 손보 양식과 통일된 SVG로 재현하면서 손보/서버/확장 회귀 0으로 구현 가능한가?

## Answer (수행 내용)
### 1. lib (불칸) — `src/lib/lifeThreeCritical.ts`
- 신규 `computeLifeThreeCriticalView(lifeMatrix, composite, coverageNameMap?, paymentYears?)` + 타입(LifeStairSide/LifeStairView/LifeEvidenceRow/LifeThreeCriticalView).
  - ① cancerStair: 손보 배정 암(Max) → 암진단비 argmin 생보사(min). ② threeCriticalStair: 손보 3사복합 3담보 합(Max) → 3담보 합 최저 단일 생보사(min).
  - bannerPct = round(cancerMonthDiff/totalMonthDiff×100)(분모≤0이면 null). remainderMonthDiff = totalMonthDiff−cancerMonthDiff. yearTotalDiff = years 유효 시 monthDiff×12×years, 아니면 null(graceful).
  - 게이트: lifeMatrix 없음/triple_best 없음/①·② 미형성 → null(섹션 미표시). **exact 원 유지(bannerPct만 표시용 정수)**.
- 기존 `computeLifeThreeCriticalDiff`+헬퍼(담보매칭 code우선·정확allowlist·유사암배제 등) 및 회귀 테스트 전부 유지. 구식 `computeLifeStaircase`+전용 타입 제거.

### 2. component (이리스) — `src/components/composite/LifeThreeCriticalDiff.tsx`
- 전면 재작성: 섹션타이틀+각주 → **배너**(headline %·인라인 게이지·서브텍스트 ①÷② 분모 명시·회사 상이 시 명기) → **① 암 SVG 계단** → **② 3대질병 SVG 계단** → **근거표**(비율바) → 하단 컴플라이언스 각주 4줄(승환 경고·단순합 정의·초기 감액·허혈성 유지유리).
- 공용 `LifeStair` SVG(2행 Max/min): 손보 `RpPresentation.SectionStaircase` 양식 차용(파란 뱃지 rect·italic bold 회사명·bold tabular-nums 금액·직선 M/L polygon 화살촉·흰 backplate rect). 차액 화살표는 **초록(#16a34a)/빨강(#dc2626) 부호병기(▼−/▲+)**. viewBox 고정+w-full(px폭 하드코딩 금지). years==null이면 우측 총액 커넥터 생략(graceful).
- 근거표: lifeMoreExpensive 담보(허혈성 등)는 손보셀 "· 유지 유리"(빨강 볼드) + ▲+ 표기.
- **레이아웃 겹침 버그 수정**: 초기 좌표계(viewW=480)에서 중앙 월차액 텍스트와 우측 20년총액 라벨이 가로로 겹침 → viewW 720·월차액 좌측정렬·커넥터 우측 이격(connX 560)·rowGap 48로 컬럼 분리하여 해소(스크린샷 재검증).

### 3. e2e (아르고스) — `tests/e2e/composite-design-vpath.spec.ts`
- 케이스 C를 새 구조(life-banner/life-stair-cancer/life-stair-three/life-evidence-*)로 갱신. 구식 testId(life-staircase-baseline/life-scenario-*/diff-cancer_only) 잔존 0. strict-mode 회피(getByTestId 스코프). 픽스처·route 무변경.

## 변경 파일 (5, 전부 allowed_resources 내)
- `src/lib/lifeThreeCritical.ts`, `src/lib/__tests__/lifeThreeCritical.test.ts`
- `src/components/composite/LifeThreeCriticalDiff.tsx`, `src/components/composite/__tests__/LifeThreeCriticalDiff.test.tsx`
- `tests/e2e/composite-design-vpath.spec.ts`
- forbidden(server/**·extension/**·.github/**·config/api.ts·integrations/**)·RpPresentation(손보) **무변경**.

## 테스트 결과
- `npx tsc --noEmit`: **0 에러**
- `npx vitest run`(전체): **73 files / 1088 tests passed, 0 fail** (기존 대비 회귀 0, 신규 뷰모델·컴포넌트 테스트 추가)
- lib 테스트: computeLifeThreeCriticalView 신규 7 describe + 기존 computeLifeThreeCriticalDiff 회귀 전부 유지(30 passed)

## L1 스모크테스트
- 서버 재시작: 해당없음(Playwright webServer가 vite dev 자동 기동, localhost:8080)
- API 응답 확인: 해당없음(webapp-only, mock route)
- **실브라우저 렌더(Playwright/Chromium)**: `npx playwright test -g "케이스 C"` → **1 passed (6.2s)**. 실제 DOM 렌더+상호작용 확인.
- 스크린샷: `tests/e2e/screenshots/vpath/c-life-staircase.png` — 팀장 **육안 독립 확인**:
  - ① 암: 최고 Max 테스트화재 30,000원 → 최저 min 행복생명 25,000원, "월 −5,000원 ▼"(초록)과 "20년 −1,200,000원"(우측 ㄱ커넥터) **겹침 없이 분리**.
  - ② 3대질병: "손보 3사 복합 합계" 57,000원 → "행복생명 (3담보)" 49,000원, "월 −8,000원 ▼"·"20년 −1,920,000원" 분리.
  - 배너 63%(=round(5000/8000×100)) + 게이지, 근거표 3행+합계(손보 57,000/생보 49,000/월▼−8,000), "절감" 미사용.
- L1 결과: **통과**(실브라우저 렌더+스크린샷 육안 검증).

## 발견 이슈 및 해결
- **SVG 겹침(중앙 월차액↔우측 20년총액)**: 좁은 viewW(480)로 컬럼 충돌. e2e는 텍스트 존재만 검사해 미검출 → 팀장 스크린샷 육안 검증에서 발견, 좌표계 확장(720)·좌측정렬·커넥터 이격으로 해소·재검증. (표면 통과 ≠ 의도대로 동작 원칙 적용.)

## 머지 판단
- **머지 필요**: Yes (단, merge_policy=none → **ANU가 독립 검증·머지·CF Pages 배포**)
- 브랜치: `task/task-2888-dev1` · 워크트리: `/home/jay/projects/InsuRo/.worktrees/task-2888-dev1`
- 머지 의견: tsc 0·vitest 1088/0·e2e 케이스 C green·스크린샷 육안 검증 완료·회귀 0·webapp-only·forbidden/손보/서버/확장 무변경. rollout(마이그레이션/확장/웹앱 CF Pages `wrangler pages deploy dist --project-name insuro --branch main`)은 회장 지시·ANU 소관.

## 모델 사용 기록
- 불칸(lib)·이리스(component)·아르고스(e2e): 전부 **sonnet**(로직/SVG/e2e — haiku 부적합). 팀장(헤르메스, opus)=설계/진단/검증/통합만, 직접 코딩 0.

## 세션 통계
- 총 도구 호출: 0회

