- 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>
357 lines
13 KiB
Markdown
Executable File
357 lines
13 KiB
Markdown
Executable File
# Modèles de données GEOSECTOR
|
|
|
|
## Description générale
|
|
|
|
GEOSECTOR utilise plusieurs modèles de données pour représenter les entités principales de l'application. Ces modèles sont utilisés à la fois pour la persistance locale via Hive et pour la communication avec l'API backend. Ce document décrit en détail chaque modèle, ses propriétés et ses méthodes.
|
|
|
|
## Intégration avec Hive
|
|
|
|
Tous les modèles sont annotés pour être utilisés avec Hive, une base de données NoSQL légère:
|
|
|
|
- Chaque modèle a un `typeId` unique pour Hive
|
|
- Les propriétés sont annotées avec `@HiveField` et un index unique
|
|
- Les modèles étendent `HiveObject` pour accéder aux fonctionnalités de persistance
|
|
|
|
## Modèle Utilisateur (UserModel)
|
|
|
|
**Description**: Représente un utilisateur de l'application, avec ses informations personnelles et de session.
|
|
|
|
### Propriétés
|
|
|
|
| Propriété | Type | Description | Hive Index |
|
|
| ------------- | --------- | ----------------------------------------- | ---------- |
|
|
| id | int | Identifiant unique | 0 |
|
|
| email | String | Adresse email | 1 |
|
|
| name | String? | Nom de l'utilisateur | 2 |
|
|
| username | String? | Nom d'utilisateur pour connexion | 11 |
|
|
| firstName | String? | Prénom de l'utilisateur | 10 |
|
|
| role | int | Rôle/niveau d'accès (1=user, 2/4/9=admin) | 3 |
|
|
| createdAt | DateTime | Date de création du compte | 4 |
|
|
| lastSyncedAt | DateTime | Dernière synchronisation avec le serveur | 5 |
|
|
| isActive | bool | Statut actif/inactif | 6 |
|
|
| isSynced | bool | Indique si synchronisé avec le serveur | 7 |
|
|
| sessionId | String? | Identifiant de session pour l'API | 8 |
|
|
| sessionExpiry | DateTime? | Date d'expiration de la session | 9 |
|
|
| lastPath | String? | Dernier chemin visité dans l'app | 12 |
|
|
| sectName | String? | Nom de la section/département | 13 |
|
|
| interface | String? | Type d'interface ('admin' ou 'user') | 14 |
|
|
|
|
### Méthodes
|
|
|
|
- **fromJson**: Convertit un objet JSON en UserModel
|
|
- **toJson**: Convertit un UserModel en objet JSON
|
|
- **copyWith**: Crée une copie avec des valeurs modifiées
|
|
- **hasValidSession**: Vérifie si la session est valide
|
|
- **clearSession**: Efface les données de session
|
|
|
|
### Exemple d'utilisation
|
|
|
|
```dart
|
|
// Créer un utilisateur
|
|
final user = UserModel(
|
|
id: 123,
|
|
email: "user@example.com",
|
|
name: "John Doe",
|
|
username: "johndoe",
|
|
role: 1,
|
|
createdAt: DateTime.now(),
|
|
lastSyncedAt: DateTime.now(),
|
|
isActive: true,
|
|
);
|
|
|
|
// Vérifier la validité de la session
|
|
if (user.hasValidSession) {
|
|
// Utiliser la session...
|
|
}
|
|
|
|
// Créer une version modifiée
|
|
final updatedUser = user.copyWith(
|
|
name: "John Smith",
|
|
isActive: false,
|
|
);
|
|
```
|
|
|
|
## Modèle Opération (OperationModel)
|
|
|
|
**Description**: Représente une opération de collecte avec ses dates et son statut.
|
|
|
|
### Propriétés
|
|
|
|
| Propriété | Type | Description | Hive Index |
|
|
| ------------ | -------- | ---------------------------------------- | ---------- |
|
|
| id | int | Identifiant unique | 0 |
|
|
| name | String | Nom de l'opération | 1 |
|
|
| dateDebut | DateTime | Date de début de l'opération | 2 |
|
|
| dateFin | DateTime | Date de fin de l'opération | 3 |
|
|
| lastSyncedAt | DateTime | Dernière synchronisation avec le serveur | 4 |
|
|
| isActive | bool | Statut actif/inactif | 5 |
|
|
| isSynced | bool | Indique si synchronisé avec le serveur | 6 |
|
|
|
|
### Méthodes
|
|
|
|
- **fromJson**: Convertit un objet JSON en OperationModel
|
|
- **toJson**: Convertit un OperationModel en objet JSON
|
|
- **copyWith**: Crée une copie avec des valeurs modifiées
|
|
|
|
### Exemple d'utilisation
|
|
|
|
```dart
|
|
// Créer une opération
|
|
final operation = OperationModel(
|
|
id: 456,
|
|
name: "Opération 2025",
|
|
dateDebut: DateTime(2025, 1, 1),
|
|
dateFin: DateTime(2025, 12, 31),
|
|
lastSyncedAt: DateTime.now(),
|
|
isActive: true,
|
|
);
|
|
|
|
// Créer une version modifiée
|
|
final updatedOperation = operation.copyWith(
|
|
name: "Opération 2025 - Printemps",
|
|
dateDebut: DateTime(2025, 3, 1),
|
|
dateFin: DateTime(2025, 6, 30),
|
|
);
|
|
```
|
|
|
|
## Modèle Secteur (SectorModel)
|
|
|
|
**Description**: Représente un secteur géographique avec ses coordonnées et son style.
|
|
|
|
### Propriétés
|
|
|
|
| Propriété | Type | Description | Hive Index |
|
|
| --------- | ------ | -------------------------------------------- | ---------- |
|
|
| id | int | Identifiant unique | 0 |
|
|
| libelle | String | Nom du secteur | 1 |
|
|
| color | String | Couleur au format hexadécimal (#RRGGBB) | 2 |
|
|
| sector | String | Coordonnées du polygone au format spécifique | 3 |
|
|
|
|
### Méthodes
|
|
|
|
- **fromJson**: Convertit un objet JSON en SectorModel
|
|
- **toJson**: Convertit un SectorModel en objet JSON
|
|
- **copyWith**: Crée une copie avec des valeurs modifiées
|
|
- **getCoordinates**: Extrait les coordonnées du polygone sous forme de liste
|
|
|
|
### Format des coordonnées
|
|
|
|
Le champ `sector` stocke les coordonnées du polygone dans un format spécifique:
|
|
|
|
```
|
|
lat1/lng1#lat2/lng2#lat3/lng3#...
|
|
```
|
|
|
|
Par exemple:
|
|
|
|
```
|
|
48.8566/2.3522#48.8567/2.3520#48.8565/2.3518#48.8564/2.3521#48.8566/2.3522
|
|
```
|
|
|
|
### Exemple d'utilisation
|
|
|
|
```dart
|
|
// Créer un secteur
|
|
final sector = SectorModel(
|
|
id: 789,
|
|
libelle: "Secteur Nord",
|
|
color: "#FF5733",
|
|
sector: "48.8566/2.3522#48.8567/2.3520#48.8565/2.3518#48.8564/2.3521#48.8566/2.3522",
|
|
);
|
|
|
|
// Obtenir les coordonnées du secteur
|
|
final coordinates = sector.getCoordinates();
|
|
// Résultat: [[48.8566, 2.3522], [48.8567, 2.3520], [48.8565, 2.3518], ...]
|
|
```
|
|
|
|
## Modèle Membre (MembreModel)
|
|
|
|
**Description**: Représente un membre de l'organisation, utilisé uniquement dans l'interface admin.
|
|
|
|
### Propriétés
|
|
|
|
| Propriété | Type | Description | Hive Index |
|
|
| ------------- | --------- | -------------------------------- | ---------- |
|
|
| id | int | Identifiant unique | 0 |
|
|
| fkRole | int | ID du rôle du membre | 1 |
|
|
| fkTitre | int | ID du titre (civilité) du membre | 2 |
|
|
| firstName | String | Prénom du membre | 3 |
|
|
| sectName | String? | Nom de la section/département | 4 |
|
|
| dateNaissance | DateTime? | Date de naissance | 5 |
|
|
| dateEmbauche | DateTime? | Date d'embauche | 6 |
|
|
| chkActive | int | Statut actif (1) ou inactif (0) | 7 |
|
|
| name | String | Nom de famille du membre | 8 |
|
|
| username | String | Nom d'utilisateur pour connexion | 9 |
|
|
| email | String | Adresse email | 10 |
|
|
|
|
### Méthodes
|
|
|
|
- **fromJson**: Convertit un objet JSON en MembreModel
|
|
- **toJson**: Convertit un MembreModel en objet JSON
|
|
- **copyWith**: Crée une copie avec des valeurs modifiées
|
|
|
|
### Exemple d'utilisation
|
|
|
|
```dart
|
|
// Créer un membre
|
|
final membre = MembreModel(
|
|
id: 9999979,
|
|
fkRole: 1,
|
|
fkTitre: 1,
|
|
firstName: "Pierre",
|
|
sectName: "",
|
|
dateNaissance: DateTime.parse("1966-04-24"),
|
|
dateEmbauche: DateTime.parse("2017-12-01"),
|
|
chkActive: 0,
|
|
name: "VAISSAIRE",
|
|
username: "pv_mobile",
|
|
email: "pierre.vaissaire@d6soft.fr",
|
|
);
|
|
|
|
// Créer une version modifiée
|
|
final updatedMembre = membre.copyWith(
|
|
chkActive: 1,
|
|
sectName: "Section A",
|
|
);
|
|
```
|
|
|
|
## Modèle Passage (PassageModel)
|
|
|
|
**Description**: Représente un passage effectué chez un habitant avec toutes les informations associées.
|
|
|
|
### Propriétés
|
|
|
|
| Propriété | Type | Description | Hive Index |
|
|
| --------------- | -------- | --------------------------------------------- | ---------- |
|
|
| id | int | Identifiant unique | 0 |
|
|
| fkOperation | int | ID de l'opération associée | 1 |
|
|
| fkSector | int | ID du secteur | 2 |
|
|
| fkUser | int | ID de l'utilisateur qui a effectué le passage | 3 |
|
|
| fkType | int | Type de passage (1-6) | 4 |
|
|
| fkAdresse | String | Identifiant de l'adresse | 5 |
|
|
| passedAt | DateTime | Date et heure du passage | 6 |
|
|
| numero | String | Numéro de rue | 7 |
|
|
| rue | String | Nom de la rue | 8 |
|
|
| rueBis | String | Complément de rue | 9 |
|
|
| ville | String | Ville | 10 |
|
|
| residence | String | Nom de la résidence | 11 |
|
|
| fkHabitat | int | Type d'habitat | 12 |
|
|
| appt | String | Numéro d'appartement | 13 |
|
|
| niveau | String | Niveau/étage | 14 |
|
|
| gpsLat | String | Latitude GPS | 15 |
|
|
| gpsLng | String | Longitude GPS | 16 |
|
|
| nomRecu | String | Nom du fichier de reçu | 17 |
|
|
| remarque | String | Remarques/commentaires | 18 |
|
|
| montant | String | Montant collecté | 19 |
|
|
| fkTypeReglement | int | Type de règlement (0-3) | 20 |
|
|
| emailErreur | String | Message d'erreur pour l'envoi par email | 21 |
|
|
| nbPassages | int | Nombre de passages à cette adresse | 22 |
|
|
| name | String | Nom de l'habitant | 23 |
|
|
| email | String | Email de l'habitant | 24 |
|
|
| phone | String | Téléphone de l'habitant | 25 |
|
|
| lastSyncedAt | DateTime | Dernière synchronisation avec le serveur | 26 |
|
|
| isActive | bool | Statut actif/inactif | 27 |
|
|
| isSynced | bool | Indique si synchronisé avec le serveur | 28 |
|
|
|
|
### Types de passages
|
|
|
|
| ID | Description | Couleur |
|
|
| --- | ----------- | ---------- |
|
|
| 1 | Effectué | Vert |
|
|
| 2 | À finaliser | Orange |
|
|
| 3 | Refusé | Rouge |
|
|
| 4 | Don | Bleu ciel |
|
|
| 5 | Lot | Bleu foncé |
|
|
| 6 | Maison vide | Gris |
|
|
|
|
### Types de règlements
|
|
|
|
| ID | Description | Couleur |
|
|
| --- | ---------------- | ------- |
|
|
| 0 | Pas de règlement | Gris |
|
|
| 1 | Espèce | Jaune |
|
|
| 2 | Chèque | Vert |
|
|
| 3 | CB | Bleu |
|
|
|
|
### Méthodes
|
|
|
|
- **fromJson**: Convertit un objet JSON en PassageModel
|
|
- **toJson**: Convertit un PassageModel en objet JSON
|
|
- **copyWith**: Crée une copie avec des valeurs modifiées
|
|
- **toString**: Représentation textuelle pour débogage
|
|
|
|
### Exemple d'utilisation
|
|
|
|
```dart
|
|
// Créer un passage
|
|
final passage = PassageModel(
|
|
id: 1001,
|
|
fkOperation: 456,
|
|
fkSector: 789,
|
|
fkUser: 123,
|
|
fkType: 1, // Effectué
|
|
fkAdresse: "ADRESSE-123",
|
|
passedAt: DateTime.now(),
|
|
numero: "12",
|
|
rue: "Rue des Lilas",
|
|
ville: "Paris",
|
|
gpsLat: "48.8566",
|
|
gpsLng: "2.3522",
|
|
montant: "25.50",
|
|
fkTypeReglement: 2, // Chèque
|
|
nbPassages: 1,
|
|
name: "Dupont",
|
|
lastSyncedAt: DateTime.now(),
|
|
);
|
|
|
|
// Créer une version modifiée
|
|
final updatedPassage = passage.copyWith(
|
|
montant: "30.00",
|
|
remarque: "Client fidèle",
|
|
);
|
|
```
|
|
|
|
## Relations entre les modèles
|
|
|
|
Les modèles sont reliés entre eux par des clés étrangères:
|
|
|
|
1. **PassageModel**:
|
|
|
|
- `fkOperation` → `OperationModel.id`
|
|
- `fkSector` → `SectorModel.id`
|
|
- `fkUser` → `UserModel.id`
|
|
|
|
2. **SectorModel**:
|
|
|
|
- Lié aux opérations via les passages
|
|
|
|
3. **OperationModel**:
|
|
|
|
- Contient des secteurs et des passages
|
|
|
|
4. **UserModel**:
|
|
- Possède des passages
|
|
|
|
## Gestion de la synchronisation
|
|
|
|
Tous les modèles principaux possèdent les propriétés de synchronisation:
|
|
|
|
- `isSynced`: Indique si l'objet a été synchronisé avec le serveur
|
|
- `lastSyncedAt`: Date de dernière synchronisation
|
|
|
|
Cette approche permet le travail hors ligne et la synchronisation ultérieure des modifications.
|
|
|
|
## Stockage Hive
|
|
|
|
Les modèles sont stockés dans des "boxes" Hive distinctes:
|
|
|
|
| Modèle | Nom de la box | Type ID |
|
|
| -------------- | ------------- | ------- |
|
|
| UserModel | users | 0 |
|
|
| OperationModel | operations | 1 |
|
|
| SectorModel | sectors | 3 |
|
|
| PassageModel | passages | 4 |
|
|
| MembreModel | membres | 5 |
|
|
|
|
Les boxes sont initialisées au démarrage de l'application ou lors de la connexion d'un utilisateur.
|