feat: Gestion des secteurs et migration v3.0.4+304

- Ajout système complet de gestion des secteurs avec contours géographiques
- Import des contours départementaux depuis GeoJSON
- API REST pour la gestion des secteurs (/api/sectors)
- Service de géolocalisation pour déterminer les secteurs
- Migration base de données avec tables x_departements_contours et sectors_adresses
- Interface Flutter pour visualisation et gestion des secteurs
- Ajout thème sombre dans l'application
- Corrections diverses et optimisations

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
pierre
2025-08-07 11:01:45 +02:00
parent 6a609fb467
commit 599b9fcda0
662 changed files with 213221 additions and 174243 deletions

391
app/CLAUDE.md Executable file
View File

@@ -0,0 +1,391 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Instructions générales pour Claude
### Langue de communication
- **TOUJOURS répondre en français** sauf si explicitement demandé autrement
- Utiliser un langage technique approprié en français
### Méthodologie de travail
- **Travailler par étapes** : Ne jamais se lancer directement dans la modification du code
- **Présenter et proposer** : Toujours expliquer ce que je compte faire AVANT de le faire
- **Demander validation** : Attendre l'accord de l'utilisateur avant de procéder aux modifications
- **Structure de réponse** :
1. Analyser la demande
2. Proposer une solution détaillée
3. Lister les fichiers qui seront modifiés
4. Attendre la validation
5. Implémenter les changements
## Build Commands
- **Run app**: `flutter run` - start the Flutter app in debug mode
- **Build for release**: `flutter build apk` (Android), `flutter build ios` (iOS), `flutter build web` (Web)
- **Run tests**: `flutter test` - run all unit tests
- **Run specific test**: `flutter test test/widget_test.dart` - run a specific test file
- **Analyze code**: `flutter analyze` - check for errors, warnings, and lints
- **Format code**: `flutter format lib/` - format all Dart files
- **Generate code**: `flutter packages pub run build_runner build` - generate Hive adapters and JSON serialization
- **Clean build**: `flutter clean && flutter pub get` - clean and reinstall dependencies
- **Update dependencies**: `flutter pub upgrade` - update all packages
- **Launcher icons**: `flutter pub run flutter_launcher_icons:main` - generate app icons
## Code Architecture
### Core Architecture Pattern
The app follows a **Repository Pattern** with singleton services and reactive UI updates:
```
UI Layer (ValueListenableBuilder)
Repository Layer (Business Logic)
Service Layer (API + Hive Storage)
```
### Key Architectural Components
#### **Singleton Services** (lib/core/services/)
- `ApiService` - HTTP client with environment auto-detection (DEV/REC/PROD)
- `HiveService` - Local database management with typed Box handling
- `CurrentUserService` - User session and authentication state
- `CurrentAmicaleService` - Current organization context
- `DataLoadingService` - Orchestrates API data synchronization to Hive
#### **Repository Pattern** (lib/core/repositories/)
- `UserRepository` - User management and authentication
- `OperationRepository` - Operations and campaigns
- `MembreRepository` - Team member management
- `PassageRepository` - Distribution tracking
- `SectorRepository` - Geographic sectors
- `AmicaleRepository` - Organization management
#### **Reactive UI Pattern**
Uses `ValueListenableBuilder` with Hive boxes for automatic UI updates:
```dart
ValueListenableBuilder<Box<UserModel>>(
valueListenable: userRepository.getUsersBox().listenable(),
builder: (context, box, child) {
// UI automatically updates when data changes
},
)
```
### Data Flow Architecture
#### **"API First" Principle**
1. UI action triggers repository method
2. Repository attempts API call first
3. On success → Save to Hive → UI auto-updates via ValueListenableBuilder
4. On error → Show error message, no local changes
#### **Hive Storage Strategy**
- **TypeId Management**: Models use specific typeIds (UserModel: 0, OperationModel: 1, etc.)
- **Typed Boxes**: Each model has its own strongly-typed Hive box
- **Auto-sync**: Data automatically syncs between API and local storage
- **Offline-ready**: App functions with cached data when offline
- **Box Caching Optimization**: Repositories use cached Box references to prevent repeated access checks
### Error Handling Architecture
#### **Centralized Error Management**
- `ApiException` class extracts meaningful error messages from API responses
- `showError()` and `showSuccess()` methods provide consistent user feedback
- Repository methods propagate exceptions to UI layer for handling
#### **Error Flow Pattern**
```dart
try {
final result = await repository.updateUser(user);
ApiException.showSuccess(context, "User updated successfully");
} catch (e) {
ApiException.showError(context, e); // Handles all error types
}
```
#### **Smart Dialog Detection**
ApiException automatically detects when called from within a Dialog and adjusts message positioning:
- **Normal context**: Uses standard SnackBar
- **Dialog context**: Uses overlay SnackBar positioned above the Dialog
- **Mobile/Web aware**: Automatically adapts presentation for each platform
- **Consistent styling**: Unified colors, icons, and behavior across all contexts
```dart
// Same API works everywhere - smart context detection
if (validationFails) {
ApiException.showError(context, Exception("Validation failed"));
return; // Dialog stays open for corrections
}
// Success handling with auto-close
if (success) {
Navigator.pop(context); // Close dialog first
ApiException.showSuccess(context, "Operation completed");
}
```
### State Management Strategy
#### **No Provider/Bloc** - Direct Reactive Pattern
- Uses `ValueListenableBuilder` directly with Hive boxes
- Singleton services maintain global state
- `ChangeNotifier` only for specific repository loading states
#### **Dialog Auto-Management Pattern**
Dialogs handle their own submission and closing:
```dart
// Dialog manages its own lifecycle
void _handleSubmit() async {
try {
await repository.saveData(data);
Navigator.pop(context); // Auto-close on success
widget.onSuccess?.call(); // Simple callback
} catch (e) {
ApiException.showError(context, e); // Error without closing
}
}
```
### Multi-Role Permission System
#### **Role Hierarchy**
- **Role 1** (Membre): Field operations, distribution tracking
- **Role 2** (Admin Amicale): Organization management, member administration
- **Role 3+** (Super Admin): Global system administration
#### **Permission Checks**
```dart
final currentUser = CurrentUserService.instance;
if (currentUser.canAccessAdmin) {
// Show admin features
}
if (currentUser.isSuperAdmin) {
// Show super admin features
}
```
### Code Generation Requirements
#### **Hive Adapters**
Models require code generation for Hive serialization:
```bash
flutter packages pub run build_runner build
```
Run this after modifying any `@HiveType` models in `lib/core/data/models/`.
#### **Model Structure**
```dart
@HiveType(typeId: X)
class MyModel extends HiveObject {
@HiveField(0)
final int id;
@HiveField(1)
final String name;
}
```
### Development Workflow
#### **Working with Repositories**
1. Always inject repositories via constructor or global instances from `app.dart`
2. Use `try/catch` blocks for all repository calls
3. Show loading states during async operations
4. Handle errors with `ApiException.showError()`
5. Implement Hive box caching to avoid repeated access checks during high-frequency operations
#### **Adding New Features**
1. Create/modify models in `lib/core/data/models/`
2. Run `build_runner` to generate Hive adapters
3. Add repository methods in `lib/core/repositories/`
4. Create UI widgets in `lib/presentation/widgets/`
5. Wire up with `ValueListenableBuilder` for reactivity
#### **Testing Strategy**
- Unit tests for repositories and services
- Widget tests for UI components
- Integration tests for complete user flows
- Use `flutter test` for running tests
### Environment Configuration
#### **Auto-Detection**
The app automatically detects environment based on URL:
- `dapp.geosector.fr` → DEV environment
- `rapp.geosector.fr` → REC environment
- Production → PROD environment
- Non-web platforms → DEV by default
#### **API Configuration**
Environment-specific API endpoints are configured in `ApiService` automatically.
### Common Patterns to Follow
#### **Repository Method Pattern**
```dart
Future<bool> updateUser(UserModel user) async {
try {
final response = await ApiService.instance.put('/users/${user.id}', user.toJson());
final updatedUser = UserModel.fromJson(response.data);
await _saveUserToHive(updatedUser);
return true;
} catch (e) {
throw ApiException.fromDioException(e);
}
}
```
#### **Hive Box Caching Pattern**
```dart
class MyRepository {
// Cache de la box pour éviter les vérifications répétées
Box<MyModel>? _cachedBox;
// Getter lazy pour n'accéder à la boîte que lorsque nécessaire
Box<MyModel> get _myBox {
if (_cachedBox == null) {
if (!Hive.isBoxOpen(AppKeys.myBoxName)) {
throw Exception('La boîte n\'est pas ouverte');
}
_cachedBox = Hive.box<MyModel>(AppKeys.myBoxName);
}
return _cachedBox!;
}
// Méthode pour réinitialiser le cache après modification
void _resetCache() {
_cachedBox = null;
}
// Sauvegarder avec réinitialisation du cache
Future<void> saveItem(MyModel item) async {
await _myBox.put(item.id, item);
_resetCache(); // Crucial pour ValueListenableBuilder
notifyListeners();
}
}
```
#### **Widget Error Handling**
```dart
Future<void> _handleSave() async {
try {
setState(() => _isLoading = true);
await repository.saveData(data);
ApiException.showSuccess(context, "Saved successfully");
} catch (e) {
ApiException.showError(context, e);
} finally {
setState(() => _isLoading = false);
}
}
```
#### **ValueListenableBuilder Usage**
```dart
ValueListenableBuilder<Box<ModelType>>(
valueListenable: repository.getBox().listenable(),
builder: (context, box, child) {
final items = box.values.where((item) => filterCondition).toList();
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) => ItemWidget(item: items[index]),
);
},
)
```
### Hive Box Performance Management
#### **Box Caching Strategy**
Repositories implement a caching pattern to optimize Hive box access and prevent performance issues during high-frequency operations:
**Problems Solved:**
- Eliminates repeated `Hive.isBoxOpen()` checks (up to 848 checks per page load)
- Improves performance during list rendering and filtering operations
- Maintains thread-safe access to Hive boxes
**Implementation Pattern:**
```dart
class ExampleRepository {
// Private cached box reference
Box<ExampleModel>? _cachedBox;
// Lazy getter with caching
Box<ExampleModel> get _exampleBox {
if (_cachedBox == null) {
if (!Hive.isBoxOpen(AppKeys.exampleBoxName)) {
throw Exception('Box not open: ${AppKeys.exampleBoxName}');
}
_cachedBox = Hive.box<ExampleModel>(AppKeys.exampleBoxName);
debugPrint('Repository: Box ${AppKeys.exampleBoxName} cached');
}
return _cachedBox!;
}
// Cache reset for ValueListenableBuilder notifications
void _resetCache() {
_cachedBox = null;
}
}
```
#### **When to Reset Cache**
Cache reset is **essential** after any database modification to ensure ValueListenableBuilder and other Hive listeners detect changes:
```dart
// REQUIRED: After individual saves
Future<void> saveItem(ExampleModel item) async {
await _exampleBox.put(item.id, item);
_resetCache(); // ← Essential for UI reactivity
notifyListeners();
}
// REQUIRED: After deletions
Future<void> deleteItem(int id) async {
await _exampleBox.delete(id);
_resetCache(); // ← Essential for UI reactivity
notifyListeners();
}
// REQUIRED: After bulk operations
Future<void> clearAll() async {
await _exampleBox.clear();
_resetCache(); // ← Essential for UI reactivity
notifyListeners();
}
// REQUIRED: After API data processing
Future<void> processApiData(List<dynamic> data) async {
await _exampleBox.clear();
for (final item in data) {
await _exampleBox.put(item.id, ExampleModel.fromJson(item));
}
_resetCache(); // ← Essential for UI reactivity
notifyListeners();
}
```
#### **Performance Impact**
| Scenario | Without Caching | With Caching |
|----------|-----------------|--------------|
| Loading 848 passages | 848 box checks | 1 box access |
| List filtering | Check per item | Cached access |
| ValueListenableBuilder | Repeated verification | Optimized access |
| Memory usage | Minimal overhead | Negligible cache |
#### **Best Practices**
1. **Always cache** in repositories that handle frequently accessed data
2. **Always reset cache** after any modification operation
3. **Use lazy getters** to avoid unnecessary box access
4. **Include debug prints** to monitor caching behavior during development
5. **Apply pattern consistently** across all repositories for maintainability
This architecture ensures type safety, reactivity, offline capability, and maintainable code structure across the entire application.