Files
unionflow-mobile-apps/docs/DATA_CONSISTENCY.md
dahoud d094d6db9c Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
2026-03-15 16:30:08 +00:00

69 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 laffichage.
- **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.