Files
superport/.claude/research/codebase_structure_analysis.md

23 KiB

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)
  • 실시간 라이선스 만료 알림 배지
  • 한국어 기반 메뉴 구조

화면 라우팅:

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개씩 고정)
  • 실시간 검색 및 상태 필터

상태 관리:

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. 폼 컴포넌트 및 검증 로직

📝 표준 폼 구조

모든 폼은 다음 패턴을 따릅니다:

// 1. 폼 스크린 클래스
class [Entity]FormScreen extends StatefulWidget
  
// 2. Provider 기반 컨트롤러
class [Entity]FormController extends ChangeNotifier
  
// 3. 검증 로직
- 실시간 검증 (500ms debounce)
- 저장  최종 검증
- 서버 사이드 검증 연동

🔧 주요 입력 컴포넌트

장비 입고 폼 (equipment_in_form.dart)

주요 필드:
- 장비명: AutocompleteTextField (Lookup API 연동)
- 제조사: CategoryAutocompleteField
- 시리얼 번호: 실시간 중복 검증
- 구매일: DatePickerField
- 구매가격: 숫자 형식 자동 변환
- 바코드: 스캔 기능 지원 예정

회사 등록 폼 (company_form.dart)

주요 필드:
- 회사명: 실시간 중복 검증
- 주소: Daum 주소 API 연동 예정
- 연락처: 전화번호 자동 포맷팅
- 이메일: 형식 검증
- 회사 유형: 파트너사/고객사 체크박스

라이선스 등록 폼 (license_form.dart)

주요 필드:
- 라이선스 : 고유값 검증
- 제품명: 자동완성 지원
- 구매일/만료일: DatePicker
- 사용자 : 숫자 입력
- 담당자: 사용자 드롭다운

검증 규칙

파일: /lib/core/utils/validators.dart

- 필수 항목 검증
- 이메일 형식 검증
- 전화번호 형식 검증
- 날짜 범위 검증
- 최대/최소 길이 검증
- 숫자 범위 검증
- 정규표현식 기반 검증

🎨 4. UI 컴포넌트 카탈로그

🧩 재사용 가능한 위젯

공통 레이아웃 컴포넌트

디렉토리: /lib/screens/common/widgets/

// 1. 데이터 테이블
standard_data_table.dart
- 정렬 가능한 컬럼
- 다중 선택 지원
- 페이지네이션 연동
- 반응형 컬럼 숨김/표시

// 2. 액션 바
standard_action_bar.dart  
- 검색 입력 필드
- 필터 드롭다운
- 추가/수정/삭제 버튼
- 엑셀 내보내기 버튼

// 3. 페이지네이션
pagination.dart
- 이전/다음 버튼
- 페이지 번호 표시
- 페이지 크기 선택

// 4. 상태 표시
standard_states.dart
- 로딩 스피너
- 에러 메시지
-  상태 표시

폼 전용 컴포넌트

디렉토리: /lib/screens/common/custom_widgets/

// 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

현재 구현된 컴포넌트:
- 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

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()
}

구체적인 컨트롤러들

// 장비 목록 컨트롤러
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?

📊 폼 컨트롤러 패턴

// 공통 폼 상태 관리
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/

// 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/

// 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/

// 비즈니스 로직 캡슐화
class Get[Entity]sUseCase {
  - repository: [Entity]Repository
  
  Future<Either<Failure, List<[Entity]>>> call(params) async {
    return await repository.get[Entity]s(params);
  }
}

🏗️ 서비스 레이어 (레거시)

디렉토리: /lib/services/

현재 혼재 상태:
 Repository 패턴으로 마이그레이션 완료:
- AuthRepository
- UserRepository  
- LicenseRepository
- WarehouseLocationRepository

🔄 마이그레이션 진행 :
- CompanyService  CompanyRepository
- EquipmentService  EquipmentRepository  

📋 마이그레이션 대기:
- DashboardService
- LookupsService

📊 7. 데이터 모델 구조 분석

🏷️ 현재 DTO 모델들

Equipment 관련

// 현재 구조 (백엔드 불일치)
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 관련

// 현재 구조
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 관련 (완전 재설계 필요)

// 현재 구조 (독립 엔티티)
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?
}

🆔 누락된 핵심 엔티티들

// 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)

심각도: 🔴 Critical
영향도: 전체 시스템
문제:
  - Equipment: category1/2/3 필드가 백엔드에 없음
  - License: 완전히 다른 테이블 구조 (maintenances)
  - 핵심 엔티티 6개 완전 누락 (vendors, models, equipment_history 등)
  - FK 관계 불일치 (companyId vs companiesId)

2. 혼재된 아키텍처 패턴

심각도: 🟡 Medium  
영향도: 유지보수성
문제:
  - Service Layer와 Repository Pattern 혼재
  - Legacy 모델과 DTO 모델 중복 존재
  - UseCase 일부만 구현 (일관성 부족)

3. UI 컴포넌트 파편화

심각도: 🟡 Medium
영향도: 사용자 경험  
문제:
  - ShadCN UI 부분 구현 상태
  - 커스텀 위젯과 표준 위젯 혼재
  - 일관되지 않은 디자인 시스템

잘 구현된 부분

1. Clean Architecture 기반 구조

✅ 레이어 분리 명확
✅ 의존성 주입 (GetIt) 잘 설정됨
✅ Freezed 기반 불변 객체 사용
✅ Provider 기반 상태 관리

2. 에러 처리 및 검증

✅ ErrorHandler 중앙화
✅ 실시간 폼 검증
✅ API 인터셉터 구조
✅ 보안 저장소 (SecureStorage)

3. 반응형 레이아웃

✅ 브레이크포인트 기반 레이아웃
✅ 접이식 사이드바
✅ 모바일 최적화 고려

🚀 9. 마이그레이션 우선순위

🔥 Phase 1: API 스키마 동기화 (Critical)

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 통합

1. 완전한 ShadCN 컴포넌트 구현:
   - ShadInput, ShadSelect, ShadDatePicker
   - ShadTable, ShadDialog, ShadSheet
   - ShadTabs, ShadCheckbox, ShadProgress

2. 기존 커스텀 위젯을 ShadCN으로 교체:
   - standard_data_table.dart → ShadTable
   - 모든 폼 입력 필드 → Shad 컴포넌트

3. 통일된 디자인 토큰:
   - 색상, 타이포그래피, 간격 표준화

Phase 3: 기능 완성

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+ 파일