# 대규모 파일 모듈 분리 리팩토링 계획

> 작성일: 2026-03-10
> 대상: dohyeons 작성 코드 중 대규모 파일 7개

---

## 전체 현황

| # | 파일 | 줄 수 | 외부 소비자 수 | 분리 난이도 |
|---|------|-------|---------------|------------|
| 1 | `frontend/lib/utils/buttonActions.ts` | 7,835 | 3곳 | 중 |
| 2 | `frontend/components/screen/ScreenDesigner.tsx` | 7,572 | 2곳 | 상 |
| 3 | `frontend/lib/registry/components/table-list/TableListComponent.tsx` | 6,815 | 3곳 | 상 |
| 4 | `backend-node/src/services/screenManagementService.ts` | 6,614 | **1곳** | **하** |
| 5 | `backend-node/src/services/tableManagementService.ts` | 5,346 | 3곳 | 중 |
| 6 | `frontend/components/screen/ScreenSettingModal.tsx` | 5,108 | **1곳** | **하** |
| 7 | `frontend/components/screen/config-panels/ButtonConfigPanel.tsx` | 4,693 | 5곳 | 상 |

---

## 1. `buttonActions.ts` (7,835줄)

### 현재 구조
단일 `ButtonActionExecutor` 클래스에 20+ 핸들러 메서드가 모두 포함.

### 외부에서 사용하는 곳

| 소비자 파일 | 가져오는 심볼 |
|------------|-------------|
| `lib/registry/components/v2-button-primary/ButtonPrimaryComponent.tsx` | `ButtonActionExecutor`, `ButtonActionContext`, `ButtonActionType`, `DEFAULT_BUTTON_ACTIONS` |
| `lib/registry/components/button-primary/ButtonPrimaryComponent.tsx` | `ButtonActionExecutor`, `ButtonActionContext`, `ButtonActionType`, `DEFAULT_BUTTON_ACTIONS` |
| `lib/registry/components/v2-button-primary/types.ts` | `ButtonActionConfig` |
| `lib/registry/components/button-primary/types.ts` | `ButtonActionConfig` |
| `components/screen/EditModal.tsx` | `ButtonActionExecutor` (동적 import) |

### 외부에서 호출하는 메서드 (2개만)
- `executeAction()` ← ButtonPrimaryComponent에서 호출
- `executeAfterSaveControl()` ← EditModal에서 호출

### 나머지 20+ 핸들러는 모두 내부 전용
`handleSave`, `handleDelete`, `handleModal`, `handleControl`, `handleExcelDownload` 등은 `executeAction` 내부에서만 분기 호출됨.

### 분리 계획

```
frontend/lib/utils/buttonActions/
├── index.ts                    # 기존 export 유지 (호환성)
├── types.ts                    # ButtonActionType, ButtonActionConfig, ButtonActionContext (~300줄)
├── utils.ts                    # normalizeFormDataArrays, resolveSpecialKeyword (~50줄)
├── defaults.ts                 # DEFAULT_BUTTON_ACTIONS (~130줄)
├── ButtonActionExecutor.ts     # executeAction 라우터 + 공통 메서드 (~500줄)
└── handlers/
    ├── saveHandler.ts          # handleSave, handleSubmit, handleBatchSave (~700줄)
    ├── deleteHandler.ts        # handleDelete (~130줄)
    ├── modalHandler.ts         # handleModal, handleOpenRelatedModal (~500줄)
    ├── editHandler.ts          # handleEdit, handleCopy (~370줄)
    ├── controlHandler.ts       # handleControl (~850줄)
    ├── excelHandler.ts         # handleExcelDownload/Upload (~600줄)
    ├── trackingHandler.ts      # handleTrackingStart/Stop (~500줄)
    ├── dataHandler.ts          # handleTransferData, handleSwapFields, handleQuickInsert (~500줄)
    ├── operationHandler.ts     # handleOperationControl (~320줄)
    ├── specialHandler.ts       # handleBarcodeScan, handleCodeMerge, handleEvent (~300줄)
    └── rackHandler.ts          # handleRackStructureBatchSave 등 (~400줄)
```

### 영향 범위
- `index.ts`에서 기존 심볼 re-export → **외부 코드 변경 0건**
- 내부 핸들러 분리는 외부에 영향 없음

---

## 2. `ScreenDesigner.tsx` (7,572줄)

### 현재 구조
상태 50+개, 이벤트 핸들러 30+개, JSX 1,700줄이 단일 함수 컴포넌트에 포함.

### 외부에서 사용하는 곳 (2곳만)

| 소비자 파일 | 전달 props |
|------------|-----------|
| `app/(main)/admin/screenMng/screenMngList/page.tsx` | `selectedScreen`, `onBackToList`, `onScreenUpdate` |
| `components/screen/ScreenSettingModal.tsx` | `selectedScreen`, `onBackToList` |

### Props 인터페이스
```typescript
interface ScreenDesignerProps {
  selectedScreen: ScreenDefinition | null;
  onBackToList: () => void;
  onScreenUpdate?: (updatedScreen: Partial<ScreenDefinition>) => void;
  isPop?: boolean;
  defaultDevicePreview?: "mobile" | "tablet";
}
```

### ScreenDesigner가 의존하는 것들

| 카테고리 | 주요 의존성 |
|---------|-----------|
| UI 컴포넌트 (15+) | `SlimToolbar`, `ComponentsPanel`, `PropertiesPanel`, `LayerManagerPanel`, `FlowButtonGroup`, `FlowButtonGroupDialog`, `MenuAssignmentModal` 등 |
| 유틸 (10+) | `gridUtils`, `alignmentUtils`, `groupingUtils`, `flowButtonGroupUtils`, `webTypeMapping`, `layoutV2Converter` 등 |
| API (4) | `screenApi`, `tableTypeApi`, `tableManagementApi`, `ExternalRestApiConnectionAPI` |
| 타입 (10+) | `ScreenDefinition`, `ComponentData`, `LayoutData`, `GridSettings` 등 |
| Context (3) | `LayerProvider`, `ScreenPreviewProvider`, `TableOptionsProvider` |

### 분리 계획

```
frontend/components/screen/screen-designer/
├── index.ts                          # export default ScreenDesigner (호환성)
├── ScreenDesigner.tsx                # 메인 (조합만, ~800줄)
├── types.ts                          # ScreenDesignerProps
├── constants.ts                      # panelConfigs
│
├── hooks/
│   ├── useDesignerState.ts           # 50+ useState 묶음 (~200줄)
│   ├── useLayoutLoader.ts            # loadLayout, loadScreenDataSource (~400줄)
│   ├── useLayoutHistory.ts           # saveToHistory, undo, redo (~150줄)
│   ├── useComponentProperty.ts       # updateComponentProperty (~300줄)
│   ├── usePanZoom.ts                 # Pan/Zoom/Grid (~250줄)
│   ├── useDesignerKeyboard.ts        # 키보드 단축키 (~500줄)
│   ├── useAlignmentHandlers.ts       # 정렬/배분/크기맞춤 (~200줄)
│   ├── useClipboard.ts              # copy, paste, delete (~400줄)
│   ├── useDragHandlers.ts           # startDrag, updateDrag, endDrag (~400줄)
│   └── useDropHandlers.ts           # handleDrop 통합 (~1,000줄)
│
├── components/
│   ├── DesignerCanvas.tsx            # 캔버스 영역 (~400줄)
│   ├── DesignerPropertiesPanel.tsx   # 속성 패널 분기 (~600줄)
│   ├── FlowButtonGroupPanel.tsx      # 플로우 버튼 그룹 UI (~200줄)
│   ├── ActiveLayerIndicator.tsx      # 레이어 인디케이터 (~50줄)
│   └── DesignerModals.tsx            # 모달 묶음 (~200줄)
│
└── utils/
    ├── gridSnapUtils.ts              # snapTo10px, calculateGridInfo (~50줄)
    ├── webTypeDefaults.ts            # getDefaultWebTypeConfig (~50줄)
    └── fileComponentRestore.ts       # restoreFileComponentsData (~100줄)
```

### 영향 범위
- `screen-designer/index.ts`에서 `export default ScreenDesigner` → **외부 import 변경 필요**
- 변경 대상: `screenMngList/page.tsx`, `ScreenSettingModal.tsx` (2곳만)
- 또는 기존 `ScreenDesigner.tsx`를 re-export 래퍼로 남겨두면 **변경 0건**

---

## 3. `TableListComponent.tsx` (6,815줄)

### 현재 구조
데이터 fetch, 필터링, 인라인 편집, WebSocket, Excel/PDF 내보내기가 모두 한 컴포넌트에 포함.

### 외부에서 사용하는 곳

| 소비자 파일 | 가져오는 심볼 |
|------------|-------------|
| `table-list/TableListRenderer.tsx` | `TableListComponent` |
| `table-list/index.ts` | `TableListWrapper` |
| `components/v2/V2List.tsx` | `TableListComponent` |

### 분리 계획

```
frontend/lib/registry/components/table-list/
├── TableListComponent.tsx          # 메인 (조합, ~800줄)
├── types.ts                        # 인터페이스, 상수 (~200줄)
│
├── hooks/
│   ├── useTableData.ts             # fetch, 페이지네이션, 정렬 (~500줄)
│   ├── useTableFilters.ts          # 헤더 필터, 고급 검색 (~400줄)
│   ├── useTableSelection.ts        # 행 선택 (~200줄)
│   ├── useTableEditing.ts          # 인라인 편집 (~300줄)
│   ├── useTableState.ts            # 컬럼 순서/너비 저장 (~200줄)
│   ├── useTableWebSocket.ts        # WebSocket (~150줄)
│   └── useTableExport.ts           # Excel/PDF (~200줄)
│
├── components/
│   ├── TableHeader.tsx             # 헤더 렌더링 (~300줄)
│   ├── TableBody.tsx               # 바디 렌더링 (~400줄)
│   ├── TableContextMenu.tsx        # 우클릭 메뉴 (~150줄)
│   ├── FilterPanel.tsx             # 필터 패널 (~200줄)
│   └── ColumnOptionsPanel.tsx      # 컬럼 옵션 (~200줄)
│
└── utils/
    ├── formatCellValue.ts          # 셀 값 포맷팅 (~100줄)
    └── filterUtils.ts              # 필터 조건 평가 (~100줄)
```

### 영향 범위
- `TableListComponent`, `TableListWrapper` export 유지 → **외부 변경 0건**

---

## 4. `screenManagementService.ts` (6,614줄) - 소비자 1곳

### 외부에서 사용하는 곳

| 소비자 파일 | 가져오는 심볼 |
|------------|-------------|
| `controllers/screenManagementController.ts` | `screenManagementService` (싱글톤 인스턴스) |

### 분리 계획

```
backend-node/src/services/screen/
├── index.ts                        # screenManagementService 싱글톤 re-export
├── ScreenManagementService.ts      # 클래스 정의 + 메서드 위임 (~300줄)
├── screenCrudService.ts            # createScreen, getScreen*, updateScreen* (~600줄)
├── screenDeletionService.ts        # delete, restore, permanentDelete, bulk* (~800줄)
├── screenLayoutService.ts          # saveLayout, getLayout (~600줄)
├── screenMenuService.ts            # assignScreenToMenu, getScreensByMenu (~300줄)
├── screenTemplateService.ts        # getTemplatesByCompany, createTemplate (~200줄)
├── screenColumnService.ts          # getColumnInfo, setColumnWebType, generateWidget (~400줄)
├── screenCodeGenerator.ts          # generateScreenCode (~200줄)
└── screenTableService.ts           # getTables, getTableInfo, getTableColumns (~400줄)
```

### 영향 범위
- `index.ts`에서 `screenManagementService` re-export → **컨트롤러 변경 0건**
- **소비자 1곳** → 가장 안전한 리팩토링 대상

---

## 5. `tableManagementService.ts` (5,346줄)

### 외부에서 사용하는 곳

| 소비자 파일 | 가져오는 심볼 |
|------------|-------------|
| `controllers/tableManagementController.ts` | `TableManagementService` |
| `controllers/entityJoinController.ts` | `TableManagementService` |
| `services/multiConnectionQueryService.ts` | `TableManagementService` |

### 분리 계획

```
backend-node/src/services/table/
├── index.ts                        # TableManagementService re-export
├── TableManagementService.ts       # 클래스 정의 + 메서드 위임 (~300줄)
├── tableMasterService.ts           # getTableList, getTableLabels (~400줄)
├── columnSettingsService.ts        # getColumnList, updateColumnSettings (~800줄)
├── tableDataService.ts             # getTableData, addTableData, editTableData, deleteTableData (~800줄)
├── tableEntityJoinService.ts       # getTableDataWithEntityJoins (~1,000줄)
├── tableValidationService.ts       # validateNotNull, validateUnique (~200줄)
├── tableLogService.ts              # createLogTable, getLogConfig, toggleLogTable (~400줄)
└── tableSchemaService.ts           # getTableSchema, checkTableExists (~400줄)
```

### 영향 범위
- `index.ts`에서 `TableManagementService` re-export → **외부 변경 0건**

---

## 6. `ScreenSettingModal.tsx` (5,108줄) - 소비자 1곳

### 현재 구조
4개 탭 컴포넌트(`OverviewTab`, `FieldMappingTab`, `DataFlowTab`, `ControlManagementTab`)와 서브 컴포넌트(`SearchableSelect`, `TableColumnAccordion`, `JoinSettingEditor`)가 모두 인라인 정의.

### 외부에서 사용하는 곳

| 소비자 파일 | 가져오는 심볼 |
|------------|-------------|
| `components/screen/ScreenRelationFlow.tsx` | `ScreenSettingModal` |

### 분리 계획

```
frontend/components/screen/screen-setting/
├── index.ts                         # ScreenSettingModal re-export
├── ScreenSettingModal.tsx           # 메인 모달 셸 (~500줄)
├── hooks/
│   └── useScreenSettingData.ts      # loadData, dataFlows (~300줄)
├── components/
│   ├── SearchableSelect.tsx         # 검색 가능 셀렉트 (~60줄)
│   ├── TableColumnAccordion.tsx     # 컬럼 아코디언 (~500줄)
│   └── JoinSettingEditor.tsx        # 조인 설정 에디터 (~200줄)
└── tabs/
    ├── OverviewTab.tsx              # 개요 탭 (~900줄)
    ├── FieldMappingTab.tsx          # 필드 매핑 탭 (~400줄)
    ├── DataFlowTab.tsx              # 데이터 플로우 탭 (~300줄)
    └── ControlManagementTab.tsx     # 버튼 제어 탭 (~2,000줄)
```

### 영향 범위
- `index.ts`에서 re-export → **외부 변경 0건**
- **소비자 1곳** → 안전한 리팩토링 대상

---

## 7. `ButtonConfigPanel.tsx` (4,693줄) - 소비자 5곳

### 현재 구조
액션 타입별 설정 UI가 조건부 렌더링으로 3,200줄, 인라인 엑셀 설정 컴포넌트 4개가 포함.

### 외부에서 사용하는 곳

| 소비자 파일 | 가져오는 심볼 | import 방식 |
|------------|-------------|------------|
| `lib/registry/init.ts` | `ButtonConfigPanel` | 정적 import |
| `lib/utils/getConfigPanelComponent.tsx` | `OriginalButtonConfigPanel` | 정적 import (별칭) |
| `lib/utils/getComponentConfigPanel.tsx` | `ButtonConfigPanel` | 동적 import |
| `components/screen/panels/V2PropertiesPanel.tsx` | `ButtonConfigPanel` | 정적 import |
| `components/screen/panels/DetailSettingsPanel.tsx` | `NewButtonConfigPanel` | 정적 import (별칭) |

### 분리 계획

```
frontend/components/screen/config-panels/button-config/
├── index.ts                              # ButtonConfigPanel re-export
├── ButtonConfigPanel.tsx                 # 메인 (액션 타입별 라우팅, ~500줄)
├── hooks/
│   ├── useButtonConfigState.ts           # 50+ useState (~200줄)
│   └── useButtonConfigData.ts            # loadTableColumns, filterScreens (~300줄)
├── sections/
│   ├── SaveActionConfig.tsx              # 저장 액션 설정 (~400줄)
│   ├── ModalActionConfig.tsx             # 모달 액션 설정 (~400줄)
│   ├── NavigateActionConfig.tsx          # 네비게이션 설정 (~300줄)
│   ├── EditActionConfig.tsx              # 편집 설정 (~200줄)
│   ├── ControlActionConfig.tsx           # 제어 설정 (~300줄)
│   └── ExcelActionConfig.tsx             # 엑셀 설정 (~500줄)
└── components/
    ├── MasterDetailExcelUploadConfig.tsx  (~340줄)
    ├── ExcelNumberingRuleInfo.tsx         (~15줄)
    ├── ExcelAfterUploadControlConfig.tsx  (~155줄)
    └── ExcelUploadConfigSection.tsx       (~160줄)
```

### 영향 범위
- `button-config/index.ts`에서 `ButtonConfigPanel` re-export
- 기존 `ButtonConfigPanel.tsx` 파일 경로가 바뀌므로 **5곳 import 경로 수정 필요**
- 또는 기존 위치에 re-export 래퍼를 남겨두면 **변경 0건**

---

## 선택적 실행 가이드

### 안전도 기준 (소비자 수 기반)

| 안전도 | 파일 | 소비자 | 비고 |
|--------|------|--------|------|
| **매우 안전** | `screenManagementService.ts` | 1곳 | 컨트롤러 1개만 사용 |
| **매우 안전** | `ScreenSettingModal.tsx` | 1곳 | ScreenRelationFlow만 사용 |
| **안전** | `ScreenDesigner.tsx` | 2곳 | 페이지 1 + 모달 1 |
| **안전** | `buttonActions.ts` | 3곳 | 버튼 컴포넌트 2 + EditModal 1 |
| **안전** | `TableListComponent.tsx` | 3곳 | 렌더러 + index + V2List |
| **안전** | `tableManagementService.ts` | 3곳 | 컨트롤러 2 + 서비스 1 |
| **주의** | `ButtonConfigPanel.tsx` | 5곳 | 정적 3 + 동적 1 + 별칭 1 |

### 독립 실행 가능 여부

각 파일은 **서로 의존하지 않으므로** 원하는 것만 선택적으로 진행 가능합니다.

| 파일 | 다른 대상 파일과의 의존성 | 독립 실행 |
|------|------------------------|----------|
| `buttonActions.ts` | 없음 | 가능 |
| `ScreenDesigner.tsx` | 없음 | 가능 |
| `TableListComponent.tsx` | 없음 | 가능 |
| `screenManagementService.ts` | 없음 | 가능 |
| `tableManagementService.ts` | 없음 | 가능 |
| `ScreenSettingModal.tsx` | ScreenDesigner를 import하지만 분리와 무관 | 가능 |
| `ButtonConfigPanel.tsx` | 없음 | 가능 |

---

## 권장 실행 순서 (효과 대비 안전도)

| 순서 | 파일 | 이유 |
|------|------|------|
| 1 | `screenManagementService.ts` | 소비자 1곳, 백엔드라 UI 영향 없음 |
| 2 | `ScreenSettingModal.tsx` | 소비자 1곳, 탭 분리라 구조 명확 |
| 3 | `buttonActions.ts` | 핸들러별 분리라 패턴 명확, 외부 변경 0건 |
| 4 | `ScreenDesigner.tsx` | 가장 효과 큼 (7,572줄), 소비자 2곳 |
| 5 | `tableManagementService.ts` | 백엔드, 패턴이 #1과 동일 |
| 6 | `TableListComponent.tsx` | 훅 추출 복잡도 높음 |
| 7 | `ButtonConfigPanel.tsx` | 소비자 5곳, import 경로 관리 필요 |
