fix
This commit is contained in:
90
claude.md
90
claude.md
@@ -64,8 +64,8 @@ You have access to these expert subagents - USE THEM PROACTIVELY:
|
||||
## Flutter Best Practices
|
||||
- Use Flutter 3.x features and Material 3 design
|
||||
- Implement clean architecture with Riverpod for state management
|
||||
- Use Hive CE for local database and offline-first functionality
|
||||
- Follow proper dependency injection with GetIt
|
||||
- Use Hive CE for local database with **online-first** strategy (API first, cache fallback)
|
||||
- Follow proper dependency injection with Riverpod providers
|
||||
- Implement proper error handling and user feedback
|
||||
- Follow platform-specific design guidelines
|
||||
- Use proper localization for multi-language support
|
||||
@@ -453,7 +453,7 @@ A comprehensive Flutter-based Point of Sale (POS) application designed for retai
|
||||
- Supplier state
|
||||
|
||||
**Data Requirements**:
|
||||
- Product list from Hive (offline-first)
|
||||
- Product list from API (online-first with Hive cache fallback)
|
||||
- Product images (cached with variants)
|
||||
- Product search indexing
|
||||
- Category relationships
|
||||
@@ -969,45 +969,63 @@ GridView.builder(
|
||||
- Debounce search queries
|
||||
- Optimize cart calculations
|
||||
|
||||
## Offline-First Strategy
|
||||
## Online-First Strategy
|
||||
|
||||
### Data Flow
|
||||
1. **Read**: Always read from Hive first (instant UI)
|
||||
2. **Sync**: Background sync with API when online
|
||||
3. **Update**: Update Hive and UI when sync completes
|
||||
4. **Conflict**: Handle conflicts with last-write-wins strategy
|
||||
1. **Check Connection**: Check if device is online
|
||||
2. **Try API First**: If online, fetch fresh data from API
|
||||
3. **Update Cache**: Save API response to Hive for offline access
|
||||
4. **Fallback to Cache**: If API fails or offline, load from Hive
|
||||
5. **Show Data**: Display data to user (from API or cache)
|
||||
|
||||
### Sync Logic
|
||||
### Implementation Pattern
|
||||
```dart
|
||||
@riverpod
|
||||
class DataSync extends _$DataSync {
|
||||
class Products extends _$Products {
|
||||
@override
|
||||
Future<SyncStatus> build() async {
|
||||
return await _performSync();
|
||||
Future<List<Product>> build() async {
|
||||
// Online-first: Try to load from API first
|
||||
final repository = ref.watch(productRepositoryProvider);
|
||||
final networkInfo = ref.watch(networkInfoProvider);
|
||||
|
||||
// Check if online
|
||||
final isConnected = await networkInfo.isConnected;
|
||||
|
||||
if (isConnected) {
|
||||
// Try API first
|
||||
try {
|
||||
final syncResult = await repository.syncProducts();
|
||||
return syncResult.fold(
|
||||
(failure) {
|
||||
// API failed, fallback to cache
|
||||
print('API failed, falling back to cache: ${failure.message}');
|
||||
return _loadFromCache();
|
||||
},
|
||||
(products) => products,
|
||||
);
|
||||
} catch (e) {
|
||||
// API error, fallback to cache
|
||||
print('API error, falling back to cache: $e');
|
||||
return _loadFromCache();
|
||||
}
|
||||
} else {
|
||||
// Offline, load from cache
|
||||
print('Offline, loading from cache');
|
||||
return _loadFromCache();
|
||||
}
|
||||
}
|
||||
|
||||
Future<SyncStatus> _performSync() async {
|
||||
if (!await ref.read(networkInfoProvider).isConnected) {
|
||||
return SyncStatus.offline;
|
||||
}
|
||||
|
||||
try {
|
||||
// Sync categories first
|
||||
await ref.read(categoriesProvider.notifier).syncCategories();
|
||||
|
||||
// Then sync products and variants
|
||||
await ref.read(productsProvider.notifier).syncProducts();
|
||||
|
||||
// Sync suppliers
|
||||
await ref.read(suppliersProvider.notifier).syncSuppliers();
|
||||
|
||||
// Update last sync time
|
||||
await ref.read(settingsProvider.notifier).updateLastSync();
|
||||
|
||||
return SyncStatus.success;
|
||||
} catch (e) {
|
||||
return SyncStatus.failed;
|
||||
}
|
||||
|
||||
Future<List<Product>> _loadFromCache() async {
|
||||
final repository = ref.read(productRepositoryProvider);
|
||||
final result = await repository.getAllProducts();
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
print('Cache load failed: ${failure.message}');
|
||||
return <Product>[];
|
||||
},
|
||||
(products) => products,
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1134,7 +1152,7 @@ class DataSync extends _$DataSync {
|
||||
### Code Review Checklist
|
||||
- [ ] Follows clean architecture principles
|
||||
- [ ] Proper error handling implemented
|
||||
- [ ] Offline-first approach maintained
|
||||
- [ ] **Online-first approach maintained** (API first, cache fallback)
|
||||
- [ ] Performance optimizations applied
|
||||
- [ ] Proper state management with Riverpod
|
||||
- [ ] Hive models and adapters properly defined
|
||||
|
||||
Reference in New Issue
Block a user