010 — Pack 1 회수 유형 UI 분기 설계
Tier: B (R1 + R3) · 상태: R1 완료, R2 진행 승인 대기
안건
Pack 1 회수 유형 6종 엔진·서면·어댑터 Core Layer 가 완성된 상태에서, Settlement 탭을 유지·분리·통합 중 어떻게 하고, 유형별 입력 폼·문서 생성 버튼 UX 를 어떻게 할 것인가.
결정 필요 5개
- 탭 구조: 단일 탭 + 유형 drop-down vs. 유형별 독립 탭 vs. 통합 "회수 탭"
- 유형 변경 정책: 경고·새 케이스 유도·자동 초기화
- 문서 생성 UX: modal / drawer / 별도 서브페이지
- 기존
DebtSettlementTab마이그레이션: 유지·교체·점진 - 임대차보증금 공제 입력 UI: 공통 폼 vs. 별도 서브모달
배경 참고
apps/docs/content/product/pack-1/core-layer.md— 3-tier 아키텍처 (엔진 6 · 서면 5 · 어댑터 5)- PR #372 —
recovery-snapshot-actions.tsServer Action 완성 (Firestore 쓰기 경로 준비됨) apps/web/app/(workspace)/cases/[caseId]/_tabs/DebtSettlementTab.tsx— 기존 debt 전용 704줄apps/web/app/(workspace)/cases/[caseId]/_lib/recovery-dispatch.ts— 6 유형 통합 dispatch 완료
Round 1 — 독립 발산 (5 subagent 병렬)
P1 변호사 (10년차 · 민사 회수 실무)
원초적 입장: 통합 "회수 탭" 하나 + 유형 selector 상단 고정. 유형 변경은 경고 + 데이터 보존 (초기화 금지). 문서 생성은 우측 drawer — 계산표·청구취지 동시 보며 확정. 기존 DebtSettlementTab 은 새 통합 컴포넌트로 교체. 임대차 공제는 같은 폼 내 동적 배열.
근거:
- 유형 오분류는 법적 치명상이 아닌 "재계산" 문제 — 소장 제출 전 변호사 최종 검토. 자동 초기화는 도구 불신 유발.
- 복합 청구 (공사대금 + 지체상금) 는 "주 유형 + 부수 청구" 구조. 한 사건 = 한 유형 원칙, 독립 탭 6개는 이 정신에 역행.
- "청구취지 자동 생성" 이 서면 작성 30~60분 단축 — Pack 1 최대 가치 제안점. Drawer 로 계산표·청구취지 실시간 대조가 핵심.
질문: 소멸시효 경고 UI (유형별 시효 다름) · 유형 변경 시 스냅샷 archive/삭제 정책.
P2 사무장 (10년차 · 파일 관리·문서 작성)
원초적 입장: 단일 "회수" 탭 + 상단 유형 선택 1회 + 스마트 폼 (공통 → 특화 순). 유형 변경은 1회 확인 + 자동 스냅샷. 문서 생성은 drawer + "전부 생성" 단일 버튼 + 개별 복사. 임대차 공제는 본 폼 안 아코디언 (별도 모달 반대).
근거:
- 탭 수 최소화 = 오입력 최소화. 6 유형 독립 탭은 사무원이 "대여금 탭" 에 공사대금 데이터 넣는 실수 유발. 신입 교육 "첫째 칸 고르고 아래로" 한 줄로 끝내야 함.
- 유형 변경 시 "기존 입력 폐기 경고 + 자동 스냅샷 보존" — 자동 초기화는 재앙, 새 케이스 유도는 사건번호 2개 혼란. 올바른 정책은 확인 다이얼로그 +
recoverySnapshots에 "유형 변경 전 보관본" 라벨로 자동 동결. - 문서 5종은 drawer + "전부 생성" 단일 버튼. modal 은 한글 문서 참조 불가. drawer 는 좌측 계산표 같이 보며 복사 가능.
질문: 공제 항목 증빙 파일 첨부 슬롯 · "유형 미정" (상담 전) 상태 허용.
P3 PM (제품 전략·Anti-Goal 수호)
원초적 입장: 통합 "회수 탭" 단일화 + 유형 드롭다운 + 우측 드로어. 유형 변경은 새 케이스 유도 — 경고 + 복제 CTA. 기존 DebtSettlementTab 은 "회수" 탭 내부 default view 로 편입 (즉시 교체 아님). 임대차 공제는 조건부 섹션.
근거:
- Pack 2~5 재사용성 — 유형별 독립 탭은 Pack 2 이혼 도달 시 탭 9개. "회수" 도메인 액션 단일 탭 + 내부 유형 스왑 패턴이 Pack 2 확장 비용 최소화. Chair 의 "베이스+유형 팩" 원칙을 UI 레이어에서 처음 증명.
- 가시적 제품 진전 — 사무원 챔피언 데모에서 드롭다운으로 6종 커버리지 시각화가 영업 핵심. Drawer 는 사건 컨텍스트 유지 + 폼·미리보기 한 축 정렬 → 사건 완주율 (L3 지표) 기여.
- 유형 변경 = 새 케이스 유도는 Anti-Goal 3 방어선 + L3 지표 정합성. 사건번호 = 불변 단위. 자동 마이그레이션은 의뢰인용 챗봇 톤 유입.
질문: UI 리팩터가 Week 4 Go/No-Go 일정 경쟁? · 회수 성공률 상태머신 (초안→발송→대응→완결) 유형 공통 설계?
P4 디자이너 (UX·정보 설계·shadcn/ui)
원초적 입장: 기존 DebtSettlementTab 을 "회수" 단일 탭으로 rename·교체 + 최상단 Segmented Control. 유형 변경은 AlertDialog 경고 + namespace 격리로 상태 자유 전환. 문서 생성은 기존 InlineDocGenerate modal 3-step 재사용 ("5종 묶음 프리셋" + "개별 선택"). 임대차 공제는 섹션 접힘.
근거:
- 탭 밴드 포화 방어 —
CaseDetailClient.VALID_TABS이미 8개. 유형별 독립 탭 추가 시 14" / 모바일 wrap. 단일 "회수" 탭 + 내부 ToggleGroup 이 정보 위계상 자연스러움. - 유형 변경 자유 + 경고 — 사건 생성 1회 락은 오분류 복구 비용 큼. 기존 fields 는 namespace (
inputs.debt.*,inputs.lease.*) 로 격리해 상태 복원 0. - 문서 생성은 기존
InlineDocGenerate모달 계약 확장 —useDocGeneration훅·3-step·시맨틱 토큰 확립. Drawer 도입 시 패턴 이중화. Step 1 docType 선택에 "5종 묶음 프리셋" + "개별 5 체크박스" 추가.
ASCII 와이어:
┌─ [회수] 탭 ────────────────────────────────┐
│ ◉ 대여금 ○ 공사대금 ○ 임대차보증금 ... │ ToggleGroup
├────────────────────────────────────────────┤
│ 기본 정보 (공통) │
│ 원금 · 이자율 · 기산일 │
│ ─ 유형 고유 섹션 (접힘/펼침) ── │
│ 임대차: 공제 항목 [+추가] │
├────────────────────────────────────────────┤
│ 계산 결과 [요약|표|청구취지] │
├────────────────────────────────────────────┤
│ [묶음 5서면 생성] [개별 선택…] │ → InlineDocGenerate
└────────────────────────────────────────────┘
질문: 기존 사건 recoveryType backfill 정책 (debt 일괄 vs. null + 진입 시 선택 모달)? · 모바일/좁은 뷰포트 대응 방침?
P5 풀스택 개발자
원초적 입장: 기존 DebtSettlementTab 704줄 건드리지 말고, 신규 RecoveryTab 병존 생성 + caseData.recoveryType 분기 라우팅. type 별 <ConstructionForm /> 등 독립 컴포넌트 dynamic import. features.infraHardening.recoveryTypeUi 플래그로 점진 배포. 유형 변경 금지 (Zod discriminator·engineVersion 호환성). 문서 생성 Drawer (5 탭 한 화면).
근거:
- 기존 파일 재사용 > 신규 작성 —
DebtSettlementTab은settlementSnapshotsPath·AddRecoveryModal·SettlementAnnexPrint·debt 전용buildClaimText와 결합. 6-way switch 주입 시 1200줄 이상.recoverySnapshots경로 자체가 다르므로 onSnapshot 리스너 공용 불가 — 병존이 자연. z.discriminatedUnion+ RHF resolver 실전 함정 —useForm<z.infer<union>>()공통 필드 타입never로 좁아짐. 해법: type 별<ConstructionForm />가 자체useForm<ConstructionSettlementInputPayload>(), 상위는recoveryType만 state.- PR 분할 5개 (각 350-400줄): ① 킬 스위치 +
RecoveryTab셸 + seed ② 공통<RecoveryTypeSelector>+<ResultSummary>③ construction·agreement·subrogation 3종 form ④ lease-deposit (useFieldArray) ⑤ assigned +DocumentBundleDrawer.
질문: recoveryType 저장 방식 (caseData 필수 필드 vs. 스냅샷 시점만)? · 유형 변경 허용 시 스냅샷·recoveries 데이터 호환성 (변경 금지 선택 시 migration 불필요)?
식별된 충돌 지점 (R2 대상)
합의 확인
- ✅ 단일 "회수" 탭 — 5인 만장일치
- ✅ 공제 UI 인라인 폼 (서브모달 반대) — 5인 만장일치
충돌 1 — 유형 변경 정책 (가장 첨예)
- 변경 허용 그룹 (P1·P2·P4): 오분류 흔함. 경고 + 데이터 보존 / namespace 격리.
- 변경 금지 그룹 (P3·P5): 새 사건 유도. Anti-Goal 정합 · 데이터 오염 / Zod·engineVersion 호환성.
- 대립 축: "변호사 실무 유연성" vs. "데이터 모델 엄격성·L3 지표 정합성".
충돌 2 — 마이그레이션 전략 (3 갈래)
- P1·P4 — 즉시 rename·교체
- P3 — 기존
DebtSettlementTab유지, "회수" 내부 default view - P5 — 완전 병존 (기존 파일 불변, flag 점진)
충돌 3 — 문서 생성 UX (4 vs. 1)
- 다수 (P1·P2·P3·P5) — 우측 Drawer
- P4 —
InlineDocGeneratemodal 재사용 (패턴 이중화 방지)
세부 차이
- 선택 UI: Dropdown (P1·P2·P3) vs. Segmented Control (P4) vs. 내부 라우터 (P5)
Round 2 — 상호 반박 (Clash)
5인 크로스 토크로 3 충돌 + 세부 차이 모두 해소.
충돌 1 — 유형 변경 정책 → "법원 사건번호 부여 전/후" 분기 합의
- P1 변호사: "사건번호 = 불변" 원칙은 법원 사건번호 에만 적용. 사무소 내부 번호는 유연. 한 달 2-3건 "대여금→구상금 재분류" 실제 발생. 법원 사건번호 부여 전 변경 허용 필수.
- P2 사무장: 의뢰인 문의 추적은 사무소 내부 번호로 하므로 새 사건 복제는 꼬임. "유형 미정" 상태 허용 제안 (→ P3 가 Anti-Goal 3 우려로 반박, "접수 = 분류 후" 원칙 유지).
- P3 PM 중대 양보: "변경 금지" 철회. 타협안 제시:
- 소 제기 전 (법원 사건번호 없음) → 유형 변경 허용 + 자동 스냅샷 archive
- 소 제기 후 (법원 사건번호 있음) → 변경 금지, "새 사건 복제" CTA
- P4 디자이너: namespace 격리 (
inputs.debt.*등) + "법원 사건번호 있음" 배지로 자동 disable. - P5 개발자 중대 양보: "변경 금지" 조건부 철회. P4 namespace + type 별 독립
useForm로 Zod discriminator 함정 우회 가능. 유형 변경 시 Server Action 레이어에서 prior snapshot 자동 archive.
충돌 2 — 마이그레이션 전략 → P5 병존 방식으로 5인 합의
- P4 양보: rename 은 탭 라벨 + URL slug 수준에만. 컴포넌트는 신규
RecoveryTab. - P5 유지:
RecoveryTab내부에서recoveryType === "debt"→<DebtSettlementTab />래핑, 나머지 5 유형 →<NonDebtRecoveryRouter />. 기존 704줄 파일 불변. - P3 합의: Phase 0 Week 4 일정 보호 + 리팩터 비용 최소.
충돌 3 — 문서 생성 UX → modal + drawer 병존 합의
- P4 양보:
InlineDocGeneratemodal 은 개별 서면 생성 유지 (back-compat). 5 서면 묶음은 신규DocumentBundleDrawer. - 다수 합의: 양 패턴 병존. 개별 = modal, 번들 = drawer.
세부 차이 — 선택 UI → Dropdown 기본 + Segmented 확장
- 기본
<Select>, CSS container query 로 화면 폭 여유 시 Segmented Control 업그레이드. 모바일은 Dropdown 고정.
R2 수렴 결과
| 쟁점 | R1 분포 | R2 수렴 |
|---|---|---|
| 탭 구조 | 5인 만장일치 단일 탭 | ✅ 유지 |
| 공제 UI 인라인 | 5인 만장일치 | ✅ 유지 |
| 유형 변경 정책 | 🔴 2파 대립 | ✅ 소 제기 전/후 분기 |
| 마이그레이션 | 🟡 3 갈래 | ✅ P5 병존 + debt 래핑 |
| 문서 UX | 🟡 4 vs 1 | ✅ modal + drawer 병존 |
| 선택 UI | 🟡 3 갈래 | ✅ Dropdown 기본 + Segmented 확장 |
모든 충돌 해소. R3 는 ADR 작성 + 와이어 + PR 계획 정리 (서기 역할).
R1·R2 공통 제기된 후속 질문 (R3 에서 결정)
| # | 질문 | 제기자 |
|---|---|---|
| Q1 | 기존 debt 사건 recoveryType backfill 정책 | P4·P5 |
| Q2 | 소멸시효 경고 UI (유형별 시효 다름) | P1 |
| Q3 | 공제 항목 증빙 파일 첨부 슬롯 | P2 |
| Q4 | 회수 성공률 상태머신 (4단계 공통) | P3 |
| Q5 | 모바일 대응 방침 | P4 |
| Q6 | "법원 사건번호 있음" 감지 로직 (courtCaseNumber 필드) | P4·P5 |