213 lines
6.1 KiB
Markdown
213 lines
6.1 KiB
Markdown
|
|
# 🔍 Audit Initial - Message Search, History Pagination, and Offline Sync
|
||
|
|
|
||
|
|
**Date**: 2025-12-05
|
||
|
|
**Objectif**: Analyser l'état actuel avant implémentation des fonctionnalités P1
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. AUDIT DES FONCTIONNALITÉS EXISTANTES
|
||
|
|
|
||
|
|
### 1.1 Recherche de messages
|
||
|
|
**❌ N'EXISTE PAS**
|
||
|
|
- Aucune fonction dans `MessageRepository` pour rechercher des messages
|
||
|
|
- Aucune route WebSocket ou REST pour la recherche
|
||
|
|
- Aucun index de recherche textuelle sur la colonne `content`
|
||
|
|
|
||
|
|
### 1.2 Pagination de l'historique
|
||
|
|
**⚠️ PARTIELLEMENT EXISTANT**
|
||
|
|
- `MessageRepository::get_conversation_messages()` existe mais :
|
||
|
|
- Ne supporte que `LIMIT` (pas de cursors `before`/`after`)
|
||
|
|
- Ne retourne pas `has_more_before`/`has_more_after`
|
||
|
|
- Tri toujours `DESC` sans possibilité de tri `ASC` pour `after`
|
||
|
|
- Aucune route WebSocket pour `FetchHistory`
|
||
|
|
|
||
|
|
### 1.3 Synchronisation hors ligne
|
||
|
|
**❌ N'EXISTE PAS**
|
||
|
|
- Aucune fonction pour récupérer les messages depuis un timestamp
|
||
|
|
- Aucune route WebSocket pour `SyncMessages`
|
||
|
|
- Pas de mécanisme pour tracker le dernier timestamp de sync
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. AUDIT DES INDEX SQL
|
||
|
|
|
||
|
|
### 2.1 Index existants sur `messages`
|
||
|
|
```sql
|
||
|
|
-- Migration 001
|
||
|
|
idx_messages_conversation_id ON messages(conversation_id)
|
||
|
|
idx_messages_sender_id ON messages(sender_id)
|
||
|
|
idx_messages_created_at ON messages(created_at)
|
||
|
|
|
||
|
|
-- Migration 005
|
||
|
|
idx_messages_deleted_at ON messages(deleted_at) WHERE deleted_at IS NOT NULL
|
||
|
|
idx_messages_edited_at ON messages(edited_at) WHERE edited_at IS NOT NULL
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.2 Index manquants (REQUIS)
|
||
|
|
**❌ Index composite pour pagination**
|
||
|
|
```sql
|
||
|
|
CREATE INDEX idx_messages_conv_created_at
|
||
|
|
ON messages(conversation_id, created_at DESC);
|
||
|
|
```
|
||
|
|
|
||
|
|
**❌ Index GIN pour recherche textuelle**
|
||
|
|
```sql
|
||
|
|
-- Option 1: Index GIN avec tsvector (recherche avancée)
|
||
|
|
ALTER TABLE messages ADD COLUMN tsv tsvector;
|
||
|
|
CREATE INDEX idx_messages_tsv ON messages USING GIN(tsv);
|
||
|
|
|
||
|
|
-- Option 2: Index trigram pour recherche ILIKE (plus simple)
|
||
|
|
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||
|
|
CREATE INDEX idx_messages_content_trgm ON messages USING GIN(content gin_trgm_ops);
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. AUDIT DES CHAMPS DE TIMESTAMPS
|
||
|
|
|
||
|
|
### 3.1 Format stocké dans la table `messages`
|
||
|
|
- ✅ `edited_at`: `TIMESTAMP WITH TIME ZONE` (Option<DateTime<Utc>> en Rust)
|
||
|
|
- ✅ `deleted_at`: `TIMESTAMP WITH TIME ZONE` (Option<DateTime<Utc>> en Rust)
|
||
|
|
- ✅ `created_at`: `TIMESTAMP WITH TIME ZONE` (DateTime<Utc> en Rust)
|
||
|
|
- ✅ `updated_at`: `TIMESTAMP WITH TIME ZONE` (DateTime<Utc> en Rust)
|
||
|
|
|
||
|
|
### 3.2 Format stocké dans les tables séparées
|
||
|
|
- ✅ `read_at`: Dans `read_receipts` table (Migration 003)
|
||
|
|
- ✅ `delivered_at`: Dans `delivered_status` table (Migration 004)
|
||
|
|
|
||
|
|
**Note**: Les statuts `read` et `delivered` sont dans des tables séparées, pas dans `messages`. Pour la sync offline, il faudra joindre ces tables ou les inclure dans la réponse.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. AUDIT DES TYPES WEBSOCKET
|
||
|
|
|
||
|
|
### 4.1 IncomingMessage (src/websocket/mod.rs)
|
||
|
|
**Types existants**:
|
||
|
|
- `SendMessage`
|
||
|
|
- `JoinConversation`
|
||
|
|
- `LeaveConversation`
|
||
|
|
- `MarkAsRead`
|
||
|
|
- `Typing`
|
||
|
|
- `Delivered`
|
||
|
|
- `EditMessage`
|
||
|
|
- `DeleteMessage`
|
||
|
|
- `Ping`
|
||
|
|
|
||
|
|
**Types manquants**:
|
||
|
|
- ❌ `FetchHistory`
|
||
|
|
- ❌ `SearchMessages`
|
||
|
|
- ❌ `SyncMessages`
|
||
|
|
|
||
|
|
### 4.2 OutgoingMessage (src/websocket/mod.rs)
|
||
|
|
**Types existants**:
|
||
|
|
- `NewMessage`
|
||
|
|
- `MessageRead`
|
||
|
|
- `MessageDelivered`
|
||
|
|
- `UserTyping`
|
||
|
|
- `MessageEdited`
|
||
|
|
- `MessageDeleted`
|
||
|
|
- `ActionConfirmed`
|
||
|
|
- `Error`
|
||
|
|
- `Pong`
|
||
|
|
|
||
|
|
**Types manquants**:
|
||
|
|
- ❌ `HistoryChunk`
|
||
|
|
- ❌ `SearchResults`
|
||
|
|
- ❌ `SyncChunk`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. AUDIT DU REPOSITORY
|
||
|
|
|
||
|
|
### 5.1 MessageRepository (src/repository/message_repository.rs)
|
||
|
|
**Méthodes existantes**:
|
||
|
|
- ✅ `create()` - Créer un message
|
||
|
|
- ✅ `get_conversation_messages()` - Récupérer messages avec LIMIT
|
||
|
|
- ✅ `get_by_id()` - Récupérer un message par ID
|
||
|
|
- ✅ `update()` - Mettre à jour un message
|
||
|
|
- ✅ `delete()` - Soft delete un message
|
||
|
|
- ✅ `get_by_id_including_deleted()` - Récupérer même si supprimé
|
||
|
|
|
||
|
|
**Méthodes manquantes**:
|
||
|
|
- ❌ `fetch_history()` - Pagination avec before/after
|
||
|
|
- ❌ `search_messages()` - Recherche textuelle
|
||
|
|
- ❌ `fetch_since()` - Sync depuis timestamp
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. AUDIT DES PERMISSIONS
|
||
|
|
|
||
|
|
### 6.1 PermissionService (src/security/permission.rs)
|
||
|
|
**Méthodes existantes** (à vérifier):
|
||
|
|
- `can_send_message()`
|
||
|
|
- `can_read_conversation()`
|
||
|
|
- `can_join_conversation()`
|
||
|
|
- `can_mark_read()`
|
||
|
|
|
||
|
|
**Méthodes nécessaires**:
|
||
|
|
- ✅ Les méthodes existantes suffisent pour les nouvelles fonctionnalités
|
||
|
|
- La recherche nécessite `can_read_conversation()`
|
||
|
|
- La pagination nécessite `can_read_conversation()`
|
||
|
|
- La sync nécessite `can_read_conversation()`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. RÉSUMÉ DES ACTIONS REQUISES
|
||
|
|
|
||
|
|
### 7.1 Migration SQL
|
||
|
|
1. ✅ Créer index composite `(conversation_id, created_at DESC)`
|
||
|
|
2. ✅ Créer index GIN pour recherche textuelle (tsvector ou trigram)
|
||
|
|
3. ✅ Ajouter colonne `tsv` si choix tsvector
|
||
|
|
|
||
|
|
### 7.2 Repository
|
||
|
|
1. ✅ Implémenter `fetch_history()` avec before/after
|
||
|
|
2. ✅ Implémenter `search_messages()` avec query
|
||
|
|
3. ✅ Implémenter `fetch_since()` avec timestamp
|
||
|
|
|
||
|
|
### 7.3 WebSocket
|
||
|
|
1. ✅ Ajouter `FetchHistory`, `SearchMessages`, `SyncMessages` dans `IncomingMessage`
|
||
|
|
2. ✅ Ajouter `HistoryChunk`, `SearchResults`, `SyncChunk` dans `OutgoingMessage`
|
||
|
|
3. ✅ Implémenter handlers dans `websocket/handler.rs`
|
||
|
|
|
||
|
|
### 7.4 Tests
|
||
|
|
1. ✅ Tests unitaires pour chaque méthode repository
|
||
|
|
2. ✅ Tests d'intégration pour les handlers WebSocket
|
||
|
|
3. ✅ Tests de permissions
|
||
|
|
|
||
|
|
### 7.5 Documentation
|
||
|
|
1. ✅ Créer `docs/CHAT_HISTORY_SEARCH_SYNC.md`
|
||
|
|
2. ✅ Mettre à jour `TRIAGE.md`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. DÉCISIONS TECHNIQUES
|
||
|
|
|
||
|
|
### 8.1 Recherche textuelle
|
||
|
|
**Choix**: Commencer avec `ILIKE` (plus simple), possibilité d'upgrade vers `tsvector` plus tard.
|
||
|
|
|
||
|
|
**Raison**:
|
||
|
|
- Plus simple à implémenter
|
||
|
|
- Pas besoin de trigger pour maintenir `tsv`
|
||
|
|
- Suffisant pour la plupart des cas d'usage
|
||
|
|
|
||
|
|
### 8.2 Pagination
|
||
|
|
**Choix**: Cursors basés sur `created_at` (timestamp).
|
||
|
|
|
||
|
|
**Raison**:
|
||
|
|
- Plus fiable que les offsets
|
||
|
|
- Meilleure performance
|
||
|
|
- Supporte les insertions concurrentes
|
||
|
|
|
||
|
|
### 8.3 Sync offline
|
||
|
|
**Choix**: Récupérer tous les messages depuis `since`, inclure les updates (edited, deleted).
|
||
|
|
|
||
|
|
**Raison**:
|
||
|
|
- Permet une vraie synchronisation fiable
|
||
|
|
- Compatible avec les statuts edited/deleted
|
||
|
|
- Nécessaire pour les clients mobiles
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Fin de l'audit**
|
||
|
|
|