Files
superport/lib/domain/usecases/get_maintenance_stats_usecase.dart
JiWoong Sul 519e1883a3
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled
feat: V/R 유지보수 시스템 전환 및 대시보드 테이블 형태 완성
- V/R 시스템 완전 전환: WARRANTY/CONTRACT/INSPECTION → V(방문)/R(원격)
- 유지보수 대시보드 카드 → StandardDataTable 테이블 형태 전환
- "조회중..." 문제 해결: 백엔드 직접 필드 사용 (equipment_model, company_name)
- MaintenanceDto 신규 필드 추가: company_id, company_name, equipment_serial, equipment_model
- preloadEquipmentData 비활성화로 불필요한 equipment-history API 호출 제거
- CO-STAR 프레임워크 적용 및 CLAUDE.md v3.0 업데이트
- Flutter Analyze ERROR: 0 유지, 100% shadcn_ui 컴플라이언스

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-05 14:33:20 +09:00

125 lines
4.1 KiB
Dart

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<MaintenanceStatsDto> 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<int> 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<Map<String, int>> getContractsByType() async {
final contractsByType = await _repository.getContractsByType();
// 빈 결과 처리
if (contractsByType.isEmpty) {
return {
'WARRANTY': 0,
'CONTRACT': 0,
'INSPECTION': 0,
};
}
return contractsByType;
}
/// 만료된 계약 수 조회 (즉시 조치 필요)
Future<int> getExpiredContractsCount() async {
return await _repository.getExpiredContractsCount();
}
/// 활성 계약 수 조회
Future<int> getActiveContractsCount() async {
return await _repository.getActiveContractsCount();
}
/// 대시보드 카드 데이터 생성
/// UI에서 바로 사용할 수 있는 카드 형태 데이터 반환
Future<List<MaintenanceStatusCardData>> getDashboardCards() async {
final stats = await getMaintenanceStats();
return stats.dashboardCards;
}
/// 위험도 평가
/// 만료 임박 계약들의 위험 수준을 0.0~1.0으로 반환
Future<double> 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% 사이여야 합니다.');
}
}
}