# InsuRo 복합설계 — 매트릭스 캡처 + history + CRM 자동 연동

## 레벨

Phase 0은 코드 수정 없음 (조사/설계 + 매핑 문서). Phase 1+는 회장 승인 후 별도 dispatch로 코드 작성 진행. 본 dispatch는 Phase 0 한정 — 리서치만.

## 작업 레벨: Lv.4 (다단계 Phase, brainstorming 완료)

## 프로젝트
- InsuRo 프론트: `/home/jay/projects/InsuRo`
- InsuRo Helper 확장: `/home/jay/projects/InsuRo/extension`
- InsuRo 서버: `/home/jay/projects/InsuRo/server`

## ★ 시스템 3문서 (필수 참조 — 한 글자도 빠짐없이 검토)

- **계획서**: `/home/jay/workspace/memory/plans/insuro-composite-design/plan.md`
- **맥락노트**: `/home/jay/workspace/memory/plans/insuro-composite-design/context-notes.md`
- **체크리스트**: `/home/jay/workspace/memory/plans/insuro-composite-design/checklist.md`

→ **반드시 위 3문서를 모두 읽고 모든 결정사항을 정확히 따를 것**. 본 task 파일은 3문서의 위임용 요약이며, 원본은 3문서가 진실의 원천.

## 배경 (요약)

2026-05-02 회장(제이) brainstorming 종합 결정:
- 옛 Phase 1 직접 크롤링 폐기, Phase 2 Chrome Extension 피벗 완료 (task-2336)
- Phase A UX 정합화(task-2349) + Phase B 버전 정책(task-2351) 완료
- **본 task = 신 Phase 0~4**: 매트릭스 전체 캡처 + history 누적 + CRM 자동 연동

## 핵심 결정사항 (3문서 발췌, 모두 반영 필수)

### 워크플로우
- ohmymanager 사용자 → 1차 입력 + 플랜/담보/한도 입력 → 보험사별 보험료 자동 로딩
- → "📊 InsuRo로 분석" 플로팅 버튼 (Z-①, 우측 하단 fixed) 클릭
- → 매트릭스 + 1차 입력 + 만기 + 플랜 + 담보 모두 DOM 스크래핑 → InsuRo POST
- → InsuRo 서버: history 저장 + CRM 자동 매칭/등록
- → InsuRo /composite-design 자동 활성화 → 1사/2사/3사 분석 + history 비교

### 보안 / 안전장치 (절대 누락 금지)
- **#1 PII 암호화 필수** — 이름 + 생년월일 8자리 평문 저장 금지. Supabase Vault 또는 pgcrypto.
- **#3 동명이인 처리** — confirm 다이얼로그 "이 고객 맞나요?" + 사후 수동 분리
- **#9 hash 디바운스** — 시간 기반 X, matrix capture_hash 동일 체크만
- **#10 InsuRo 미로그인 시 플로팅 버튼 미표시** — 인증 만료 우회 (회장 결정)
- **#15 CRM UPSERT 패턴** — 동시성 중복 방지 (이름+생년월일+성별 컴포지트 유니크)

### 폐기/제외 (작업하지 말 것)
- Y1 자동 push (실시간 변동) — 폐기
- silent 백그라운드 fetch — ohmymanager 약관 위반 위험
- 시간 기반 디바운스 — hash로 충분
- 가입금액 변경 시각 신호 — pass

### 향후 검토 (본 task 범위 외)
- 금소법 동의 화면 — Phase 5+
- GoogleDrive 백업 — Phase 5+
- ohmymanager DOM 셀렉터 변경 자동 감지 — 사용자 신고로 충분

## Phase 진행 (반드시 순서대로)

### Phase 0 — 사전 조사 (★ 회장 승인 게이트 필수, Phase 1 진행 전)

**1. 기존 InsuRo CRM 스키마 조사**
- `/customer-management` 페이지 코드 확인
- customers 테이블 스키마 추출 (컬럼/제약/RLS)
- 기존 고객 등록 API 엔드포인트 식별
- CRM history/메모/연락처 관련 테이블 매핑

**2. PII 암호화 설계**
- Supabase Vault 사용 가능 여부 확인
- pgcrypto 컬럼 암호화 옵션 평가
- 암호화 키 관리 방안 (.env.keys 또는 KMS)
- 매칭 키 hash 함수 + salt 정책: `customer_key_hash = SHA-256(name + dob + gender + salt)`
- 표시용 마스킹 정책 ("홍**" / "850101")

**3. 매핑 문서 작성 → 회장 승인 게이트**
- ohmymanager 캡처 → 기존 CRM 컬럼 매핑 테이블
- 신규 필드 vs 기존 필드 구분
- **회장 승인받기 전까지 Phase 1 시작 금지**
- 보고 위치: `/home/jay/workspace/memory/reports/task-2354-phase0-cr_mapping.md`

### Phase 1 — 캡처 + history 기본 (필수)

#### 1-1. Extension 변경
- `extension/content.js`: `mmlfcp.ohmymanager.com` 도메인 감지
- 매트릭스 DOM 스크래핑 함수:
  - 1차 입력 (이름/생년월일/성별/생손보유형/상품유형/만기)
  - **만기 분리 파싱**: "20년/100세" → `payment_term: "20년"` + `maturity_age: "100세"`
  - 플랜 추출 (드롭다운 현재 선택값)
  - 보험사 컬럼 + 보험사별 합계
  - 담보 행 + 가입금액 + 보험사별 단가
- 매트릭스 hash 함수: `capture_hash = SHA-256(JSON.stringify(매트릭스))`
- API 응답 가로채기 백업 (DOM 셀렉터 깨짐 대비)
- **플로팅 버튼 (Z-①)**:
  - 우측 하단 `position: fixed`, z-index 충돌 회피
  - 인디고 톤 (#4F46E5 또는 InsuRo 브랜드 컬러)
  - "📊 InsuRo로 분석" 텍스트
  - **InsuRo JWT 미로그인 시 미표시** (extension에서 storage.local 또는 cookie로 InsuRo 세션 확인)
  - 클릭 → 스크래핑 → background.js → InsuRo POST
- `extension/manifest.json`: `mmlfcp.ohmymanager.com` host_permissions 추가

#### 1-2. 백엔드
- 신규 마이그레이션: `ohmy_capture_history` 테이블
  ```sql
  CREATE TABLE ohmy_capture_history (
    id BIGSERIAL PRIMARY KEY,
    user_id UUID NOT NULL,
    customer_id UUID,
    customer_key_hash TEXT NOT NULL,
    encrypted_name TEXT NOT NULL,
    encrypted_dob TEXT NOT NULL,
    gender TEXT NOT NULL CHECK (gender IN ('M','F')),
    insurance_type TEXT,
    product_type TEXT,
    payment_term TEXT,
    maturity_age TEXT,
    plan_name TEXT,
    matrix JSONB NOT NULL,
    capture_hash TEXT NOT NULL,
    source TEXT DEFAULT 'trigger',
    captured_at TIMESTAMPTZ DEFAULT now()
  );
  CREATE INDEX idx_ohmy_capture_user ON ohmy_capture_history(user_id, captured_at DESC);
  CREATE INDEX idx_ohmy_capture_customer ON ohmy_capture_history(customer_id, captured_at DESC);
  CREATE INDEX idx_ohmy_capture_keyhash ON ohmy_capture_history(customer_key_hash);
  CREATE UNIQUE INDEX idx_ohmy_capture_dedupe ON ohmy_capture_history(user_id, capture_hash);
  ```
- POST `/api/insuro/ohmy-capture`:
  - InsuRo JWT 검증 + 인카 organization 검증
  - PII 암호화 + key_hash 계산
  - capture_hash 중복 체크 → 동일 시 무시 (저장 안 함)
  - history INSERT (Phase 1에서는 customer_id NULL)
- GET `/api/insuro/ohmy-capture-history`:
  - 사용자별 RLS
  - 최근순 정렬 + 페이지네이션
  - 매트릭스 JSON + 메타 반환

#### 1-3. 프론트
- `src/pages/CompositeDesign.tsx` 단계 C UI 재구성:
  - history 목록 카드 (고객 이름 마스킹 + 만기 + 캡처 시각)
  - 항목 클릭 → 1사/2사/3사 분석 결과 (composite_calculator 입력)
  - 캡처 매트릭스 → 기존 task-2346 정규화 로직 재활용

#### 1-4. 검증
- ohmymanager 화면 로드 + InsuRo 로그인 → 플로팅 버튼 표시
- InsuRo 미로그인 → 플로팅 버튼 미표시
- 클릭 → 매트릭스 캡처 + InsuRo POST 성공 + history INSERT
- 동일 매트릭스 재클릭 → hash 동일 → 저장 안 함 (DB row count 변화 없음)
- InsuRo /composite-design 단계 C → history 목록 + 항목 클릭 → 1사/2사/3사 분석

### Phase 2 — 비교 UI (만기별/조건별)

- customer_key_hash 기반 동일 고객 history 그룹화
- 같은 고객 + 다른 payment_term 2건+ 자동 감지 → **만기별 비교 카드 자동 활성화**
- 비교 카드: 20년/100세 vs 30년/100세 매트릭스 나란히
- **20년납 vs 30년납 총 납입액 시뮬레이션** (월 보험료 × 12 × payment_term) — 회장 핵심 가치
- 보험사별 곡선 비교 (20년에선 메리츠 싸지만 30년에선 롯데 더 싼 케이스 등)
- ohmymanager "만기별 보험료 비교" 탭 캡처: source="tab_compare"로 별도 저장 + 별도 카테고리 표시

### Phase 3 — CRM 자동 연동 (★ 회장 승인 게이트, Phase 4 진행 전)

#### 3-1. 매칭 로직
- customer_key_hash로 기존 customers 조회
- 일치 시 → **confirm 다이얼로그**: "기존 고객 홍**(850101) 맞나요? / 신규 등록"
- 미일치 시 → 신규 고객 자동 등록 (UPSERT 패턴)
- 트랜잭션 처리 + 유니크 제약 (이름+생년월일+성별 컴포지트 키)

#### 3-2. CRM 통합
- customers 테이블 INSERT/UPDATE
- ohmy_capture_history.customer_id 채움
- CRM 페이지 변경 (`/customer-management` 또는 고객 상세):
  - "최근 ohmymanager 분석 history" 섹션 추가
  - history 항목 클릭 → InsuRo /composite-design 자동 이동

#### 3-3. 사후 수정 (동명이인 안전장치)
- CRM에서 잘못 매칭된 history를 다른 고객으로 이동 UI
- history customer_id 재할당 API + 권한 체크

### Phase 4 — 운영 안정화 (선택, 후속 분리 가능)

- DOM 셀렉터 견고성 (API 응답 가로채기 백업 활성화)
- 모바일 대응 (ohmymanager 모바일 화면 캡처 검증, 플로팅 버튼 모바일 위치/크기)
- 시크릿 모드 가이드 (가이드 페이지 안내 추가)
- history 사용자 수동 삭제 UI

## affected_files (예상)

### 신규
- `server/migrations/0XX_ohmy_capture_history.sql` (Phase 1)
- `extension/content.js` 매트릭스 스크래핑 + 플로팅 버튼 (Phase 1)
- `src/components/composite/HistoryList.tsx` (Phase 1)
- `src/components/composite/MaturityCompare.tsx` (Phase 2)
- `src/components/composite/CustomerMatchDialog.tsx` (Phase 3)

### 수정
- `extension/content.js` (도메인 분기 강화, DOM 스크래핑, 플로팅 버튼)
- `extension/background.js` (ohmy-capture push)
- `extension/manifest.json` (host_permissions, version bump)
- `server/main.py` (`/api/insuro/ohmy-capture` 강화 + GET history + Phase 3 CRM 매칭)
- `src/pages/CompositeDesign.tsx` (단계 C history UI + 만기 비교)
- `src/lib/extensionBridge.ts` (필요 시 capture trigger 헬퍼)
- (Phase 3) `src/pages/CustomerManagement.tsx` 또는 고객 상세 페이지

## 검증 시나리오 (회장 승인 기준 8개)

1. **첫 캡처 (신규 고객)**: ohmymanager → 플로팅 버튼 → history1 + (Phase 3) CRM 신규 등록
2. **두 번째 캡처 (동일 고객 다른 만기)**: 30년/100세로 토글 후 클릭 → history2 + (Phase 3) confirm
3. **만기별 비교**: history 2건+ 자동 비교 카드 → 20년 vs 30년 총액 차이
4. **ohmymanager "만기별 비교" 탭**: 별도 source="tab_compare" history
5. **동명이인**: confirm에서 "신규 등록" → 별도 고객 카드
6. **중복 클릭**: 같은 매트릭스 hash → 저장 안 함
7. **InsuRo 미로그인**: ohmymanager 플로팅 버튼 미표시
8. **F12 Console 0건 + npm run build PASS**

## 보고

- Phase 0 보고서 (회장 승인 게이트): `memory/reports/task-2354-phase0-cr_mapping.md`
- 통합 보고서: `memory/reports/task-2354.md`
- 각 Phase 별 변경 + 검증 + 스크린샷
- L1+L2 검증 + Playwright 시나리오

## 후속 운영
- PR 머지 → Cloudflare Pages 배포
- PWA SW 캐시 우회 새로고침 (Ctrl+Shift+R)
- 확장 zip 재배포 (회장 직접) + 사용자 사이드로드 재설치 안내

## 운영 메모

### 진행 순서
- **Phase 0 → 회장 승인 → Phase 1** (절대 건너뛰지 말 것)
- **Phase 1+2 통합 PR 가능** (한 번에 머지)
- **Phase 3 → 회장 승인 → Phase 4** (동명이인 confirm UX 검증)
- **Phase 4는 선택** — 후속 task로 분리 가능

### 충돌 회피
- task-2349 / task-2351 머지 완료 → 충돌 없음
- 같은 파일(`CompositeDesign.tsx`, `extensionBridge.ts`) 만지지만 별도 영역(단계 C UI 추가, capture trigger 추가)이라 안전

### 위임 결정 변경 신호
- 작업 도중 회장 결정 변경 시 → `.cancelled` 마커 또는 task 파일 STOP 마커 즉시 인식 후 중단
- task-2348(이참나, cancellation enforcement) 머지 후 표준화

## 참조
- task-2333 (옛 Phase 1, 폐기)
- task-2336 (Chrome Extension 피벗) 보고서: `memory/reports/task-2336.md`
- task-2346 (정규화 로직) 보고서: `memory/reports/task-2346.md`
- task-2349 (UX A안) 보고서: `memory/reports/task-2349.md`
- task-2351 (버전 정책 (c) 분기) 보고서: `memory/reports/task-2351.md`
- 시스템 3문서: `memory/plans/insuro-composite-design/`