## 주요 변경사항 ### 🏗️ Architecture - Repository 패턴 전면 도입 (인터페이스/구현체 분리) - Domain Layer에 Repository 인터페이스 정의 - Data Layer에 Repository 구현체 배치 - UseCase 의존성을 Service에서 Repository로 전환 ### 📦 Dependency Injection - GetIt 기반 DI Container 재구성 (lib/injection_container.dart) - Repository 인터페이스와 구현체 등록 - Service와 Repository 공존 (마이그레이션 기간) ### 🔄 Migration Status 완료: - License 모듈 (6개 UseCase) - Warehouse Location 모듈 (5개 UseCase) 진행중: - Auth 모듈 (2/5 UseCase) - Company 모듈 (1/6 UseCase) 대기: - User 모듈 (7개 UseCase) - Equipment 모듈 (4개 UseCase) ### 🎯 Controller 통합 - 중복 Controller 제거 (with_usecase 버전) - 단일 Controller로 통합 - UseCase 패턴 직접 적용 ### 🧹 코드 정리 - 임시 파일 제거 (test_*.md, task.md) - Node.js 아티팩트 제거 (package.json) - 불필요한 테스트 파일 정리 ### ✅ 테스트 개선 - Real API 중심 테스트 구조 - Mock 제거, 실제 API 엔드포인트 사용 - 통합 테스트 프레임워크 강화 ## 기술적 영향 - 의존성 역전 원칙 적용 - 레이어 간 결합도 감소 - 테스트 용이성 향상 - 확장성 및 유지보수성 개선 ## 다음 단계 1. User/Equipment 모듈 Repository 마이그레이션 2. Service Layer 점진적 제거 3. 캐싱 전략 구현 4. 성능 최적화
250 lines
12 KiB
Dart
250 lines
12 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:get_it/get_it.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
// Core
|
|
import 'core/storage/secure_storage.dart';
|
|
|
|
// Data Sources
|
|
import 'data/datasources/remote/api_client.dart';
|
|
import 'data/datasources/remote/auth_remote_datasource.dart';
|
|
import 'data/datasources/remote/company_remote_datasource.dart';
|
|
import 'data/datasources/remote/dashboard_remote_datasource.dart';
|
|
import 'data/datasources/remote/equipment_remote_datasource.dart';
|
|
import 'data/datasources/remote/license_remote_datasource.dart';
|
|
import 'data/datasources/remote/lookup_remote_datasource.dart';
|
|
import 'data/datasources/remote/user_remote_datasource.dart';
|
|
import 'data/datasources/remote/warehouse_location_remote_datasource.dart';
|
|
import 'data/datasources/remote/warehouse_remote_datasource.dart';
|
|
import 'data/datasources/interceptors/api_interceptor.dart';
|
|
|
|
// Repositories
|
|
import 'domain/repositories/auth_repository.dart';
|
|
import 'domain/repositories/company_repository.dart';
|
|
import 'domain/repositories/equipment_repository.dart';
|
|
import 'domain/repositories/license_repository.dart';
|
|
import 'domain/repositories/user_repository.dart';
|
|
import 'domain/repositories/warehouse_location_repository.dart';
|
|
import 'data/repositories/auth_repository_impl.dart';
|
|
import 'data/repositories/company_repository_impl.dart';
|
|
import 'data/repositories/equipment_repository_impl.dart';
|
|
import 'data/repositories/license_repository_impl.dart';
|
|
import 'data/repositories/user_repository_impl.dart';
|
|
import 'data/repositories/warehouse_location_repository_impl.dart';
|
|
|
|
// Use Cases - Auth
|
|
import 'domain/usecases/auth/login_usecase.dart';
|
|
import 'domain/usecases/auth/logout_usecase.dart';
|
|
import 'domain/usecases/auth/get_current_user_usecase.dart';
|
|
import 'domain/usecases/auth/check_auth_status_usecase.dart';
|
|
import 'domain/usecases/auth/refresh_token_usecase.dart';
|
|
|
|
// Use Cases - Company
|
|
import 'domain/usecases/company/get_companies_usecase.dart';
|
|
import 'domain/usecases/company/get_company_detail_usecase.dart';
|
|
import 'domain/usecases/company/create_company_usecase.dart';
|
|
import 'domain/usecases/company/update_company_usecase.dart';
|
|
import 'domain/usecases/company/delete_company_usecase.dart';
|
|
import 'domain/usecases/company/toggle_company_status_usecase.dart';
|
|
|
|
// Use Cases - User
|
|
import 'domain/usecases/user/get_users_usecase.dart';
|
|
import 'domain/usecases/user/get_user_detail_usecase.dart';
|
|
import 'domain/usecases/user/create_user_usecase.dart';
|
|
import 'domain/usecases/user/update_user_usecase.dart';
|
|
import 'domain/usecases/user/delete_user_usecase.dart';
|
|
import 'domain/usecases/user/toggle_user_status_usecase.dart';
|
|
import 'domain/usecases/user/reset_password_usecase.dart';
|
|
|
|
// Use Cases - Equipment
|
|
import 'domain/usecases/equipment/get_equipments_usecase.dart';
|
|
import 'domain/usecases/equipment/equipment_in_usecase.dart';
|
|
import 'domain/usecases/equipment/equipment_out_usecase.dart';
|
|
import 'domain/usecases/equipment/get_equipment_history_usecase.dart';
|
|
|
|
// Use Cases - License
|
|
import 'domain/usecases/license/get_licenses_usecase.dart';
|
|
import 'domain/usecases/license/get_license_detail_usecase.dart';
|
|
import 'domain/usecases/license/create_license_usecase.dart';
|
|
import 'domain/usecases/license/update_license_usecase.dart';
|
|
import 'domain/usecases/license/delete_license_usecase.dart';
|
|
import 'domain/usecases/license/check_license_expiry_usecase.dart';
|
|
|
|
// Use Cases - Warehouse Location
|
|
import 'domain/usecases/warehouse_location/get_warehouse_locations_usecase.dart';
|
|
import 'domain/usecases/warehouse_location/get_warehouse_location_detail_usecase.dart';
|
|
import 'domain/usecases/warehouse_location/create_warehouse_location_usecase.dart';
|
|
import 'domain/usecases/warehouse_location/update_warehouse_location_usecase.dart';
|
|
import 'domain/usecases/warehouse_location/delete_warehouse_location_usecase.dart';
|
|
|
|
// Services (기존 서비스들과의 호환성을 위해 유지)
|
|
import 'services/auth_service.dart';
|
|
import 'services/company_service.dart';
|
|
import 'services/dashboard_service.dart';
|
|
import 'services/equipment_service.dart';
|
|
import 'services/license_service.dart';
|
|
import 'services/lookup_service.dart';
|
|
import 'services/user_service.dart';
|
|
import 'services/warehouse_service.dart';
|
|
|
|
final sl = GetIt.instance;
|
|
|
|
Future<void> init() async {
|
|
// External
|
|
final sharedPreferences = await SharedPreferences.getInstance();
|
|
sl.registerLazySingleton(() => sharedPreferences);
|
|
|
|
// Core
|
|
sl.registerLazySingleton(() => SecureStorage());
|
|
sl.registerLazySingleton(() => const FlutterSecureStorage());
|
|
sl.registerLazySingleton(() => ApiInterceptor(sl()));
|
|
|
|
// API Client
|
|
sl.registerLazySingleton(() => ApiClient());
|
|
|
|
// Dio
|
|
sl.registerLazySingleton<Dio>(() {
|
|
final dio = Dio();
|
|
dio.options = BaseOptions(
|
|
baseUrl: 'http://43.201.34.104:8080/api/v1',
|
|
connectTimeout: const Duration(seconds: 30),
|
|
receiveTimeout: const Duration(seconds: 30),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
);
|
|
dio.interceptors.add(sl<ApiInterceptor>());
|
|
dio.interceptors.add(LogInterceptor(
|
|
requestBody: true,
|
|
responseBody: true,
|
|
));
|
|
return dio;
|
|
});
|
|
|
|
// Data Sources
|
|
sl.registerLazySingleton<AuthRemoteDataSource>(
|
|
() => AuthRemoteDataSourceImpl(sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<CompanyRemoteDataSource>(
|
|
() => CompanyRemoteDataSourceImpl(sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<DashboardRemoteDataSource>(
|
|
() => DashboardRemoteDataSourceImpl(sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<EquipmentRemoteDataSource>(
|
|
() => EquipmentRemoteDataSourceImpl(),
|
|
);
|
|
sl.registerLazySingleton<LicenseRemoteDataSource>(
|
|
() => LicenseRemoteDataSourceImpl(apiClient: sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<LookupRemoteDataSource>(
|
|
() => LookupRemoteDataSourceImpl(sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<UserRemoteDataSource>(
|
|
() => UserRemoteDataSourceImpl(sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<WarehouseLocationRemoteDataSource>(
|
|
() => WarehouseLocationRemoteDataSourceImpl(apiClient: sl<ApiClient>()),
|
|
);
|
|
sl.registerLazySingleton<WarehouseRemoteDataSource>(
|
|
() => WarehouseRemoteDataSourceImpl(apiClient: sl<ApiClient>()),
|
|
);
|
|
|
|
// Repositories
|
|
sl.registerLazySingleton<AuthRepository>(
|
|
() => AuthRepositoryImpl(
|
|
remoteDataSource: sl<AuthRemoteDataSource>(),
|
|
sharedPreferences: sl<SharedPreferences>(),
|
|
),
|
|
);
|
|
sl.registerLazySingleton<CompanyRepository>(
|
|
() => CompanyRepositoryImpl(remoteDataSource: sl<CompanyRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<EquipmentRepository>(
|
|
() => EquipmentRepositoryImpl(sl<EquipmentRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<LicenseRepository>(
|
|
() => LicenseRepositoryImpl(remoteDataSource: sl<LicenseRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<UserRepository>(
|
|
() => UserRepositoryImpl(remoteDataSource: sl<UserRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<WarehouseLocationRepository>(
|
|
() => WarehouseLocationRepositoryImpl(remoteDataSource: sl<WarehouseLocationRemoteDataSource>()),
|
|
);
|
|
|
|
// Use Cases - Auth
|
|
sl.registerLazySingleton(() => LoginUseCase(sl<AuthRepository>())); // Repository 사용
|
|
sl.registerLazySingleton(() => LogoutUseCase(sl<AuthService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => GetCurrentUserUseCase(sl<AuthService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => CheckAuthStatusUseCase(sl<AuthRepository>())); // Repository 사용
|
|
sl.registerLazySingleton(() => RefreshTokenUseCase(sl<AuthService>())); // Service 사용 (아직 미수정)
|
|
|
|
// Use Cases - Company
|
|
sl.registerLazySingleton(() => GetCompaniesUseCase(sl<CompanyRepository>())); // Repository 사용
|
|
sl.registerLazySingleton(() => GetCompanyDetailUseCase(sl<CompanyService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => CreateCompanyUseCase(sl<CompanyService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => UpdateCompanyUseCase(sl<CompanyService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => DeleteCompanyUseCase(sl<CompanyService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => ToggleCompanyStatusUseCase(sl<CompanyService>())); // Service 사용 (아직 미수정)
|
|
|
|
// Use Cases - User
|
|
sl.registerLazySingleton(() => GetUsersUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => GetUserDetailUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => CreateUserUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => UpdateUserUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => DeleteUserUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => ToggleUserStatusUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => ResetPasswordUseCase(sl<UserService>())); // Service 사용 (아직 미수정)
|
|
|
|
// Use Cases - Equipment
|
|
sl.registerLazySingleton(() => GetEquipmentsUseCase(sl<EquipmentService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => EquipmentInUseCase(sl<EquipmentService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => EquipmentOutUseCase(sl<EquipmentService>())); // Service 사용 (아직 미수정)
|
|
sl.registerLazySingleton(() => GetEquipmentHistoryUseCase(sl<EquipmentService>())); // Service 사용 (아직 미수정)
|
|
|
|
// Use Cases - License
|
|
sl.registerLazySingleton(() => GetLicensesUseCase(sl<LicenseRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => GetLicenseDetailUseCase(sl<LicenseRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => CreateLicenseUseCase(sl<LicenseRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => UpdateLicenseUseCase(sl<LicenseRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => DeleteLicenseUseCase(sl<LicenseRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => CheckLicenseExpiryUseCase(sl<LicenseRepository>())); // Repository 사용 (이미 구현됨)
|
|
|
|
// Use Cases - Warehouse Location
|
|
sl.registerLazySingleton(() => GetWarehouseLocationsUseCase(sl<WarehouseLocationRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => GetWarehouseLocationDetailUseCase(sl<WarehouseLocationRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => CreateWarehouseLocationUseCase(sl<WarehouseLocationRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => UpdateWarehouseLocationUseCase(sl<WarehouseLocationRepository>())); // Repository 사용 (이미 구현됨)
|
|
sl.registerLazySingleton(() => DeleteWarehouseLocationUseCase(sl<WarehouseLocationRepository>())); // Repository 사용 (이미 구현됨)
|
|
|
|
// Services (기존 서비스들과의 호환성을 위해 유지)
|
|
sl.registerLazySingleton<AuthService>(
|
|
() => AuthServiceImpl(
|
|
sl<AuthRemoteDataSource>(),
|
|
sl<FlutterSecureStorage>(),
|
|
),
|
|
);
|
|
sl.registerLazySingleton<CompanyService>(
|
|
() => CompanyService(sl<CompanyRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<DashboardService>(
|
|
() => DashboardServiceImpl(sl<DashboardRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<EquipmentService>(
|
|
() => EquipmentService(),
|
|
);
|
|
sl.registerLazySingleton<LicenseService>(
|
|
() => LicenseService(sl<LicenseRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<LookupService>(
|
|
() => LookupService(sl<LookupRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<UserService>(
|
|
() => UserService(sl<UserRemoteDataSource>()),
|
|
);
|
|
sl.registerLazySingleton<WarehouseService>(
|
|
() => WarehouseService(),
|
|
);
|
|
} |