feat: 대시보드에 라이선스 만료 요약 및 Lookup 데이터 캐싱 시스템 구현
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

- License Expiry Summary API 연동 완료
  - 30/60/90일 내 만료 예정 라이선스 요약 표시
  - 대시보드 상단에 알림 카드로 통합
  - 만료 임박 순서로 색상 구분 (빨강/주황/노랑)

- Lookup 데이터 전역 캐싱 시스템 구축
  - LookupService 및 RemoteDataSource 생성
  - 전체 lookup 데이터 일괄 로드 및 캐싱
  - 타입별 필터링 지원

- 새로운 모델 추가
  - LicenseExpirySummary (Freezed)
  - LookupData, LookupCategory, LookupItem 모델

- CLAUDE.md 문서 업데이트
  - 미사용 API 활용 계획 추가
  - 구현 우선순위 정의

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
JiWoong Sul
2025-08-08 14:42:20 +09:00
parent 740a691406
commit 844c7bd92f
15 changed files with 2105 additions and 4 deletions

View File

@@ -6,6 +6,7 @@ import 'package:superport/core/errors/failures.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/data/models/dashboard/equipment_status_distribution.dart';
import 'package:superport/data/models/dashboard/expiring_license.dart';
import 'package:superport/data/models/dashboard/license_expiry_summary.dart';
import 'package:superport/data/models/dashboard/overview_stats.dart';
import 'package:superport/data/models/dashboard/recent_activity.dart';
@@ -14,6 +15,7 @@ abstract class DashboardRemoteDataSource {
Future<Either<Failure, List<RecentActivity>>> getRecentActivities();
Future<Either<Failure, EquipmentStatusDistribution>> getEquipmentStatusDistribution();
Future<Either<Failure, List<ExpiringLicense>>> getExpiringLicenses({int days = 30});
Future<Either<Failure, LicenseExpirySummary>> getLicenseExpirySummary();
}
@LazySingleton(as: DashboardRemoteDataSource)
@@ -105,6 +107,25 @@ class DashboardRemoteDataSourceImpl implements DashboardRemoteDataSource {
}
}
@override
Future<Either<Failure, LicenseExpirySummary>> getLicenseExpirySummary() async {
try {
final response = await _apiClient.get('/overview/license-expiry');
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
final summary = LicenseExpirySummary.fromJson(response.data['data']);
return Right(summary);
} else {
final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 올바르지 않습니다';
return Left(ServerFailure(message: errorMessage));
}
} on DioException catch (e) {
return Left(_handleDioError(e));
} catch (e) {
return Left(ServerFailure(message: '라이선스 만료 요약을 가져오는 중 오류가 발생했습니다: $e'));
}
}
Failure _handleDioError(DioException error) {
switch (error.type) {
case DioExceptionType.connectionTimeout: