# task-2998 — InsuRo 메뉴 일원화 · 용어 완결 (task-2997 후속)

**레벨**: Lv.2 (UI 정보구조) · **팀**: dev5-team (마르둑) · **회장 승인 완료** (2026-08-22)

## ★ 왜 이 태스크가 생겼나 — 먼저 읽어라
task-2997(PR #244, main=`36ac664`)은 머지됐으나 **회장님 화면에는 4건 중 2건만 반영된다.**
ANU 가 재측정해 원인을 확정했다. **명세를 쓴 ANU 의 전제가 틀렸다.**

```
src/config/routes.ts 의 section 필드
  → 유일한 소비자 AppSidebar 의 import = 0건.  죽은 메타데이터다.
src/components/navigation/navigationConfig.ts
  → 실제 메뉴 소스. 소비자 6개 파일(DashboardLayout·MobileCategoryHub·
     ContextSubMenu·MobileBottomNav·TopNavBar·index).
```
즉 2997 이 `section` 을 고친 것은 **화면에 아무 영향이 없다.** 봇이 실브라우저로 확인해
ANU 에 보고했고 그 보고가 옳았다. 이 태스크는 **진짜 소스를 고친다.**

**이 태스크가 끝나야 2997 과 함께 배포한다.** 지금 2997 만 배포하면 회장님 눈에
"신규 설계"와 "신규 견적"이 한 화면에 섞인 채 약관 업로드는 여전히 설계사 메뉴에 남는다.

---

## 고칠 것 4건

### ① `신규설계 비교` 가 메뉴에 아예 없다 (접근 불가)
```
실측: navigationConfig.ts 전체에서 new-design-comparison = 0건
      routes.ts:331 에 라우트는 존재 → URL 직접 입력으로만 도달 가능
```
**조치**: `domainTabs` 의 `crm` 탭에 추가한다. 위치는 `고객 증권분석`(`/crm/policy-analysis`) **바로 다음**.
특정 고객의 기존계약 분석 → 신규설계 비교로 이어지는 순서이기 때문이다.
```
{ title: "신규설계 비교", url: "/new-design-comparison", icon: <적절한 lucide 아이콘> },
```
★ **URL 은 바꾸지 마라.** `/crm/` 접두사로 옮기고 싶어도 하지 마라 —
라우트·북마크·기존 링크가 깨진다. 메뉴 등록만 한다.

### ② `약관 업로드` 가 설계사 도구 메뉴에 있다
```
실측: navigationConfig.ts:57  analytics-tools 탭
      { title: "약관 업로드", url: "/tools/policy-terms-upload", icon: FileCheck2 }
근거: POST /api/insuro/policy-terms/upload = 상품 지식 DB 적재(보험사·상품명·상품코드·약관버전)
      → 시스템에 상품을 등록하는 관리 작업이다.
```
**조치**: `analytics-tools` 에서 **제거**하고 `adminMenuItems` 에 **추가**한다.
`adminMenuItems` 는 `ContextSubMenu.tsx:34` 가 `isAdmin` 을 확인한 뒤에만 렌더한다
(task-2996 결과, 이미 배포됨). 별도 권한 코드를 새로 짜지 마라.

★ 주의: `고객 증권분석` 화면의 약관 PDF 첨부(`POST /api/insuro/analyze-policy`)는 **별개 기능**이다.
그건 특정 고객 분석용이므로 **건드리지 말 것.**

★ 라우트 자체의 `adminOnly` 를 새로 켜는 것은 **이 태스크 범위 밖**이다.
메뉴 노출만 정리한다. 라우트 가드 변경이 필요하다고 판단되면 **고치지 말고 ANU 에 보고**하라.
(2997 에서 봇이 같은 판단으로 보류한 것이 옳았다)

### ③ 용어 혼재 — 한 화면에 "신규 설계"와 "신규 견적"이 같이 있다
```
실측(origin/main = 36ac664):
  src/pages/NewDesignComparison.tsx           "신규 설계" 9곳   ← 2997 이 고침
  src/components/policy/NewDesignComparisonTable.tsx:264  "신규 견적"  ← 범위 밖이라 남음
  src/components/policy/NewDesignComparisonTable.tsx:303  "신규 견적"  ← 범위 밖이라 남음
```
같은 화면을 구성하는 페이지와 표 컴포넌트가 서로 다른 말을 쓴다.
**조치**: Table 컴포넌트 2곳을 "신규 설계"로 통일한다.

★ 264 는 `role="alert"` 경고 배너 문구다. 경고문 자체가 용어 불일치를 담고 있다.
문구의 **의미는 바꾸지 말고 용어만** 교체하라.
★ 실제로 "견적"을 뜻하는 곳이 있으면 두고 **보고**하라. 기계적 치환 금지.

### ④ `routes.ts` 의 죽은 `section` 필드
소비자가 없는데 값만 있어서, 다음 사람이 또 여기를 고치고 "반영 안 된다"고 헤맨다.
**조치**: 필드를 **삭제하지 말고**, 무엇이 진짜 소스인지 한 줄 주석을 남긴다.
```
// ★ 이 필드는 화면 메뉴를 좌우하지 않는다. 실제 메뉴 = components/navigation/navigationConfig.ts
```
삭제하지 않는 이유: 타입·테스트가 참조할 수 있고, 삭제는 이 태스크가 감당할 범위를 넘는다.
**타입 정의나 다른 필드는 건드리지 마라.**

---

## 검증 (전부 실측으로 증명하라)
1. **변경 전 원문 기록** — `navigationConfig.ts` 의 해당 항목, Table 264/303 원문.
2. **메뉴 노출 실브라우저 확인**
   - `신규설계 비교` 가 **고객관리 탭**에 보이고 클릭 시 페이지가 열린다.
   - `약관 업로드` 가 **분석&도구에서 사라졌고**, 관리자 메뉴에 나타난다.
   - **비관리자 계정으로도 확인** — 약관 업로드가 안 보여야 한다.
   ★ 사이드바는 스크롤이 필요할 수 있다. 목록 전체를 확인하라
     (2026-08-21 ANU 가 스크롤을 놓쳐 "메뉴에 없다"고 오판한 사례가 있다).
   ★ 스크린샷은 **픽스처가 아닌 실제 렌더**임을 명시하라.
3. **용어 혼재 해소 확인** — 신규설계 비교 화면 전체에서 "신규 견적" 0건.
   경고 배너를 실제로 띄운 상태의 스크린샷을 포함하라(배너가 조건부 렌더라면 그 조건을 만들어라).
4. **봉인 증명 — 회귀 테스트를 변이시켜라.**
   새로 쓴 테스트가 값을 원복했을 때 **실제로 FAIL 하는지** 확인하고 복원하라.
   "N passed" 재현만으로는 테스트에 이빨이 있는지 알 수 없다(2026-08-22 확립).
5. `npm run build` EXIT=0 · `npx vitest run` 회귀 유지(**base 재측정 기준선**. 명세 수치 아님).
6. 모바일 경로(`MobileBottomNav` · `MobileCategoryHub`)가 같은 설정을 읽으므로
   **모바일 뷰포트에서도** 메뉴가 깨지지 않는지 확인하라.

## 범위 · 금지
**수정 허용**: `src/components/navigation/navigationConfig.ts` ·
`src/components/policy/NewDesignComparisonTable.tsx` · `src/config/routes.ts`(주석 1줄만) · 관련 테스트

**금지**:
- **URL·라우트 경로 변경** (`/new-design-comparison` 유지)
- **라우트 `adminOnly` 값 변경** — 필요하면 보고하고 멈춰라
- `src/App.tsx` · `ContextSubMenu.tsx` — task-2996 결과물, 배포 완료됨
- `src/pages/PolicyAnalysis.tsx` — PR #215 가 이 파일에서 충돌 중
- `src/pages/NewDesignComparison.tsx` — 2997 이 이미 고쳤다. 다시 손대지 마라
- `server/**` · `supabase/**`
- 화면 구조·입력 방식 변경 (JSON → PDF 업로드 등은 별도 태스크)

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "src/components/navigation/navigationConfig.ts"
    - "src/components/policy/NewDesignComparisonTable.tsx"
    - "src/config/routes.ts"
    - "src/components/__tests__/**"
    - "src/pages/__tests__/**"
    - "src/config/__tests__/**"
    - "tests/**"
    - "e2e/**"
    - "memory/reports/task-2998.md"
  forbidden_paths:
    - "src/App.tsx"
    - "src/components/navigation/ContextSubMenu.tsx"
    - "src/pages/NewDesignComparison.tsx"
    - "src/pages/PolicyAnalysis.tsx"
    - "server/**"
    - "supabase/**"
    - "ops/**"
    - "scripts/**"
    - ".github/**"
  commands:
    - "npm run build"
    - "npx vitest run"
    - "npx playwright test"
  merge_policy: "tiered"
  ttl_hours: 48
```

## 운영 계약
- `origin/main`(=`36ac664`) 기준 `git pull --ff-only` 후 시작
- ★ `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` 금지.
- **명세와 실측이 다르면 임의 판단하지 말고 ANU 에 보고하라.**
  이 태스크 자체가 ANU 명세 오류에서 나왔다. 봇이 실측으로 반박한 것이 옳았다.

## 완료 조건
4건 반영 · 실브라우저 스크린샷(관리자/비관리자/모바일) · "신규 견적" 0건 ·
변이 테스트로 봉인 실증 · 빌드 0 · 회귀 유지 · URL 무변경

## 보고
**★★★ PR 생성까지가 범위다. 머지는 ANU 가 한다. 절대 직접 머지하지 마라.**
2026-08-22 에만 봇 무단 머지가 **4건**(t2986·t2993·t2995·t2997) 발생했다.
PR 을 열고 멈춰라. 머지 여부는 ANU 가 배포 시점과 함께 판단한다.
`memory/reports/task-2998.md` 작성 후 표준 완료 콜백 등록. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.

## goal_assertions (auto-generated)
- `npm run build`
- `npx vitest run`
