import 'package:injectable/injectable.dart'; import 'package:superport/data/models/maintenance_stats_dto.dart'; import 'package:superport/data/repositories/maintenance_stats_repository.dart'; @lazySingleton class GetMaintenanceStatsUseCase { final MaintenanceStatsRepository _repository; GetMaintenanceStatsUseCase({ required MaintenanceStatsRepository repository, }) : _repository = repository; /// 유지보수 대시보드 통계 조회 /// 60일내, 30일내, 7일내, 만료된 계약 통계를 포함한 종합 대시보드 데이터 Future getMaintenanceStats() async { try { final stats = await _repository.getMaintenanceStats(); // 비즈니스 검증: 통계 데이터 무결성 확인 _validateStatsData(stats); return stats; } catch (e) { // 통계 조회 실패시 기본값 반환 (UX 개선) return const MaintenanceStatsDto( updatedAt: null, // 실패 상태 표시를 위해 null ); } } /// 특정 기간 내 만료 예정 계약 수 조회 /// [days]: 조회할 기간 (일 단위) /// 사용자 요구사항: 60일, 30일, 7일 통계 제공 Future getExpiringContractsCount({required int days}) async { // 입력값 검증 if (days <= 0) { throw ArgumentError('조회 기간은 1일 이상이어야 합니다.'); } if (days > 365) { throw ArgumentError('조회 기간은 365일 이하여야 합니다.'); } return await _repository.getExpiringContractsCount(days: days); } /// 계약 타입별 통계 조회 /// WARRANTY, CONTRACT, INSPECTION 별 계약 수 반환 Future> getContractsByType() async { final contractsByType = await _repository.getContractsByType(); // 빈 결과 처리 if (contractsByType.isEmpty) { return { 'WARRANTY': 0, 'CONTRACT': 0, 'INSPECTION': 0, }; } return contractsByType; } /// 만료된 계약 수 조회 (즉시 조치 필요) Future getExpiredContractsCount() async { return await _repository.getExpiredContractsCount(); } /// 활성 계약 수 조회 Future getActiveContractsCount() async { return await _repository.getActiveContractsCount(); } /// 대시보드 카드 데이터 생성 /// UI에서 바로 사용할 수 있는 카드 형태 데이터 반환 Future> getDashboardCards() async { final stats = await getMaintenanceStats(); return stats.dashboardCards; } /// 위험도 평가 /// 만료 임박 계약들의 위험 수준을 0.0~1.0으로 반환 Future calculateRiskScore() async { final stats = await getMaintenanceStats(); return stats.riskScore; } /// 통계 데이터 무결성 검증 void _validateStatsData(MaintenanceStatsDto stats) { // 기본 유효성 검사 if (stats.totalContracts < 0) { throw Exception('총 계약 수는 음수일 수 없습니다.'); } if (stats.activeContracts < 0) { throw Exception('활성 계약 수는 음수일 수 없습니다.'); } if (stats.activeContracts > stats.totalContracts) { throw Exception('활성 계약 수는 총 계약 수를 초과할 수 없습니다.'); } // 만료 기간별 통계 검증 if (stats.expiring7Days < 0 || stats.expiring30Days < 0 || stats.expiring60Days < 0 || stats.expiredContracts < 0) { throw Exception('만료 관련 통계는 음수일 수 없습니다.'); } // 계약 타입별 통계 검증 (V/R 시스템) final totalByType = stats.visitContracts + stats.remoteContracts; // 약간의 오차는 허용 (삭제된 계약 등으로 인한 불일치 가능) if (totalByType > stats.totalContracts + 100) { throw Exception('계약 타입별 합계가 총 계약 수를 크게 초과합니다.'); } // 완료율 검증 (0.0 ~ 1.0 사이) if (stats.completionRate < 0.0 || stats.completionRate > 1.0) { throw Exception('완료율은 0~100% 사이여야 합니다.'); } } }