Files
geo/app/README-APP.md
2025-06-04 16:51:40 +02:00

8.6 KiB

GEOSECTOR

Une application puissante et intuitive de gestion de vos distributions de calendriers par secteurs géographiques pour les amicales de pompiers.

📱 Présentation

GEOSECTOR est une application Flutter qui permet aux amicales de pompiers de gérer efficacement la distribution de calendriers par secteurs géographiques.

Fonctionnalités principales

  • Gestion des secteurs géographiques avec cartes interactives (Flutter Map)
  • Suivi des passages avec géolocalisation
  • Interface différenciée : utilisateur et administrateur
  • Authentification sécurisée avec gestion des rôles@
  • Chat intégré avec système de notifications
  • Stockage local avec synchronisation en ligne
  • Support multi-plateforme : Web, iOS, Android

🏗️ Architecture

Stack technique

  • Framework : Flutter 3.32
  • Routing : Go Router
  • Base de données locale : Hive
  • Gestion d'état : Provider + Repository Pattern
  • Cartes : Flutter Map avec Mapbox
  • API : Dio pour les requêtes HTTP
  • Chat : MQTT5 Client

Architecture de données : Hive + Provider + Repository

L'application utilise une architecture en couches pour la gestion des données :

UI Layer (Widgets)
    ↓
Provider Layer (State Management)
    ↓
Repository Layer (Business Logic)
    ↓
Data Layer (Hive + API)

Couches de l'architecture

  1. UI Layer : Widgets Flutter qui affichent les données
  2. Provider Layer : Gestion d'état avec ChangeNotifier
  3. Repository Layer : Logique métier et orchestration des sources de données
  4. Data Layer : Stockage local (Hive) et API distante

Structure des dossiers

lib/
├── core/
│   ├── config/
│   ├── constants/
│   ├── errors/
│   ├── network/
│   └── utils/
├── data/
│   ├── datasources/
│   ├── models/
│   └── repositories/
├── domain/
│   ├── entities/
│   ├── repositories/
│   └── usecases/
├── presentation/
│   ├── pages/
│   ├── providers/
│   ├── widgets/
│   └── theme/
└── main.dart

🚀 Installation et configuration

Prérequis

  • Flutter 3.x
  • Dart SDK
  • Android Studio / VS Code
  • Émulateur ou appareil physique

Installation

  1. Cloner le repository

    git clone https://github.com/votre-repo/geosector.git
    cd geosector
    
  2. Installer les dépendances

    flutter pub get
    
  3. Configuration des clés API

    Créer un fichier .env à la racine :

    MAPBOX_ACCESS_TOKEN=your_mapbox_token
    API_BASE_URL=https://your-api.com
    MQTT_BROKER_URL=your-mqtt-broker
    
  4. Lancer l'application

    flutter run
    

📦 Dépendances principales

dependencies:
  flutter:
    sdk: flutter
  
  # État et navigation
  provider: ^6.1.1
  go_router: ^12.1.3
  
  # Stockage local
  hive: ^2.2.3
  hive_flutter: ^1.1.0
  
  # Réseau
  dio: ^5.4.0
  
  # Cartes
  flutter_map: ^6.1.0
  geolocator: ^10.1.0
  
  # Chat
  mqtt5_client: ^4.2.0
  
  # UI
  flutter_screenutil: ^5.9.0
  cached_network_image: ^3.3.0
  
dev_dependencies:
  hive_generator: ^2.0.1
  build_runner: ^2.4.7

🗄️ Modèles de données

Secteur

@HiveType(typeId: 0)
class Secteur extends HiveObject {
  @HiveField(0)
  String id;
  
  @HiveField(1)
  String nom;
  
  @HiveField(2)
  List<LatLng> polygone;
  
  @HiveField(3)
  String couleur;
  
  @HiveField(4)
  int nombreCalendriers;
  
  @HiveField(5)
  DateTime dateCreation;
}

Passage

@HiveType(typeId: 1)
class Passage extends HiveObject {
  @HiveField(0)
  String id;
  
  @HiveField(1)
  String secteurId;
  
  @HiveField(2)
  String utilisateurId;
  
  @HiveField(3)
  DateTime datePassage;
  
  @HiveField(4)
  LatLng position;
  
  @HiveField(5)
  int calendriersDistribues;
  
  @HiveField(6)
  String commentaire;
  
  @HiveField(7)
  List<String> photos;
}

Utilisateur

@HiveType(typeId: 2)
class Utilisateur extends HiveObject {
  @HiveField(0)
  String id;
  
  @HiveField(1)
  String nom;
  
  @HiveField(2)
  String email;
  
  @HiveField(3)
  String role; // 'admin' ou 'user'
  
  @HiveField(4)
  List<String> secteursAssignes;
  
  @HiveField(5)
  DateTime dernierLogin;
}

🔧 Gestion d'état avec Provider

SecteurProvider

class SecteurProvider extends ChangeNotifier {
  final SecteurRepository _repository;
  
  List<Secteur> _secteurs = [];
  bool _isLoading = false;
  
  List<Secteur> get secteurs => _secteurs;
  bool get isLoading => _isLoading;
  
  Future<void> loadSecteurs() async {
    _isLoading = true;
    notifyListeners();
    
    try {
      _secteurs = await _repository.getAllSecteurs();
    } catch (e) {
      // Gestion d'erreur
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
}

🗺️ Cartes et géolocalisation

Configuration Flutter Map

FlutterMap(
  options: MapOptions(
    center: LatLng(46.2276, 2.2137), // Centre de la France
    zoom: 6.0,
  ),
  children: [
    TileLayer(
      urlTemplate: 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}',
      additionalOptions: {
        'accessToken': mapboxToken,
        'id': 'mapbox/streets-v11',
      },
    ),
    PolygonLayer(
      polygons: secteurs.map((secteur) => Polygon(
        points: secteur.polygone,
        color: Color(int.parse(secteur.couleur)),
        borderColor: Colors.black,
        borderStrokeWidth: 2.0,
      )).toList(),
    ),
  ],
)

💬 Chat intégré

Configuration MQTT

class ChatService {
  late MqttClient client;
  
  Future<void> connect() async {
    client = MqttClient('mqtt://broker-url', 'client-id');
    await client.connect();
    
    client.subscribe('geosector/chat', MqttQos.atLeastOnce);
    client.updates!.listen((messages) {
      // Traitement des messages
    });
  }
}

🔐 Authentification

Gestion des rôles

class AuthProvider extends ChangeNotifier {
  Utilisateur? _currentUser;
  
  bool get isAdmin => _currentUser?.role == 'admin';
  bool get isAuthenticated => _currentUser != null;
  
  Future<void> login(String email, String password) async {
    // Logique d'authentification
  }
  
  void logout() {
    _currentUser = null;
    notifyListeners();
  }
}

📱 Interface utilisateur

Thème de l'application

class AppTheme {
  static ThemeData get lightTheme => ThemeData(
    primarySwatch: Colors.red,
    appBarTheme: AppBarTheme(
      backgroundColor: Colors.red[700],
      elevation: 0,
    ),
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        backgroundColor: Colors.red[700],
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(8),
        ),
      ),
    ),
  );
}

🔄 Synchronisation des données

Repository Pattern

class SecteurRepository {
  final SecteurLocalDataSource _localDataSource;
  final SecteurRemoteDataSource _remoteDataSource;
  
  Future<List<Secteur>> getAllSecteurs() async {
    try {
      // Essayer de récupérer depuis l'API
      final remoteSecteurs = await _remoteDataSource.getAllSecteurs();
      await _localDataSource.cacheSecteurs(remoteSecteurs);
      return remoteSecteurs;
    } catch (e) {
      // Fallback sur le cache local
      return await _localDataSource.getAllSecteurs();
    }
  }
}

🧪 Tests

Tests unitaires

flutter test

Tests d'intégration

flutter test integration_test/

📚 Documentation

🤝 Contribution

  1. Fork le projet
  2. Créer une branche feature (git checkout -b feature/AmazingFeature)
  3. Commit vos changements (git commit -m 'Add some AmazingFeature')
  4. Push vers la branche (git push origin feature/AmazingFeature)
  5. Ouvrir une Pull Request

📄 Licence

Distribué sous la licence MIT. Voir LICENSE pour plus d'informations.

👥 Équipe

📞 Support

Pour toute question ou problème :


GEOSECTOR - Simplifiant la gestion des distributions de calendriers pour les amicales de pompiers 🚒