update
This commit is contained in:
161
lib/features/home/data/repositories/home_repository_impl.dart
Normal file
161
lib/features/home/data/repositories/home_repository_impl.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
/// Repository Implementation: Home Repository
|
||||
///
|
||||
/// Concrete implementation of the HomeRepository interface.
|
||||
/// Coordinates between local and remote data sources to provide home data.
|
||||
///
|
||||
/// Implements offline-first strategy:
|
||||
/// 1. Try to return cached data immediately
|
||||
/// 2. Fetch fresh data from server in background
|
||||
/// 3. Update cache with fresh data
|
||||
library;
|
||||
|
||||
import 'package:worker/core/errors/exceptions.dart';
|
||||
import 'package:worker/core/errors/failures.dart';
|
||||
import 'package:worker/features/home/data/datasources/home_local_datasource.dart';
|
||||
import 'package:worker/features/home/domain/entities/member_card.dart';
|
||||
import 'package:worker/features/home/domain/entities/promotion.dart';
|
||||
import 'package:worker/features/home/domain/repositories/home_repository.dart';
|
||||
|
||||
/// Home Repository Implementation
|
||||
///
|
||||
/// Responsibilities:
|
||||
/// - Coordinate between local cache and remote API
|
||||
/// - Implement offline-first data strategy
|
||||
/// - Handle errors and convert to domain failures
|
||||
/// - Manage cache invalidation
|
||||
class HomeRepositoryImpl implements HomeRepository {
|
||||
/// Local data source (Hive)
|
||||
final HomeLocalDataSource localDataSource;
|
||||
|
||||
/// Remote data source (API) - TODO: Add when API is ready
|
||||
// final HomeRemoteDataSource remoteDataSource;
|
||||
|
||||
/// Constructor
|
||||
HomeRepositoryImpl({
|
||||
required this.localDataSource,
|
||||
// required this.remoteDataSource, // TODO: Add when API ready
|
||||
});
|
||||
|
||||
@override
|
||||
Future<MemberCard> getMemberCard() async {
|
||||
try {
|
||||
// TODO: Implement offline-first strategy
|
||||
// 1. Check if cache is valid
|
||||
final isCacheValid = await localDataSource.isMemberCardCacheValid();
|
||||
|
||||
if (isCacheValid) {
|
||||
// 2. Return cached data if valid
|
||||
final cachedModel = await localDataSource.getMemberCard();
|
||||
return cachedModel.toEntity();
|
||||
}
|
||||
|
||||
// 3. If cache invalid, fetch from remote (when API ready)
|
||||
// For now, try to return cached data even if expired
|
||||
try {
|
||||
final cachedModel = await localDataSource.getMemberCard();
|
||||
return cachedModel.toEntity();
|
||||
} catch (e) {
|
||||
// TODO: Fetch from remote API when available
|
||||
// final remoteModel = await remoteDataSource.getMemberCard();
|
||||
// await localDataSource.cacheMemberCard(remoteModel);
|
||||
// return remoteModel.toEntity();
|
||||
|
||||
throw const CacheException('No member card data available');
|
||||
}
|
||||
} on CacheException catch (e) {
|
||||
throw CacheFailure(message: e.message);
|
||||
} catch (e) {
|
||||
throw ServerFailure(message: 'Failed to get member card: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Promotion>> getPromotions() async {
|
||||
try {
|
||||
// TODO: Implement offline-first strategy
|
||||
// 1. Check if cache is valid
|
||||
final isCacheValid = await localDataSource.isPromotionsCacheValid();
|
||||
|
||||
if (isCacheValid) {
|
||||
// 2. Return cached data if valid
|
||||
final cachedModels = await localDataSource.getPromotions();
|
||||
return cachedModels.map((model) => model.toEntity()).toList();
|
||||
}
|
||||
|
||||
// 3. If cache invalid, fetch from remote (when API ready)
|
||||
// For now, try to return cached data even if expired
|
||||
try {
|
||||
final cachedModels = await localDataSource.getPromotions();
|
||||
return cachedModels.map((model) => model.toEntity()).toList();
|
||||
} catch (e) {
|
||||
// TODO: Fetch from remote API when available
|
||||
// final remoteModels = await remoteDataSource.getPromotions();
|
||||
// await localDataSource.cachePromotions(remoteModels);
|
||||
// return remoteModels.map((m) => m.toEntity()).toList();
|
||||
|
||||
// Return empty list if no data available
|
||||
return [];
|
||||
}
|
||||
} on CacheException catch (e) {
|
||||
throw CacheFailure(message: e.message);
|
||||
} catch (e) {
|
||||
throw ServerFailure(message: 'Failed to get promotions: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MemberCard> refreshMemberCard() async {
|
||||
try {
|
||||
// TODO: Implement force refresh from API
|
||||
// This should always fetch from remote, bypassing cache
|
||||
|
||||
// When API is ready:
|
||||
// 1. Fetch from remote
|
||||
// final remoteModel = await remoteDataSource.getMemberCard();
|
||||
|
||||
// 2. Update cache
|
||||
// await localDataSource.cacheMemberCard(remoteModel);
|
||||
|
||||
// 3. Return entity
|
||||
// return remoteModel.toEntity();
|
||||
|
||||
// For now, just return cached data
|
||||
final cachedModel = await localDataSource.getMemberCard();
|
||||
return cachedModel.toEntity();
|
||||
} on ServerException catch (e) {
|
||||
throw ServerFailure(message: e.message);
|
||||
} on NetworkException catch (e) {
|
||||
throw NetworkFailure(message: e.message);
|
||||
} catch (e) {
|
||||
throw ServerFailure(message: 'Failed to refresh member card: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Promotion>> refreshPromotions() async {
|
||||
try {
|
||||
// TODO: Implement force refresh from API
|
||||
// This should always fetch from remote, bypassing cache
|
||||
|
||||
// When API is ready:
|
||||
// 1. Fetch from remote
|
||||
// final remoteModels = await remoteDataSource.getPromotions();
|
||||
|
||||
// 2. Update cache
|
||||
// await localDataSource.cachePromotions(remoteModels);
|
||||
|
||||
// 3. Return entities
|
||||
// return remoteModels.map((m) => m.toEntity()).toList();
|
||||
|
||||
// For now, just return cached data
|
||||
final cachedModels = await localDataSource.getPromotions();
|
||||
return cachedModels.map((model) => model.toEntity()).toList();
|
||||
} on ServerException catch (e) {
|
||||
throw ServerFailure(message: e.message);
|
||||
} on NetworkException catch (e) {
|
||||
throw NetworkFailure(message: e.message);
|
||||
} catch (e) {
|
||||
throw ServerFailure(message: 'Failed to refresh promotions: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user