# Inv* 일괄 네이밍 통합 + 리팩토링 검토

날짜: 2026-04-28
요청자: gbpark
검토자: Claude + Codex (예정)

---

## 0. 배경

좌측 팔레트 10 컴포넌트의 ConfigPanel cp 톤 마이그 완료. 단 이름이 일관되지 않음 — 일부는 `Inv*`, 일부는 in-place (원래 이름 유지).

cp-panel-standard.md §10 의 정책: **모든 새 ConfigPanel / 마이그레이션 대상 = `Inv*` prefix**

→ 일괄 Inv* 로 정리 필요 + 리팩토링 같이.

---

## 1. 현황 — ConfigPanel 위치별 정리

### 1.1 frontend/components/v2/config-panels/

**Inv* (cp 톤 신규/마이그):**
- `InvDataConfigPanel.tsx` — "데이터 조회/선택" wrapper
- `InvRepeaterConfigPanel.tsx` — InvData 의 repeater 분기 본체 (V2RepeaterConfigPanel 폐기 → 신규)
- `InvDividerConfigPanel.tsx` — 옛 v2-divider-line 의 패널 (hidden 호환용)
- `InvTextConfigPanel.tsx` — 옛 v2-text-display 의 패널 (hidden 호환용)
- `InvButtonConfigPanel.tsx` — 옛 v2-button-primary 의 패널 (hidden 호환용)

**V2* (cp 마이그됨, 이름만 V2):**
- `V2FieldConfigPanel.tsx` (2191줄) — "입력 필드" 진짜 패널, cp 톤 ✅, 이름만 V2

**V2* (cp 마이그 안 됨, 옛 디자인):**
- V2AggregationWidget / V2ApprovalStep / V2BizConfig / V2BomItemEditor / V2BomTree / V2CardDisplay / V2CategoryManager / V2Date / V2FileUpload / V2Group / V2Hierarchy / V2InputConfigPanel / V2ItemRouting / V2Layout / V2List / V2LocationSwapSelector / V2Media / V2NumberingRule / V2PivotGrid / V2ProcessWorkStandard / V2RackStructure / V2RepeatContainer / V2SectionCard / V2SectionPaper / V2Select / V2SelectedItemsDetailInput / V2SplitLine / V2SplitPanelLayout / V2StatusCount / V2TableGrouped / V2TableList (1497줄!) / V2TableSearchWidget / V2TimelineScheduler

### 1.2 lib/registry/components/X/XConfigPanel.tsx (in-place 마이그)

좌측 팔레트의 통합 컴포넌트 7개 (모두 cp 톤 ✅):
- `divider/DividerConfigPanel.tsx` — id "divider"
- `title/TitleConfigPanel.tsx` — id "title"
- `container/ContainerConfigPanel.tsx` — id "container"
- `button/ButtonConfigPanel.tsx` — id "button"
- `search/SearchConfigPanel.tsx` — id "search"
- `stats/StatsConfigPanel.tsx` — id "stats"
- `table/TableConfigPanel.tsx` — id "table"

### 1.3 좌측 팔레트 라벨 → ConfigPanel 매핑 (10개)

| 라벨 | id | ConfigPanel |
|---|---|---|
| 데이터 조회/선택 | v2-repeater | InvDataConfigPanel + InvRepeaterConfigPanel |
| 입력 필드 | v2-input/v2-select | V2FieldConfigPanel |
| 구분선 | divider | divider/DividerConfigPanel |
| 제목/텍스트 | title | title/TitleConfigPanel |
| 영역 | container | container/ContainerConfigPanel |
| 버튼 | button | button/ButtonConfigPanel |
| 검색 | search | search/SearchConfigPanel |
| 통계 카드 | stats | stats/StatsConfigPanel |
| 테이블 | table | table/TableConfigPanel |

---

## 2. 이름 충돌 이슈

옛 v2-* 컴포넌트의 호환 패널을 만들 때 이미 Inv* 사용:

| 옛 v2 컴포넌트 (hidden) | 호환 패널 (frontend/components/v2/config-panels/) | 통합 컴포넌트의 같은 이름 |
|---|---|---|
| v2-divider-line | InvDividerConfigPanel ✅ 사용 중 | divider 의 DividerConfigPanel |
| v2-text-display | InvTextConfigPanel ✅ 사용 중 (?) | title 의 TitleConfigPanel |
| v2-button-primary | InvButtonConfigPanel ✅ 사용 중 | button 의 ButtonConfigPanel |

통합 컴포넌트도 InvDivider/InvButton 으로 가려면 충돌.

### 옛 V2 컴포넌트의 사용 여부

- v2-divider-line: `hidden: true` (팔레트 X). 이미 만들어진 옛 화면만 렌더용
- v2-text-display: `hidden: true`
- v2-button-primary: `hidden: true`

**→ 신규 배치 시 사용자가 절대 보지 못함. 옛 화면 호환만.**

---

## 3. 해결안 후보

### 옵션 A: 옛 v2 호환 패널 삭제 + 통합 패널이 Inv* 차지

- 옛 v2-* 컴포넌트의 config_panel 매핑을 통합 패널로 변경 (예: v2-divider-line의 config_panel = InvDividerConfigPanel = 통합 divider 의 패널)
- 옛 호환용 InvDividerConfigPanel/InvTextConfigPanel/InvButtonConfigPanel **삭제**
- 통합 컴포넌트 패널 rename: divider/DividerConfigPanel → divider/InvDividerConfigPanel
- **충돌 해결 + 코드 슬림**
- ⚠️ 위험: 옛 v2-* config 스키마 ≠ 통합 컴포넌트 스키마 (예: ButtonConfig vs v2-button-primary 의 풍부한 액션). 옛 화면이 깨질 수 있음

### 옵션 B: 옛 호환 InvXxxConfigPanel을 InvLegacyXxxConfigPanel 로 rename

- 충돌 해결
- 옛 화면 안전 (스키마 보존)
- 통합 컴포넌트가 Inv* 이름 차지
- 코드 양 그대로 (legacy 패널 보존)

### 옵션 C: 옛 v2-* 컴포넌트 자체를 deprecate + 옛 화면 마이그레이션 스크립트

- 옛 v2-divider-line 데이터 → divider 로 변환
- 옛 v2-button-primary 데이터 → button 으로 변환
- 옛 컴포넌트 + 호환 패널 둘 다 삭제
- 가장 깔끔하지만 마이그레이션 스크립트 작성 필요 (큰 작업)

---

## 4. 일괄 rename 대상 (옵션 A or B 선택 후)

### rename 필요한 통합 컴포넌트 패널 (7개)

```
lib/registry/components/divider/DividerConfigPanel.tsx → InvDividerConfigPanel.tsx
lib/registry/components/title/TitleConfigPanel.tsx     → InvTitleConfigPanel.tsx
lib/registry/components/container/ContainerConfigPanel.tsx → InvContainerConfigPanel.tsx
lib/registry/components/button/ButtonConfigPanel.tsx   → InvButtonConfigPanel.tsx (옵션 A 시 충돌 해결)
lib/registry/components/search/SearchConfigPanel.tsx   → InvSearchConfigPanel.tsx
lib/registry/components/stats/StatsConfigPanel.tsx     → InvStatsConfigPanel.tsx
lib/registry/components/table/TableConfigPanel.tsx     → InvTableConfigPanel.tsx
```

### rename 필요한 V2* (1개)

```
frontend/components/v2/config-panels/V2FieldConfigPanel.tsx → InvFieldConfigPanel.tsx
```

### 호출처 갱신 대상

각 통합 컴포넌트의 index.ts (component_definition) + 외부 import + getComponentConfigPanel.tsx

---

## 5. 리팩토링 검토 후보 (Codex 에게)

### 5.1 중복 코드 패턴

- **테이블 연결 + 자동 로드 버튼**: search / table / stats 3 패널 모두 비슷한 패턴 (CPSelect 테이블 + Wand2 자동 로드 버튼). **공용 `<TableConnectSection>` 추출 가능?**
- **Dense list + 펼침**: search 의 SearchFieldRow / table 의 ColumnEditRow / stats 의 ItemEditRow 모두 비슷한 row 패턴 (#번호 + 라벨 + key + ▸ 펼침 + ×). **공용 `<DenseListRow>` 또는 `<ExpandableRow>` 추출?**
- **autoLoad + tableManagementApi.getTableList**: search / table / stats 모두 같은 useEffect. **공용 `useDbTables()` hook?**

### 5.2 dead code 후보

- 옛 V2 호환 패널 3개 (해결안 결정 후)
- frontend/components/v2/config-panels/ 의 V2* 마이그 안 된 33개 (실제 사용 여부 확인)

### 5.3 cp/_shared 확장 후보

- `TableConnectSection` (테이블 + 자동 로드)
- `useDbTables()` hook
- `ExpandableRow` (dense + 펼침 패턴)
- `useExpandable(ids)` (펼침 상태 관리)

---

## 6. Codex 검토 요청

1. **이름 충돌 해결**: 옵션 A vs B vs C 중 어느 게 안전 + 깔끔?
2. **rename 작업 순서**: 한 번에 vs 점진?
3. **리팩토링 우선순위**: 위 5.1 / 5.2 / 5.3 중 임팩트 큰 것?
4. **dead code 식별 방법**: V2* 33개 중 실제 사용/미사용 빠르게 판별?
5. **마이그 안 된 V2* 33개**: 다음 단계로 cp 마이그 가야 하나, 아니면 통합 컴포넌트로 흡수만 하면 되나?
