# [Lv.2] 담보명 코드 노출 버그 수정 — 캡처 담보명 병합 + 전 표 가드

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "src/components/composite/ConsultationHistoryView.tsx"
    - "src/components/composite/RpPresentation.tsx"
    - "src/lib/coverageCatalog.ts"
    - "src/lib/**"
    - "src/**/__tests__/**"
    - "tests/e2e/**"
  forbidden_paths:
    - "server/**"
    - "extension/**"
    - ".github/**"
    - "src/config/api.ts"
    - "src/integrations/**"
  commands: ["npx vitest","npx tsc","npx playwright","git"]
  merge_policy: "none"
  ttl_hours: 10
```
> ★ merge_policy=none. base=현 origin/main. webapp-only, 서버·확장 무변경.

## 배경 (회장 실사용 버그)
결과지에서 **담보명이 아니라 코드(a042·b002 등)가 보일 때가 있음**(특히 최상단 표). 원인:
- 담보명 해석이 `fetchCoverageNameMap`(`/api/insuro/composite-coverages`) **카탈로그 맵 단일 의존**. fetch 실패(미인증/네트워크/non-ok → `{}` 반환)나 특정 코드 누락 시 코드로 fallback.
- `SelectedCoveragesBlock`(ConsultationHistoryView:168)은 `resolveCoverageName(cov.coverage_cd, nameMap)`만 호출 — **명시적 담보명 미전달 + "미분류" 가드 없음** → raw 코드 그대로 노출.
- 저장된 `analysis_matrix.coverages[]`에는 캡처된 담보명(`name`)이 이미 존재하는데 이름 해석에 활용 안 함.

## 작업 (surgical)

### 1. 캡처 담보명으로 보조 맵 구성 → 병합
- `ConsultationHistoryView`에서 렌더 시 `record.analysis_matrix.coverages[]`의 **`{cd → name}`**(유효한 사람이름만, 코드패턴 `^[a-z]\d{3}$` 제외)로 보조 nameMap 구성.
- 이걸 fetch된 카탈로그 `coverageNameMap`과 **병합**해서 하위 전체(RpPresentation·SelectedCoveragesBlock·PerInsurer·LifeThreeCriticalDiff 등)에 전달. 우선순위: **명시적 name(캡처) > 카탈로그 맵 > 코드**. (즉 캡처 이름이 있으면 카탈로그 실패해도 표시됨.)
- 병합 헬퍼는 `src/lib/coverageCatalog.ts`에 추가(예: `mergeCoverageNameMaps(...)` 또는 매트릭스에서 map 추출 `coverageNameMapFromMatrix(matrix)`).

### 2. 모든 담보표에서 raw 코드 노출 0
- `SelectedCoveragesBlock`(168): resolveCoverageName 결과가 코드패턴/cd 동일이면 **"미분류"**(코드는 `title` 툴팁만) — RpPresentation의 `DisplayCovName` 가드와 동일 규칙 적용. 병합 map 사용.
- 코드가 화면 텍스트로 그대로 나오는 경로를 **전수 제거**(matrix·selected·per-insurer·생보 표 포함). 공용 가드 컴포넌트/헬퍼로 통일 권장(중복 로직 제거, surgical).
- 단 병합(1) 덕분에 대부분 **실제 담보명**이 나와야 하며, "미분류"는 정말 이름 없을 때만.

## 제약
- webapp-only. 서버/확장/카탈로그 엔드포인트 불변. 이름 해석·가드만 손봄. 손보 계단식·생보 계단식·수치·색 로직 불변.

## 검증
- `npx tsc` 0. `npx vitest run` 회귀 0. 신규:
  - 카탈로그 맵 비어있음({}) + 매트릭스에 name 있음 → **담보명 표시**(코드 아님).
  - 카탈로그·매트릭스 둘 다 이름 없음 → "미분류"(raw 코드 텍스트 노출 0, 코드는 title만).
  - 병합 우선순위(캡처 name > 카탈로그 > 미분류) 단위검증.
  - 모든 담보표(matrix/selected/per-insurer/생보)에서 코드패턴 텍스트 노출 0 검증.
- e2e: 상담 결과지에서 코드패턴(`a042`류) 화면 노출 없음 확인(가능 범위). clean worktree PASS.

## 완료 (★ 순서 B)
- 변경 = src/ (+tests) 만. 서버/확장 불변.
- **dev6 금지** — dev1. 커밋 → push → finish-task **foreground 1회** → .done 즉시 종료. **background wait 금지.** ANU 검증·머지·CF Pages 배포(source /home/jay/workspace/.env.keys → wrangler pages deploy dist --project-name insuro --branch main)는 ANU.

## goal_assertions (auto-generated)
- `npx tsc`
- `npx vitest run`
