# Module Chat - Documentation API ## Vue d'ensemble Le module Chat permet aux utilisateurs de l'application GeoSector de communiquer entre eux via une messagerie intégrée. Il supporte les conversations privées, de groupe et les diffusions (broadcast). ## Architecture ### Tables de base de données - `chat_rooms` : Salles de conversation - `chat_messages` : Messages échangés - `chat_participants` : Participants aux conversations - `chat_read_receipts` : Accusés de lecture ### Permissions par rôle | Rôle | Permissions | |------|------------| | **1 - Utilisateur** | Conversations privées et groupes avec membres de son entité | | **2 - Admin entité** | Toutes conversations de son entité + création de diffusions | | **> 2 - Super admin** | Accès total à toutes les conversations | ## Flux d'utilisation du module Chat ### 📱 Vue d'ensemble du flux Le module Chat fonctionne en mode **chargement dynamique** : les données sont récupérées à la demande, pas toutes en une fois au login. ### 1. Au login (`/api/login`) La réponse du login contient un objet `chat` avec les informations de base : ```json { "status": "success", "user": {...}, "amicale": {...}, "chat": { "total_rooms": 5, // Nombre total de conversations "unread_messages": 12, // Total messages non lus "chat_enabled": true, // Module activé pour cet utilisateur "last_active_room": { // Dernière conversation active "id": "uuid-room-123", "title": "Discussion équipe", "type": "group", "last_message": "À demain !", "last_message_at": "2025-01-17 18:30:00" } } } ``` → Permet d'afficher un **badge de notification** et de savoir si le chat est disponible ### 2. Ouverture de la page Chat #### Étape 1 : Chargement initial ``` GET /api/chat/rooms ``` → Récupère la liste des conversations avec aperçu du dernier message #### Étape 2 : Sélection d'une conversation ``` GET /api/chat/rooms/{room_id}/messages?limit=50 ``` → Charge les 50 derniers messages (pagination disponible) #### Étape 3 : Marquage comme lu ``` POST /api/chat/rooms/{room_id}/read ``` → Met à jour les compteurs de messages non lus ### 3. Actions utilisateur | Action | Endpoint | Description | |--------|----------|-------------| | **Envoyer un message** | `POST /api/chat/rooms/{id}/messages` | Envoie et retourne le message créé | | **Créer une conversation** | `POST /api/chat/rooms` | Crée une nouvelle room | | **Obtenir les destinataires** | `GET /api/chat/recipients` | Liste des contacts disponibles | | **Charger plus de messages** | `GET /api/chat/rooms/{id}/messages?before={msg_id}` | Pagination | ### 4. Stratégies de rafraîchissement #### Polling (recommandé pour débuter) - Rafraîchir `/api/chat/rooms` toutes les 30 secondes - Rafraîchir les messages de la conversation active toutes les 10 secondes #### Pull to refresh - Permettre à l'utilisateur de rafraîchir manuellement #### Lifecycle events - Recharger quand l'app revient au premier plan - Rafraîchir après envoi d'un message ### 5. Exemple d'implémentation Flutter ```dart class ChatService { Timer? _roomsTimer; Timer? _messagesTimer; // 1. Au login, stocker les infos de base void initFromLogin(Map chatData) { _unreadCount = chatData['unread_messages']; _chatEnabled = chatData['chat_enabled']; notifyListeners(); } // 2. À l'ouverture du chat Future openChatPage() async { // Charger les conversations final rooms = await api.get('/api/chat/rooms'); _rooms = rooms['rooms']; // Démarrer le polling _startPolling(); } // 3. Sélection d'une conversation Future selectRoom(String roomId) async { // Charger les messages final response = await api.get('/api/chat/rooms/$roomId/messages'); _currentMessages = response['messages']; // Marquer comme lu await api.post('/api/chat/rooms/$roomId/read'); // Rafraîchir plus fréquemment cette conversation _startMessagePolling(roomId); } // 4. Polling automatique void _startPolling() { _roomsTimer = Timer.periodic(Duration(seconds: 30), (_) { _refreshRooms(); }); } // 5. Nettoyage void dispose() { _roomsTimer?.cancel(); _messagesTimer?.cancel(); } } ``` ## Endpoints API ### 1. GET /api/chat/rooms **Description** : Récupère la liste des conversations de l'utilisateur **Réponse** : ```json { "status": "success", "rooms": [ { "id": "uuid-room-1", "title": "Discussion équipe", "type": "group", "created_at": "2025-01-17 10:00:00", "created_by": 123, "updated_at": "2025-01-17 14:30:00", "last_message": "Bonjour tout le monde", "last_message_at": "2025-01-17 14:30:00", "unread_count": 3, "participant_count": 5, "participants": [ { "user_id": 123, "name": "Jean Dupont", "first_name": "Jean", "is_admin": true } ] } ] } ``` ### 2. POST /api/chat/rooms **Description** : Crée une nouvelle conversation **Body** : ```json { "type": "private|group|broadcast", "title": "Titre optionnel (requis pour group/broadcast)", "participants": [456, 789], // IDs des participants "initial_message": "Message initial optionnel" } ``` **Règles** : - `private` : Maximum 2 participants (incluant le créateur) - `group` : Plusieurs participants possibles - `broadcast` : Réservé aux admins (rôle >= 2) **Réponse** : ```json { "status": "success", "room": { "id": "uuid-new-room", "title": "Nouvelle conversation", "type": "group", "created_at": "2025-01-17 15:00:00", "participants": [...] }, "existing": false // true si conversation privée existante trouvée } ``` ### 3. GET /api/chat/rooms/{id}/messages **Description** : Récupère les messages d'une conversation **Paramètres** : - `limit` : Nombre de messages (défaut: 50, max: 100) - `before` : ID du message pour pagination **Réponse** : ```json { "status": "success", "messages": [ { "id": "uuid-message-1", "content": "Bonjour !", "sender_id": 123, "sender_name": "Jean Dupont", "sender_first_name": "Jean", "sent_at": "2025-01-17 14:00:00", "edited_at": null, "is_deleted": false, "is_read": true, "is_mine": false, "read_count": 3 } ], "has_more": true } ``` ### 4. POST /api/chat/rooms/{id}/messages **Description** : Envoie un message dans une conversation **Body** : ```json { "content": "Contenu du message (max 5000 caractères)" } ``` **Réponse** : ```json { "status": "success", "message": { "id": "uuid-new-message", "content": "Message envoyé", "sender_id": 123, "sender_name": "Jean Dupont", "sent_at": "2025-01-17 15:30:00", "is_mine": true, "is_read": false, "read_count": 0 } } ``` ### 5. POST /api/chat/rooms/{id}/read **Description** : Marque les messages comme lus **Body (optionnel)** : ```json { "message_ids": ["uuid-1", "uuid-2"] // Si omis, marque tous les messages } ``` **Réponse** : ```json { "status": "success", "unread_count": 0 // Nombre de messages non lus restants } ``` ### 6. GET /api/chat/recipients **Description** : Liste des destinataires possibles pour créer une conversation **Réponse** : ```json { "status": "success", "recipients": [ { "id": 456, "name": "Marie Martin", "first_name": "Marie", "role": 1, "entite_id": 5 } ], "recipients_by_entity": { "Amicale de Grenoble": [ {...} ], "Amicale de Lyon": [ {...} ] } } ``` ## Fonctionnalités clés ### 1. Types de conversations #### Private (Conversation privée) - Entre 2 utilisateurs uniquement - Détection automatique de conversation existante - Pas de titre requis #### Group (Groupe) - Plusieurs participants - Titre optionnel mais recommandé - Admin de groupe (créateur) #### Broadcast (Diffusion) - Réservé aux admins (rôle >= 2) - Communication unidirectionnelle possible - Pour annonces importantes ### 2. Gestion des permissions Le système vérifie automatiquement : - L'appartenance à une conversation avant lecture/écriture - Les droits de création selon le type de conversation - La visibilité des destinataires selon le rôle ### 3. Statuts de lecture - **Accusés de lecture individuels** : Chaque message peut être marqué comme lu - **Compteur de non-lus** : Par conversation et global - **Last read** : Timestamp de dernière lecture par participant ### 4. Optimisations - **Pagination** : Chargement progressif des messages - **Index optimisés** : Pour les requêtes fréquentes - **Vue SQL** : Pour récupération rapide du dernier message ## Sécurité ### Chiffrement - Les noms d'utilisateurs sont stockés chiffrés (AES-256) - Déchiffrement à la volée lors de la lecture ### Validation - Longueur maximale des messages : 5000 caractères - Trim automatique du contenu - Vérification des permissions à chaque action ### Isolation - Les utilisateurs ne voient que leurs conversations autorisées - Filtrage par entité selon le rôle - Soft delete pour conservation de l'historique ## Migration Exécuter le script SQL : ```bash mysql -u root -p geo_app < scripts/sql/create_chat_tables.sql ``` ## Évolutions futures possibles 1. **Notifications push** : Intégration avec Firebase/WebSocket 2. **Fichiers joints** : Support d'images et documents 3. **Réactions** : Emojis sur les messages 4. **Mentions** : @username pour notifier 5. **Recherche** : Dans l'historique des messages 6. **Chiffrement E2E** : Pour conversations sensibles 7. **Statuts de présence** : En ligne/Hors ligne 8. **Indicateur de frappe** : "X est en train d'écrire..." ## Tests ### Cas de test recommandés 1. **Création de conversation privée** - Vérifier la détection de conversation existante - Tester avec utilisateurs de différentes entités 2. **Envoi de messages** - Messages avec caractères UTF-8 (émojis, accents) - Messages très longs (limite 5000) - Messages vides (doivent être rejetés) 3. **Marquage comme lu** - Marquer messages spécifiques - Marquer tous les messages d'une room - Vérifier les compteurs 4. **Permissions** - Utilisateur simple ne peut pas créer de broadcast - Accès refusé aux conversations non autorisées - Filtrage correct des destinataires ## Support Pour toute question ou problème : - Vérifier les logs dans `/logs/` - Consulter les tables `chat_*` en base de données - Tester avec les scripts de test fournis