This commit is contained in:
Phuoc Nguyen
2025-11-27 14:59:48 +07:00
parent dc8e60f589
commit ba04576750
25 changed files with 931 additions and 721 deletions

View File

@@ -1,66 +1,85 @@
/// Submissions Repository Implementation
///
/// Implements the submissions repository interface.
/// Implements the submissions repository interface with caching support.
library;
import 'package:worker/features/projects/data/datasources/project_status_local_datasource.dart';
import 'package:worker/features/projects/data/datasources/submissions_remote_datasource.dart';
import 'package:worker/features/projects/domain/entities/project_status.dart';
import 'package:worker/features/projects/domain/entities/project_submission.dart';
import 'package:worker/features/projects/domain/repositories/submissions_repository.dart';
/// Submissions Repository Implementation
///
/// Handles data operations for project submissions.
/// Handles data operations for project submissions with cache-first pattern.
class SubmissionsRepositoryImpl implements SubmissionsRepository {
const SubmissionsRepositoryImpl(
this._remoteDataSource,
this._statusLocalDataSource,
);
const SubmissionsRepositoryImpl(this._remoteDataSource);
final SubmissionsRemoteDataSource _remoteDataSource;
final ProjectStatusLocalDataSource _statusLocalDataSource;
/// Get project status list with cache-first pattern
///
/// 1. Return cached data if available
/// 2. Fetch from API in background and update cache
/// 3. If no cache, wait for API response
@override
Future<List<ProjectSubmission>> getSubmissions() async {
Future<List<ProjectStatus>> getProjectStatusList({
bool forceRefresh = false,
}) async {
// Check cache first (unless force refresh)
if (!forceRefresh && _statusLocalDataSource.hasCachedData()) {
final cachedStatuses = _statusLocalDataSource.getCachedStatusList();
if (cachedStatuses.isNotEmpty) {
// Return cached data immediately
// Also refresh cache in background (fire and forget)
_refreshStatusCache();
return cachedStatuses.map((model) => model.toEntity()).toList();
}
}
// No cache or force refresh - fetch from API
try {
return await _remoteDataSource.getSubmissions();
final statusModels = await _remoteDataSource.getProjectStatusList();
// Cache the result
await _statusLocalDataSource.cacheStatusList(statusModels);
return statusModels.map((model) => model.toEntity()).toList();
} catch (e) {
// In real implementation, handle errors properly
// For now, rethrow
// If API fails, try to return cached data as fallback
final cachedStatuses = _statusLocalDataSource.getCachedStatusList();
if (cachedStatuses.isNotEmpty) {
return cachedStatuses.map((model) => model.toEntity()).toList();
}
rethrow;
}
}
@override
Future<ProjectSubmission> getSubmissionById(String submissionId) async {
/// Refresh status cache in background
Future<void> _refreshStatusCache() async {
try {
return await _remoteDataSource.getSubmissionById(submissionId);
final statusModels = await _remoteDataSource.getProjectStatusList();
await _statusLocalDataSource.cacheStatusList(statusModels);
} catch (e) {
rethrow;
// Silently fail - we already returned cached data
}
}
@override
Future<ProjectSubmission> createSubmission(
ProjectSubmission submission,
) async {
Future<List<ProjectSubmission>> getSubmissions({
int limitStart = 0,
int limitPageLength = 0,
}) async {
try {
return await _remoteDataSource.createSubmission(submission);
} catch (e) {
rethrow;
}
}
@override
Future<ProjectSubmission> updateSubmission(
ProjectSubmission submission,
) async {
try {
return await _remoteDataSource.updateSubmission(submission);
} catch (e) {
rethrow;
}
}
@override
Future<void> deleteSubmission(String submissionId) async {
try {
await _remoteDataSource.deleteSubmission(submissionId);
final submissionModels = await _remoteDataSource.getSubmissions(
limitStart: limitStart,
limitPageLength: limitPageLength,
);
return submissionModels.map((model) => model.toEntity()).toList();
} catch (e) {
rethrow;
}