# SuperPort 프로젝트 리팩토링 계획 ## 📋 개요 현재 SuperPort 프로젝트의 일부 파일들이 너무 커서 코드 가독성과 유지보수성이 떨어지는 문제가 있습니다. 이 문서는 대규모 파일들을 작은 단위로 분리하고, 중복 코드를 제거하여 코드베이스를 개선하기 위한 상세한 리팩토링 계획입니다. ## 🎯 리팩토링 목표 1. **코드 가독성 향상**: 파일당 300줄 이하 유지 2. **중복 코드 제거**: 반복되는 패턴을 재사용 가능한 컴포넌트로 추출 3. **관심사 분리**: 각 파일이 단일 책임을 갖도록 분리 4. **유지보수성 향상**: 기능별로 모듈화하여 수정 용이성 증대 5. **재사용성 증대**: 공통 컴포넌트 및 유틸리티 함수 추출 ## 📊 현재 상태 분석 ### 문제가 되는 대형 파일들: 1. **`lib/screens/equipment/equipment_in_form.dart`** (2,315줄) - 7개의 드롭다운 필드에 대해 거의 동일한 코드 패턴 반복 - 각 필드마다 별도의 오버레이, 컨트롤러, 포커스 노드 관리 2. **`lib/screens/equipment/equipment_out_form.dart`** (852줄) - equipment_in_form과 유사한 구조와 문제점 3. **`lib/screens/equipment/equipment_list_redesign.dart`** (1,151줄) - 리스트 화면 로직과 UI가 한 파일에 혼재 4. **`lib/services/mock_data_service.dart`** (1,157줄) - 모든 엔티티의 초기 데이터와 CRUD 메서드가 한 파일에 집중 - 싱글톤 패턴으로 구현되어 있어 분리 시 주의 필요 ## 📂 새로운 디렉토리 구조 ``` lib/ ├── screens/ │ ├── equipment/ │ │ ├── equipment_in_form.dart (메인 화면 - 150줄) │ │ ├── equipment_out_form.dart (메인 화면 - 150줄) │ │ ├── equipment_list_redesign.dart (메인 화면 - 200줄) │ │ ├── controllers/ │ │ │ └── (기존 유지) │ │ └── widgets/ │ │ ├── (기존 위젯들) │ │ ├── equipment_in/ │ │ │ ├── equipment_in_form_body.dart │ │ │ ├── equipment_in_form_fields.dart │ │ │ ├── equipment_in_summary_section.dart │ │ │ └── equipment_in_action_buttons.dart │ │ ├── equipment_out/ │ │ │ ├── equipment_out_form_body.dart │ │ │ ├── equipment_out_form_fields.dart │ │ │ └── equipment_out_action_buttons.dart │ │ └── equipment_list/ │ │ ├── equipment_list_header.dart │ │ ├── equipment_list_filters.dart │ │ ├── equipment_list_table.dart │ │ └── equipment_list_item.dart │ │ │ └── common/ │ ├── custom_widgets/ │ │ ├── (기존 위젯들) │ │ └── overlay_dropdown/ │ │ ├── overlay_dropdown_field.dart │ │ ├── overlay_dropdown_controller.dart │ │ └── overlay_dropdown_config.dart │ └── mixins/ │ ├── form_validation_mixin.dart │ └── dropdown_handler_mixin.dart │ ├── services/ │ ├── mock_data_service.dart (메인 서비스 - 100줄) │ └── mock_data/ │ ├── mock_data_interface.dart │ ├── equipment_mock_data.dart │ ├── company_mock_data.dart │ ├── user_mock_data.dart │ ├── license_mock_data.dart │ └── warehouse_mock_data.dart │ └── utils/ └── dropdown/ ├── dropdown_utils.dart └── autocomplete_utils.dart ``` ## 🔧 상세 리팩토링 계획 ### 1. Equipment Form 리팩토링 #### 1.1 공통 드롭다운 컴포넌트 추출 **새 파일: `lib/screens/common/custom_widgets/overlay_dropdown/overlay_dropdown_field.dart`** ```dart class OverlayDropdownField extends StatefulWidget { final String label; final TextEditingController controller; final List items; final Function(String) onSelected; final String? Function(String)? getAutocompleteSuggestion; final bool isRequired; // ... 기타 필요한 속성들 } ``` **장점:** - 7개의 반복되는 드롭다운 코드를 하나의 재사용 가능한 컴포넌트로 통합 - 오버레이 관리 로직 캡슐화 - 포커스 관리 자동화 #### 1.2 Equipment In Form 분리 **`equipment_in_form.dart`** (150줄) - 메인 스캐폴드와 레이아웃만 포함 - 하위 위젯들을 조합하는 역할 **`equipment_in_form_body.dart`** (200줄) - 폼의 전체 구조 정의 - 섹션별 위젯 배치 **`equipment_in_form_fields.dart`** (300줄) - 모든 입력 필드 정의 - OverlayDropdownField 활용 **`equipment_in_summary_section.dart`** (150줄) - 요약 정보 표시 섹션 **`equipment_in_action_buttons.dart`** (100줄) - 저장, 취소 등 액션 버튼 #### 1.3 Mixin을 통한 공통 로직 추출 **`form_validation_mixin.dart`** ```dart mixin FormValidationMixin { bool validateRequiredField(String? value, String fieldName); bool validateEmail(String? value); bool validatePhone(String? value); // ... 기타 검증 메서드 } ``` ### 2. Mock Data Service 리팩토링 #### 2.1 인터페이스 정의 **`mock_data_interface.dart`** ```dart abstract class MockDataProvider { List getAll(); T? getById(int id); void add(T item); void update(T item); void delete(int id); void initializeData(); } ``` #### 2.2 엔티티별 Mock Data 분리 **`equipment_mock_data.dart`** (200줄) ```dart class EquipmentMockData implements MockDataProvider { final List _equipmentIns = []; final List _equipmentOuts = []; void initializeData() { // 장비 초기 데이터 } // CRUD 메서드들 } ``` **유사하게 구현:** - `company_mock_data.dart` - `user_mock_data.dart` - `license_mock_data.dart` - `warehouse_mock_data.dart` #### 2.3 메인 서비스 리팩토링 **`mock_data_service.dart`** (100줄) ```dart class MockDataService { static final MockDataService _instance = MockDataService._internal(); late final EquipmentMockData equipmentData; late final CompanyMockData companyData; late final UserMockData userData; late final LicenseMockData licenseData; late final WarehouseMockData warehouseData; void initialize() { equipmentData = EquipmentMockData()..initializeData(); companyData = CompanyMockData()..initializeData(); // ... } } ``` ### 3. Equipment List 리팩토링 #### 3.1 컴포넌트 분리 **`equipment_list_header.dart`** (100줄) - 제목, 추가 버튼, 필터 토글 **`equipment_list_filters.dart`** (150줄) - 검색 및 필터 UI **`equipment_list_table.dart`** (200줄) - 테이블 헤더와 바디 **`equipment_list_item.dart`** (100줄) - 개별 리스트 아이템 렌더링 ## 🚀 구현 순서 ### Phase 1: 공통 컴포넌트 구축 (우선순위: 높음) 1. OverlayDropdownField 컴포넌트 개발 2. FormValidationMixin 구현 3. 공통 유틸리티 함수 추출 ### Phase 2: Equipment Forms 리팩토링 (우선순위: 높음) 1. equipment_in_form.dart 분리 2. equipment_out_form.dart 분리 3. 기존 기능 테스트 및 검증 ### Phase 3: Mock Data Service 분리 (우선순위: 중간) 1. MockDataInterface 정의 2. 엔티티별 mock data 클래스 생성 3. 메인 서비스 리팩토링 4. 의존성 주입 패턴 적용 ### Phase 4: Equipment List 리팩토링 (우선순위: 중간) 1. 리스트 컴포넌트 분리 2. 상태 관리 최적화 ### Phase 5: 기타 대형 파일 검토 (우선순위: 낮음) 1. 600줄 이상 파일들 추가 분석 2. 필요시 추가 리팩토링 ## ⚠️ 주의사항 1. **기능 보존**: 모든 리팩토링은 기존 기능을 100% 유지해야 함 2. **점진적 적용**: 한 번에 하나의 컴포넌트씩 리팩토링 3. **테스트**: 각 단계별로 충분한 테스트 수행 4. **버전 관리**: 각 리팩토링 단계별로 커밋 5. **의존성**: MockDataService는 싱글톤 패턴이므로 분리 시 주의 6. **성능**: 파일 분리로 인한 import 증가가 성능에 미치는 영향 최소화 ## 📈 예상 효과 1. **가독성**: 파일당 평균 200줄로 감소 (90% 개선) 2. **중복 제거**: 드롭다운 관련 코드 85% 감소 3. **유지보수**: 기능별 파일 분리로 수정 범위 명확화 4. **재사용성**: 공통 컴포넌트로 신규 폼 개발 시간 50% 단축 5. **테스트**: 단위 테스트 작성 용이성 향상 ## 🔄 롤백 계획 각 단계별로 git 브랜치를 생성하여 문제 발생 시 즉시 롤백 가능하도록 함: - `refactor/phase-1-common-components` - `refactor/phase-2-equipment-forms` - `refactor/phase-3-mock-data` - `refactor/phase-4-equipment-list` ## 📝 추가 고려사항 1. **국제화(i18n)**: 리팩토링 시 다국어 지원 구조 개선 2. **접근성**: WCAG 가이드라인 준수 여부 확인 3. **성능 최적화**: 불필요한 리빌드 방지를 위한 const 생성자 활용 4. **문서화**: 각 컴포넌트별 JSDoc 스타일 주석 추가 --- 이 계획은 코드베이스의 품질을 크게 향상시키면서도 기존 기능을 그대로 유지하는 것을 목표로 합니다. 각 단계는 독립적으로 수행 가능하며, 프로젝트 일정에 따라 우선순위를 조정할 수 있습니다.