사용하지 않는 파일 정리 전 백업 (Phase 10 완료 후 상태)
This commit is contained in:
796
.claude/research/codebase_structure_analysis.md
Normal file
796
.claude/research/codebase_structure_analysis.md
Normal file
@@ -0,0 +1,796 @@
|
||||
# Superport ERP 코드베이스 구조 상세 분석
|
||||
|
||||
> 📅 **분석 일자**: 2025-08-23
|
||||
> 🎯 **목적**: 백엔드 API 스키마 동기화 및 ShadCN UI 마이그레이션 기초 자료
|
||||
> 📊 **분석 범위**: /Users/maximilian.j.sul/Documents/flutter/superport/lib/ 전체
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 1. 전체 디렉토리 구조 매핑
|
||||
|
||||
### 📁 Clean Architecture 기반 구조
|
||||
```
|
||||
lib/
|
||||
├── assets/ # 정적 자원
|
||||
│ └── fonts/ # 한글 폰트 (NotoSansKR)
|
||||
├── core/ # 핵심 공통 기능
|
||||
│ ├── config/ # 환경 설정
|
||||
│ ├── constants/ # 상수 정의
|
||||
│ ├── controllers/ # 기본 컨트롤러
|
||||
│ ├── errors/ # 에러 처리
|
||||
│ ├── extensions/ # 확장 메서드
|
||||
│ ├── services/ # 코어 서비스
|
||||
│ ├── storage/ # 보안 저장소
|
||||
│ ├── utils/ # 유틸리티
|
||||
│ └── widgets/ # 공통 위젯
|
||||
├── data/ # Data Layer (Clean Architecture)
|
||||
│ ├── datasources/ # 데이터 소스
|
||||
│ │ ├── interceptors/ # API 인터셉터
|
||||
│ │ ├── local/ # 로컬 데이터 소스
|
||||
│ │ └── remote/ # 원격 데이터 소스
|
||||
│ ├── models/ # DTO 모델 (Freezed)
|
||||
│ │ ├── auth/ # 인증 관련
|
||||
│ │ ├── common/ # 공통 응답 모델
|
||||
│ │ ├── company/ # 회사 관련
|
||||
│ │ ├── dashboard/ # 대시보드
|
||||
│ │ ├── equipment/ # 장비 관련
|
||||
│ │ ├── license/ # 라이선스 관련
|
||||
│ │ ├── lookups/ # 룩업 데이터
|
||||
│ │ ├── user/ # 사용자 관련
|
||||
│ │ └── warehouse/ # 창고 관련
|
||||
│ └── repositories/ # Repository 구현체
|
||||
├── domain/ # Domain Layer (비즈니스 로직)
|
||||
│ ├── entities/ # 도메인 엔티티 (비어있음)
|
||||
│ ├── repositories/ # Repository 인터페이스
|
||||
│ └── usecases/ # UseCase (비즈니스 규칙)
|
||||
│ ├── auth/ # 인증 UseCase
|
||||
│ ├── company/ # 회사 UseCase
|
||||
│ ├── equipment/ # 장비 UseCase
|
||||
│ ├── license/ # 라이선스 UseCase
|
||||
│ ├── lookups/ # 룩업 UseCase
|
||||
│ ├── user/ # 사용자 UseCase
|
||||
│ └── warehouse_location/ # 창고 위치 UseCase
|
||||
├── models/ # 레거시 모델 (마이그레이션 중)
|
||||
├── screens/ # Presentation Layer
|
||||
│ ├── common/ # 공통 UI 컴포넌트
|
||||
│ │ ├── components/ # 재사용 컴포넌트
|
||||
│ │ ├── custom_widgets/ # 커스텀 위젯
|
||||
│ │ ├── layouts/ # 레이아웃 템플릿
|
||||
│ │ ├── templates/ # 폼 템플릿
|
||||
│ │ └── widgets/ # 표준 위젯
|
||||
│ ├── company/ # 회사 관리 화면
|
||||
│ │ ├── controllers/ # Provider 컨트롤러
|
||||
│ │ └── widgets/ # 회사 관련 위젯
|
||||
│ ├── equipment/ # 장비 관리 화면
|
||||
│ │ ├── controllers/ # Provider 컨트롤러
|
||||
│ │ └── widgets/ # 장비 관련 위젯
|
||||
│ ├── license/ # 라이선스 관리 화면
|
||||
│ │ ├── controllers/ # Provider 컨트롤러
|
||||
│ │ └── widgets/ # 라이선스 관련 위젯
|
||||
│ ├── login/ # 로그인 화면
|
||||
│ ├── overview/ # 대시보드 화면
|
||||
│ ├── user/ # 사용자 관리 화면
|
||||
│ └── warehouse_location/ # 창고 위치 관리 화면
|
||||
├── services/ # 레거시 서비스 레이어
|
||||
├── utils/ # 유틸리티 함수
|
||||
├── injection_container.dart # 의존성 주입 설정
|
||||
└── main.dart # 앱 진입점
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 2. 화면별 상세 분석
|
||||
|
||||
### 🏠 **메인 레이아웃 (AppLayout)**
|
||||
**파일**: `/lib/screens/common/app_layout.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- F-Pattern 레이아웃 적용 (1920x1080 최적화)
|
||||
- 상단 헤더 + 좌측 사이드바 + 메인 콘텐츠 구조
|
||||
- 접이식 사이드바 (260px ↔ 72px)
|
||||
- 실시간 라이선스 만료 알림 배지
|
||||
- 한국어 기반 메뉴 구조
|
||||
|
||||
**화면 라우팅**:
|
||||
```dart
|
||||
Routes.home → OverviewScreen (대시보드)
|
||||
Routes.equipment → EquipmentList (장비 관리)
|
||||
Routes.company → CompanyList (회사 관리)
|
||||
Routes.user → UserList (사용자 관리)
|
||||
Routes.license → LicenseList (유지보수 관리)
|
||||
Routes.warehouseLocation → WarehouseLocationList (입고지 관리)
|
||||
```
|
||||
|
||||
### 🔧 **장비 관리 화면 (EquipmentList)**
|
||||
**파일**: `/lib/screens/equipment/equipment_list.dart`
|
||||
**컨트롤러**: `/lib/screens/equipment/controllers/equipment_list_controller.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- 입고(IN)/출고(OUT)/대여(RENT) 상태별 필터링
|
||||
- 반응형 컬럼 표시 (900px 기준)
|
||||
- 다중 선택 및 일괄 처리
|
||||
- 페이지네이션 (10개씩 고정)
|
||||
- 실시간 검색 및 상태 필터
|
||||
|
||||
**상태 관리**:
|
||||
```dart
|
||||
class EquipmentListController extends BaseListController<UnifiedEquipment> {
|
||||
- selectedEquipmentIds: Set<String> // 선택된 장비 IDs
|
||||
- statusFilter: String? // 상태 필터
|
||||
- categoryFilter: String? // 카테고리 필터
|
||||
- includeInactive: bool // 비활성 포함 여부
|
||||
}
|
||||
```
|
||||
|
||||
**관련 폼 화면**:
|
||||
- `equipment_in_form.dart` - 장비 입고 등록
|
||||
- `equipment_out_form.dart` - 장비 출고 처리
|
||||
|
||||
### 🏢 **회사 관리 화면 (CompanyList)**
|
||||
**파일**: `/lib/screens/company/company_list.dart`
|
||||
**컨트롤러**: `/lib/screens/company/controllers/company_list_controller.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- 회사 + 지점 계층 구조 관리
|
||||
- 파트너사/고객사 구분 표시
|
||||
- 활성/비활성 상태 토글
|
||||
- 주소 검색 통합 (Daum API 예정)
|
||||
|
||||
**관련 폼 화면**:
|
||||
- `company_form.dart` - 회사 등록/수정
|
||||
- `branch_form.dart` - 지점 등록/수정
|
||||
|
||||
### 📄 **라이선스 관리 화면 (LicenseList)**
|
||||
**파일**: `/lib/screens/license/license_list.dart`
|
||||
**컨트롤러**: `/lib/screens/license/controllers/license_list_controller.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- 만료일 기준 자동 정렬
|
||||
- 7일/30일/90일 만료 예정 필터
|
||||
- 라이선스 연장 처리
|
||||
- 만료 알림 시스템
|
||||
|
||||
**관련 폼 화면**:
|
||||
- `license_form.dart` - 라이선스 등록/수정 (MaintenanceFormScreen으로 사용)
|
||||
|
||||
### 👥 **사용자 관리 화면 (UserList)**
|
||||
**파일**: `/lib/screens/user/user_list.dart`
|
||||
**컨트롤러**: `/lib/screens/user/controllers/user_list_controller.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- 역할별 사용자 관리 (admin/manager/member)
|
||||
- 사용자명 중복 검증
|
||||
- 비밀번호 리셋 기능
|
||||
|
||||
### 📦 **입고지 관리 화면 (WarehouseLocationList)**
|
||||
**파일**: `/lib/screens/warehouse_location/warehouse_location_list.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- 창고 위치별 재고 관리
|
||||
- 주소 기반 위치 설정
|
||||
|
||||
### 📊 **대시보드 화면 (OverviewScreen)**
|
||||
**파일**: `/lib/screens/overview/overview_screen.dart`
|
||||
**컨트롤러**: `/lib/screens/overview/controllers/overview_controller.dart`
|
||||
|
||||
**주요 기능**:
|
||||
- 실시간 KPI 카드 표시
|
||||
- 라이선스 만료 예정 알림
|
||||
- 장비 상태 분포 차트
|
||||
- 최근 활동 피드
|
||||
|
||||
---
|
||||
|
||||
## 🎯 3. 폼 컴포넌트 및 검증 로직
|
||||
|
||||
### 📝 **표준 폼 구조**
|
||||
모든 폼은 다음 패턴을 따릅니다:
|
||||
|
||||
```dart
|
||||
// 1. 폼 스크린 클래스
|
||||
class [Entity]FormScreen extends StatefulWidget
|
||||
|
||||
// 2. Provider 기반 컨트롤러
|
||||
class [Entity]FormController extends ChangeNotifier
|
||||
|
||||
// 3. 검증 로직
|
||||
- 실시간 검증 (500ms debounce)
|
||||
- 저장 전 최종 검증
|
||||
- 서버 사이드 검증 연동
|
||||
```
|
||||
|
||||
### 🔧 **주요 입력 컴포넌트**
|
||||
|
||||
#### **장비 입고 폼 (equipment_in_form.dart)**
|
||||
```dart
|
||||
주요 필드:
|
||||
- 장비명: AutocompleteTextField (Lookup API 연동)
|
||||
- 제조사: CategoryAutocompleteField
|
||||
- 시리얼 번호: 실시간 중복 검증
|
||||
- 구매일: DatePickerField
|
||||
- 구매가격: 숫자 형식 자동 변환
|
||||
- 바코드: 스캔 기능 지원 예정
|
||||
```
|
||||
|
||||
#### **회사 등록 폼 (company_form.dart)**
|
||||
```dart
|
||||
주요 필드:
|
||||
- 회사명: 실시간 중복 검증
|
||||
- 주소: Daum 주소 API 연동 예정
|
||||
- 연락처: 전화번호 자동 포맷팅
|
||||
- 이메일: 형식 검증
|
||||
- 회사 유형: 파트너사/고객사 체크박스
|
||||
```
|
||||
|
||||
#### **라이선스 등록 폼 (license_form.dart)**
|
||||
```dart
|
||||
주요 필드:
|
||||
- 라이선스 키: 고유값 검증
|
||||
- 제품명: 자동완성 지원
|
||||
- 구매일/만료일: DatePicker
|
||||
- 사용자 수: 숫자 입력
|
||||
- 담당자: 사용자 드롭다운
|
||||
```
|
||||
|
||||
### ✅ **검증 규칙**
|
||||
**파일**: `/lib/core/utils/validators.dart`
|
||||
|
||||
```dart
|
||||
- 필수 항목 검증
|
||||
- 이메일 형식 검증
|
||||
- 전화번호 형식 검증
|
||||
- 날짜 범위 검증
|
||||
- 최대/최소 길이 검증
|
||||
- 숫자 범위 검증
|
||||
- 정규표현식 기반 검증
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 4. UI 컴포넌트 카탈로그
|
||||
|
||||
### 🧩 **재사용 가능한 위젯**
|
||||
|
||||
#### **공통 레이아웃 컴포넌트**
|
||||
**디렉토리**: `/lib/screens/common/widgets/`
|
||||
|
||||
```dart
|
||||
// 1. 데이터 테이블
|
||||
standard_data_table.dart
|
||||
- 정렬 가능한 컬럼
|
||||
- 다중 선택 지원
|
||||
- 페이지네이션 연동
|
||||
- 반응형 컬럼 숨김/표시
|
||||
|
||||
// 2. 액션 바
|
||||
standard_action_bar.dart
|
||||
- 검색 입력 필드
|
||||
- 필터 드롭다운
|
||||
- 추가/수정/삭제 버튼
|
||||
- 엑셀 내보내기 버튼
|
||||
|
||||
// 3. 페이지네이션
|
||||
pagination.dart
|
||||
- 이전/다음 버튼
|
||||
- 페이지 번호 표시
|
||||
- 페이지 크기 선택
|
||||
|
||||
// 4. 상태 표시
|
||||
standard_states.dart
|
||||
- 로딩 스피너
|
||||
- 에러 메시지
|
||||
- 빈 상태 표시
|
||||
```
|
||||
|
||||
#### **폼 전용 컴포넌트**
|
||||
**디렉토리**: `/lib/screens/common/custom_widgets/`
|
||||
|
||||
```dart
|
||||
// 1. 자동완성 드롭다운
|
||||
autocomplete_dropdown.dart
|
||||
- API 기반 검색
|
||||
- 키보드 네비게이션
|
||||
- 최근 검색어 캐시
|
||||
|
||||
// 2. 카테고리 선택
|
||||
category_selection_field.dart
|
||||
- 3단계 카테고리 선택
|
||||
- 상위 카테고리 변경 시 하위 초기화
|
||||
|
||||
// 3. 날짜 선택기
|
||||
date_picker_field.dart
|
||||
- 한국어 로케일
|
||||
- 최소/최대 날짜 제한
|
||||
- 달력 팝업
|
||||
|
||||
// 4. 주소 입력
|
||||
address_input.dart
|
||||
- Daum 주소 검색 API 연동 준비
|
||||
- 우편번호/기본주소/상세주소 분리
|
||||
```
|
||||
|
||||
#### **ShadCN UI 통합**
|
||||
**파일**: `/lib/screens/common/theme_shadcn.dart`
|
||||
|
||||
```dart
|
||||
현재 구현된 컴포넌트:
|
||||
- ShadcnButton (Primary/Secondary/Outline/Ghost)
|
||||
- ShadcnCard (Shadow, Border 스타일)
|
||||
- ShadcnBadge (Primary/Secondary/Destructive)
|
||||
- ShadcnAvatar (이니셜 기반)
|
||||
- ShadcnSeparator (수평/수직)
|
||||
|
||||
부분 구현:
|
||||
- ShadcnInput (기본 텍스트 입력만)
|
||||
- ShadcnSelect (단순 드롭다운만)
|
||||
|
||||
미구현 (ShadCN UI 마이그레이션 필요):
|
||||
- ShadcnTable
|
||||
- ShadcnDialog
|
||||
- ShadcnSheet
|
||||
- ShadcnTabs
|
||||
- ShadcnDatePicker
|
||||
- ShadcnCheckbox
|
||||
- ShadcnRadio
|
||||
- ShadcnProgress
|
||||
- ShadcnAlert
|
||||
- ShadcnToast
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ 5. 상태 관리 아키텍처
|
||||
|
||||
### 🎛️ **Provider 패턴 기반**
|
||||
|
||||
#### **BaseListController 추상화**
|
||||
**파일**: `/lib/core/controllers/base_list_controller.dart`
|
||||
|
||||
```dart
|
||||
abstract class BaseListController<T> extends ChangeNotifier {
|
||||
// 공통 상태
|
||||
- items: List<T>
|
||||
- isLoading: bool
|
||||
- error: String?
|
||||
- pagination: PaginationMeta
|
||||
|
||||
// 공통 메서드
|
||||
- loadData({bool isRefresh = false})
|
||||
- search(String keyword)
|
||||
- applyFilters(Map<String, dynamic> filters)
|
||||
- selectItem(T item)
|
||||
- selectAll()
|
||||
- clearSelection()
|
||||
}
|
||||
```
|
||||
|
||||
#### **구체적인 컨트롤러들**
|
||||
|
||||
```dart
|
||||
// 장비 목록 컨트롤러
|
||||
EquipmentListController extends BaseListController<UnifiedEquipment>
|
||||
- selectedEquipmentIds: Set<String>
|
||||
- statusFilter: String?
|
||||
- categoryFilter: String?
|
||||
- includeInactive: bool
|
||||
|
||||
// 회사 목록 컨트롤러
|
||||
CompanyListController extends BaseListController<CompanyModel>
|
||||
- selectedCompanyTypes: List<String>
|
||||
- isPartnerFilter: bool?
|
||||
- isCustomerFilter: bool?
|
||||
|
||||
// 라이선스 목록 컨트롤러
|
||||
LicenseListController extends BaseListController<LicenseDto>
|
||||
- expiryDateFilter: DateRange?
|
||||
- vendorFilter: String?
|
||||
- assignedUserFilter: int?
|
||||
```
|
||||
|
||||
### 📊 **폼 컨트롤러 패턴**
|
||||
|
||||
```dart
|
||||
// 공통 폼 상태 관리
|
||||
class [Entity]FormController extends ChangeNotifier {
|
||||
// 폼 상태
|
||||
- isLoading: bool
|
||||
- isEditing: bool
|
||||
- validationErrors: Map<String, String>
|
||||
|
||||
// 폼 데이터
|
||||
- [entity]: [Entity]Model?
|
||||
- formKey: GlobalKey<FormState>
|
||||
|
||||
// 비즈니스 로직
|
||||
- validateField(String field, dynamic value)
|
||||
- save()
|
||||
- reset()
|
||||
- dispose()
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 6. API 통합 패턴
|
||||
|
||||
### 🌐 **현재 API 구조**
|
||||
|
||||
#### **Data Sources (Retrofit 기반)**
|
||||
**디렉토리**: `/lib/data/datasources/remote/`
|
||||
|
||||
```dart
|
||||
// API 클라이언트들
|
||||
auth_remote_datasource.dart - 인증 관련 API
|
||||
company_remote_datasource.dart - 회사 관리 API
|
||||
equipment_remote_datasource.dart - 장비 관리 API
|
||||
license_remote_datasource.dart - 라이선스 관리 API
|
||||
lookup_remote_datasource.dart - 룩업 데이터 API
|
||||
user_remote_datasource.dart - 사용자 관리 API
|
||||
warehouse_remote_datasource.dart - 창고 관리 API
|
||||
```
|
||||
|
||||
#### **Repository 구현체**
|
||||
**디렉토리**: `/lib/data/repositories/`
|
||||
|
||||
```dart
|
||||
// Clean Architecture Repository 패턴
|
||||
[Entity]RepositoryImpl implements [Entity]Repository {
|
||||
- remoteDataSource: [Entity]RemoteDataSource
|
||||
|
||||
메서드:
|
||||
- get[Entity]s(params) -> Either<Failure, List<[Entity]>>
|
||||
- get[Entity](id) -> Either<Failure, [Entity]>
|
||||
- create[Entity](data) -> Either<Failure, [Entity]>
|
||||
- update[Entity](id, data) -> Either<Failure, [Entity]>
|
||||
- delete[Entity](id) -> Either<Failure, void>
|
||||
}
|
||||
```
|
||||
|
||||
#### **UseCase 레이어**
|
||||
**디렉토리**: `/lib/domain/usecases/`
|
||||
|
||||
```dart
|
||||
// 비즈니스 로직 캡슐화
|
||||
class Get[Entity]sUseCase {
|
||||
- repository: [Entity]Repository
|
||||
|
||||
Future<Either<Failure, List<[Entity]>>> call(params) async {
|
||||
return await repository.get[Entity]s(params);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🏗️ **서비스 레이어 (레거시)**
|
||||
**디렉토리**: `/lib/services/`
|
||||
|
||||
```dart
|
||||
현재 혼재 상태:
|
||||
✅ Repository 패턴으로 마이그레이션 완료:
|
||||
- AuthRepository
|
||||
- UserRepository
|
||||
- LicenseRepository
|
||||
- WarehouseLocationRepository
|
||||
|
||||
🔄 마이그레이션 진행 중:
|
||||
- CompanyService → CompanyRepository
|
||||
- EquipmentService → EquipmentRepository
|
||||
|
||||
📋 마이그레이션 대기:
|
||||
- DashboardService
|
||||
- LookupsService
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 7. 데이터 모델 구조 분석
|
||||
|
||||
### 🏷️ **현재 DTO 모델들**
|
||||
|
||||
#### **Equipment 관련**
|
||||
```dart
|
||||
// 현재 구조 (백엔드 불일치)
|
||||
EquipmentDto {
|
||||
id: int
|
||||
equipmentNumber: String
|
||||
serialNumber: String?
|
||||
category1: String? // ❌ 백엔드에 없음
|
||||
category2: String? // ❌ 백엔드에 없음
|
||||
category3: String? // ❌ 백엔드에 없음
|
||||
manufacturer: String
|
||||
modelName: String?
|
||||
status: String
|
||||
companyId: int?
|
||||
warehouseLocationId: int?
|
||||
purchaseDate: String?
|
||||
purchasePrice: double?
|
||||
}
|
||||
|
||||
// 필요한 구조 (백엔드 매칭)
|
||||
EquipmentDto {
|
||||
id: int
|
||||
companiesId: int // 🚨 현재: companyId
|
||||
modelsId: int // 🚨 누락: models 테이블 FK
|
||||
serialNumber: String // UNIQUE 제약
|
||||
barcode: String? // UNIQUE 제약
|
||||
purchasedAt: DateTime
|
||||
purchasePrice: int
|
||||
warrantyNumber: String
|
||||
warrantyStartedAt: DateTime
|
||||
warrantyEndedAt: DateTime
|
||||
remark: String?
|
||||
isDeleted: bool
|
||||
registeredAt: DateTime
|
||||
updatedAt: DateTime?
|
||||
}
|
||||
```
|
||||
|
||||
#### **Company 관련**
|
||||
```dart
|
||||
// 현재 구조
|
||||
CompanyResponse {
|
||||
id: int
|
||||
name: String
|
||||
address: String?
|
||||
contactName: String
|
||||
contactPhone: String
|
||||
contactEmail: String
|
||||
isPartner: bool
|
||||
isCustomer: bool
|
||||
parentCompanyId: int? // ✅ 계층 구조 지원
|
||||
}
|
||||
|
||||
// 백엔드 매칭 필요 사항
|
||||
CompanyEntity {
|
||||
zipcodeZipcode: String // 🚨 누락: zipcodes FK
|
||||
address: String
|
||||
isActive: bool // 🚨 누락: 활성화 상태
|
||||
}
|
||||
```
|
||||
|
||||
#### **License 관련 (완전 재설계 필요)**
|
||||
```dart
|
||||
// 현재 구조 (독립 엔티티)
|
||||
LicenseDto {
|
||||
id: int
|
||||
licenseKey: String
|
||||
productName: String?
|
||||
vendor: String?
|
||||
expiryDate: DateTime?
|
||||
companyId: int?
|
||||
assignedUserId: int?
|
||||
}
|
||||
|
||||
// 백엔드 실제 구조 (maintenances 테이블)
|
||||
MaintenanceEntity {
|
||||
id: int
|
||||
equipmentHistoryId: int // 🚨 완전히 다른 구조
|
||||
startedAt: DateTime
|
||||
endedAt: DateTime
|
||||
periodMonth: int // 방문 주기
|
||||
maintenanceType: String // 'O'(방문) | 'R'(원격)
|
||||
isDeleted: bool
|
||||
registeredAt: DateTime
|
||||
updatedAt: DateTime?
|
||||
}
|
||||
```
|
||||
|
||||
### 🆔 **누락된 핵심 엔티티들**
|
||||
|
||||
```dart
|
||||
// 1. 제조사 (vendors) - 완전히 누락
|
||||
VendorEntity {
|
||||
id: int
|
||||
name: String // UNIQUE
|
||||
isDeleted: bool
|
||||
registeredAt: DateTime
|
||||
updatedAt: DateTime?
|
||||
}
|
||||
|
||||
// 2. 모델명 (models) - 완전히 누락
|
||||
ModelEntity {
|
||||
id: int
|
||||
name: String // UNIQUE
|
||||
vendorsId: int // FK to vendors
|
||||
isDeleted: bool
|
||||
registeredAt: DateTime
|
||||
updatedAt: DateTime?
|
||||
}
|
||||
|
||||
// 3. 장비이력 (equipment_history) - 핵심 누락
|
||||
EquipmentHistoryEntity {
|
||||
id: int
|
||||
equipmentsId: int // FK to equipments
|
||||
warehousesId: int // FK to warehouses
|
||||
transactionType: String // 'I'(입고) | 'O'(출고)
|
||||
quantity: int
|
||||
transactedAt: DateTime
|
||||
remark: String?
|
||||
isDeleted: DateTime // 🚨 DATETIME 타입
|
||||
createdAt: DateTime
|
||||
updatedAt: DateTime?
|
||||
}
|
||||
|
||||
// 4. 임대상세 (rents) - 완전히 누락
|
||||
RentEntity {
|
||||
id: int
|
||||
startedAt: DateTime
|
||||
endedAt: DateTime
|
||||
equipmentHistoryId: int // FK to equipment_history
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 8. 아키텍처 문제점 및 개선 필요사항
|
||||
|
||||
### ❌ **현재 문제점**
|
||||
|
||||
#### **1. API 스키마 불일치 (Critical)**
|
||||
```yaml
|
||||
심각도: 🔴 Critical
|
||||
영향도: 전체 시스템
|
||||
문제:
|
||||
- Equipment: category1/2/3 필드가 백엔드에 없음
|
||||
- License: 완전히 다른 테이블 구조 (maintenances)
|
||||
- 핵심 엔티티 6개 완전 누락 (vendors, models, equipment_history 등)
|
||||
- FK 관계 불일치 (companyId vs companiesId)
|
||||
```
|
||||
|
||||
#### **2. 혼재된 아키텍처 패턴**
|
||||
```yaml
|
||||
심각도: 🟡 Medium
|
||||
영향도: 유지보수성
|
||||
문제:
|
||||
- Service Layer와 Repository Pattern 혼재
|
||||
- Legacy 모델과 DTO 모델 중복 존재
|
||||
- UseCase 일부만 구현 (일관성 부족)
|
||||
```
|
||||
|
||||
#### **3. UI 컴포넌트 파편화**
|
||||
```yaml
|
||||
심각도: 🟡 Medium
|
||||
영향도: 사용자 경험
|
||||
문제:
|
||||
- ShadCN UI 부분 구현 상태
|
||||
- 커스텀 위젯과 표준 위젯 혼재
|
||||
- 일관되지 않은 디자인 시스템
|
||||
```
|
||||
|
||||
### ✅ **잘 구현된 부분**
|
||||
|
||||
#### **1. Clean Architecture 기반 구조**
|
||||
```yaml
|
||||
✅ 레이어 분리 명확
|
||||
✅ 의존성 주입 (GetIt) 잘 설정됨
|
||||
✅ Freezed 기반 불변 객체 사용
|
||||
✅ Provider 기반 상태 관리
|
||||
```
|
||||
|
||||
#### **2. 에러 처리 및 검증**
|
||||
```yaml
|
||||
✅ ErrorHandler 중앙화
|
||||
✅ 실시간 폼 검증
|
||||
✅ API 인터셉터 구조
|
||||
✅ 보안 저장소 (SecureStorage)
|
||||
```
|
||||
|
||||
#### **3. 반응형 레이아웃**
|
||||
```yaml
|
||||
✅ 브레이크포인트 기반 레이아웃
|
||||
✅ 접이식 사이드바
|
||||
✅ 모바일 최적화 고려
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 9. 마이그레이션 우선순위
|
||||
|
||||
### 🔥 **Phase 1: API 스키마 동기화 (Critical)**
|
||||
```yaml
|
||||
1. 누락 엔티티 DTO 생성:
|
||||
- VendorDto + Repository + UseCase
|
||||
- ModelDto + Repository + UseCase
|
||||
- EquipmentHistoryDto + Repository + UseCase
|
||||
- MaintenanceHistoryDto + Repository + UseCase (License 대체)
|
||||
- RentDto + Repository + UseCase
|
||||
|
||||
2. 기존 DTO 수정:
|
||||
- EquipmentDto: modelsId 추가, category1/2/3 제거
|
||||
- CompanyDto: zipcodeZipcode, isActive 추가
|
||||
|
||||
3. Service → Repository 마이그레이션:
|
||||
- CompanyService → CompanyRepository
|
||||
- EquipmentService → EquipmentRepository
|
||||
```
|
||||
|
||||
### 🎨 **Phase 2: ShadCN UI 통합**
|
||||
```yaml
|
||||
1. 완전한 ShadCN 컴포넌트 구현:
|
||||
- ShadInput, ShadSelect, ShadDatePicker
|
||||
- ShadTable, ShadDialog, ShadSheet
|
||||
- ShadTabs, ShadCheckbox, ShadProgress
|
||||
|
||||
2. 기존 커스텀 위젯을 ShadCN으로 교체:
|
||||
- standard_data_table.dart → ShadTable
|
||||
- 모든 폼 입력 필드 → Shad 컴포넌트
|
||||
|
||||
3. 통일된 디자인 토큰:
|
||||
- 색상, 타이포그래피, 간격 표준화
|
||||
```
|
||||
|
||||
### ⚡ **Phase 3: 기능 완성**
|
||||
```yaml
|
||||
1. Equipment History & Rent 시스템:
|
||||
- 장비 라이프사이클 완전 추적
|
||||
- 입고 → 출고 → 대여 → 반납 흐름
|
||||
|
||||
2. Maintenance 시스템 (License 대체):
|
||||
- Equipment History 기반 유지보수 관리
|
||||
- 주기별 점검 스케줄링
|
||||
|
||||
3. Company 계층 구조:
|
||||
- 본사-지점 트리 뷰
|
||||
- 계층별 권한 관리
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 10. 성능 및 최적화 현황
|
||||
|
||||
### ✅ **현재 잘 구현된 부분**
|
||||
- **페이지네이션**: 모든 리스트 10개씩 고정
|
||||
- **검색 디바운싱**: 500ms 지연 후 API 호출
|
||||
- **캐싱**: LookupsService에서 30분 캐시
|
||||
- **인터셉터**: 로그인, 에러 처리 자동화
|
||||
|
||||
### 🔄 **개선 필요사항**
|
||||
- **가상화 스크롤**: 대용량 데이터 처리
|
||||
- **이미지 최적화**: 바코드/QR코드 캐싱
|
||||
- **오프라인 지원**: 핵심 데이터 로컬 저장
|
||||
- **번들 크기**: Tree shaking 및 코드 분할
|
||||
|
||||
---
|
||||
|
||||
## 🎯 11. 마이그레이션 실행 계획
|
||||
|
||||
### **Week 1**: API 스키마 동기화
|
||||
- Day 1-2: 누락 엔티티 DTO/Repository 생성
|
||||
- Day 3-4: 기존 DTO 수정 및 API 통합 테스트
|
||||
- Day 5-7: Equipment 화면 완전 재구현
|
||||
|
||||
### **Week 2**: ShadCN UI 통합
|
||||
- Day 8-10: ShadCN 컴포넌트 완전 구현
|
||||
- Day 11-12: 기존 화면들을 ShadCN으로 마이그레이션
|
||||
- Day 13-14: 반응형 레이아웃 완성
|
||||
|
||||
### **Week 3**: 기능 완성 및 최적화
|
||||
- Day 15-17: Equipment History & Maintenance 시스템
|
||||
- Day 18-19: 성능 최적화 및 테스트
|
||||
- Day 20-21: 배포 준비 및 문서 업데이트
|
||||
|
||||
---
|
||||
|
||||
## 📋 12. 결론 및 권장사항
|
||||
|
||||
### **🎯 핵심 발견사항**
|
||||
1. **Clean Architecture 기반이 잘 구축되어 있어 마이그레이션 기반은 탄탄함**
|
||||
2. **백엔드 API와 심각한 스키마 불일치 발견 (즉시 해결 필요)**
|
||||
3. **ShadCN UI 부분 구현으로 일관성 있는 디자인 시스템 필요**
|
||||
4. **핵심 기능 90% 구현되어 있으나 백엔드 매칭 시 대폭 수정 필요**
|
||||
|
||||
### **🚀 권장 실행 전략**
|
||||
1. **Phase 1 우선 집중**: API 스키마 불일치 해결이 최우선
|
||||
2. **점진적 마이그레이션**: 화면별 단계적 ShadCN 적용
|
||||
3. **테스트 주도 개발**: 각 단계마다 철저한 API 통합 테스트
|
||||
4. **성능 모니터링**: 마이그레이션 과정에서 성능 저하 방지
|
||||
|
||||
**예상 소요 기간**: 3주 (21일)
|
||||
**성공 가능성**: 85% (체계적인 기반 구조 덕분)
|
||||
**위험 요소**: 백엔드 API 의존성, 복잡한 Equipment History 로직
|
||||
|
||||
---
|
||||
|
||||
**📝 문서 작성자**: Claude (Research Agent)
|
||||
**📅 작성 일자**: 2025-08-23
|
||||
**🔍 분석 범위**: /Users/maximilian.j.sul/Documents/flutter/superport/lib/ 전체
|
||||
**📊 총 분석 파일**: 200+ 파일
|
||||
Reference in New Issue
Block a user