Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts). Signed-off-by: lions dev Team
This commit is contained in:
68
docs/DATA_CONSISTENCY.md
Normal file
68
docs/DATA_CONSISTENCY.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Cohérence des données — UnionFlow Mobile
|
||||
|
||||
Ce document décrit les conventions et alignements API ↔ app pour éviter les incohérences.
|
||||
|
||||
## 1. Configuration
|
||||
|
||||
- **API** : `AppConfig.apiBaseUrl` (initialisé dans `main()` via `AppConfig.initialize()`). Utilisé par `ApiClient` (Dio `baseUrl`).
|
||||
- **Keycloak** : `AppConfig.keycloakBaseUrl`, `keycloakRealmUrl`, `keycloakTokenUrl`.
|
||||
- Toutes les requêtes passent par le même `ApiClient` (token, refresh, timeouts).
|
||||
|
||||
## 2. Membres (Annuaire)
|
||||
|
||||
| Backend (MembreSummaryResponse / PagedResponse) | Mobile (MembreCompletModel / repository) |
|
||||
|-------------------------------------------------|------------------------------------------|
|
||||
| `data` (liste), `total`, `page`, `size`, `totalPages` | `_parseMembreSearchResult` lit `data`, `total` (num→int), `page`, `size`, `totalPages` |
|
||||
| `associationNom` | Normalisé → `organisationNom` dans `_normalizeAndParseMembre` |
|
||||
| `statutCompte` ("ACTIF", etc.) | Normalisé → `statut` (enum StatutMembre) |
|
||||
| `photoUrl` (MembreResponse détail) | Normalisé → `photo` si absent |
|
||||
| `id`, `organisationId` (UUID) | Convertis en `String` avant `fromJson` |
|
||||
| `nom`, `prenom`, `email` requis | Modèle : champs requis ; summary backend les envoie toujours |
|
||||
|
||||
- **Liste paginée** : GET `/api/membres?page=&size=` → réponse `PagedResponse` avec `data`, `total`, `page`, `size`, `totalPages`.
|
||||
- **Recherche** : GET `/api/membres/recherche?q=&page=&size=` → liste ou même structure paginée selon backend.
|
||||
- **Affichage annuaire** : `members_page_wrapper` convertit `MembreCompletModel` en `Map` avec `status` = libellé français (Actif, En attente, etc.) via `_mapStatutToString(statut)`.
|
||||
|
||||
## 3. Cotisations (Contributions)
|
||||
|
||||
- **Mes cotisations** : GET `/api/cotisations/mes-cotisations?page=&size=` → backend renvoie une **liste** (pas un objet paginé). Le repository gère `data is List`.
|
||||
- **En attente** : GET `/api/cotisations/mes-cotisations/en-attente` → liste. Le repository accepte aussi `data['data']` ou `data['content']` si le format change.
|
||||
- Modèle : `ContributionModel` avec `id`, `statut`, `montantDu`, `montantPaye`, `dateEcheance`, `nomMembre`, etc. alignés sur les champs backend. Côté mobile, `membreNom` utilise `nomMembre` avec fallback sur `nomCompletMembre` (Summary vs Response).
|
||||
|
||||
## 4. Épargne
|
||||
|
||||
- **Comptes** : GET `/api/v1/epargne/comptes/mes-comptes` → liste de comptes. `CompteEpargneModel` : `id`, `membreId`, `organisationId` en `String` (backend UUID sérialisé).
|
||||
- **Transactions** : GET `/api/v1/epargne/transactions/compte/{compteId}` → liste. `TransactionEpargneModel.fromJson` avec `_toDouble` pour montants.
|
||||
- Tous les IDs (compte, membre, org) sont traités en `String` côté mobile (`toString()` si besoin).
|
||||
|
||||
## 5. Organisations
|
||||
|
||||
- **Mes organisations** : GET `/api/organisations/mes` → liste. `OrganizationModel` avec `id`, `nom`, `nomCourt`, etc.
|
||||
- **Liste (admin)** : GET `/api/organisations?page=&size=` → liste ou paginée selon endpoint. Repository parse `response.data as List` ou structure paginée.
|
||||
|
||||
## 6. Admin utilisateurs (SUPER_ADMIN)
|
||||
|
||||
- **Liste** : GET `/api/admin/users?page=&size=&search=` → UnionFlow renvoie `UserSearchResultDTO` (proxy lions-user-manager). Structure vérifiée dans `lions-user-manager-server-api` :
|
||||
- **UserSearchResultDTO** : `users` (List\<UserDTO\>), `totalCount` (Long), `currentPage` (Integer), `pageSize` (Integer), `totalPages` (Integer), plus optionnels (`hasNextPage`, `criteria`, `executionTimeMs`, etc.).
|
||||
- **UserDTO** (BaseDTO + champs) : `id`, `username`, `email`, `prenom`, `nom`, `enabled`, `realmRoles` (List\<String\>), `statut`, `dateCreation`, etc.
|
||||
- Le repository mobile lit `data['users']`, `totalCount`, `currentPage`, `pageSize`, `totalPages` (avec cast `num` → int) et parse chaque élément avec `AdminUserModel.fromJson`. Alignement confirmé.
|
||||
- **Associer organisation** : POST `/api/admin/associer-organisation` avec body `{ "email", "organisationId" }`.
|
||||
|
||||
## 7. Dashboard
|
||||
|
||||
- **Avec organisation** : appel avec `organizationId` et `userId` (chaînes). `DashboardEntity` / `DashboardStatsModel` alignés sur les réponses backend.
|
||||
- **Membre sans org** : GET `/api/dashboard/membre/me` → `MembreDashboardSyntheseModel`, mappé vers la même `DashboardEntity` pour réutilisation UI.
|
||||
|
||||
## 8. Bonnes pratiques
|
||||
|
||||
- **IDs** : toujours normaliser en `String` côté mobile (`.toString()`) pour UUID backend.
|
||||
- **Pagination** : préférer `(data['total'] as num?)?.toInt()` pour accepter `int` ou `double` selon la sérialisation JSON.
|
||||
- **Statut / libellé** : backend envoie souvent `statutCompte` + `statutCompteLibelle` ; le mobile peut normaliser `statutCompte` → `statut` (enum) et utiliser les libellés pour l’affichage.
|
||||
- **Noms de champs** : garder une seule normalisation dans le repository (ex. `_normalizeAndParseMembre`) pour éviter les doublons (associationNom, photoUrl, statutCompte, etc.).
|
||||
|
||||
## 9. Vérifications effectuées
|
||||
|
||||
- Membres : PagedResponse `data`/`total`/`page`/`size`/`totalPages` alignés ; normalisation associationNom, statutCompte, photoUrl, id/organisationId.
|
||||
- Cotisations : liste directe pour mes-cotisations et en-attente.
|
||||
- Épargne : IDs en string, montants avec _toDouble.
|
||||
- Config : une seule base URL et un seul ApiClient.
|
||||
Reference in New Issue
Block a user