193 lines
7.5 KiB
Markdown
193 lines
7.5 KiB
Markdown
# Flow complet des tâches Leantime dans le widget Devoirs
|
|
|
|
## 1. BACKEND - API Route `/api/leantime/tasks` (app/api/leantime/tasks/route.ts)
|
|
|
|
### Étape 1.1 : Vérification de session
|
|
- **Ligne 91-95** : Vérifie la session utilisateur
|
|
- Si pas de session → retourne 401 Unauthorized
|
|
|
|
### Étape 1.2 : Vérification du cache Redis
|
|
- **Ligne 103-141** : Si `forceRefresh=false`, vérifie le cache Redis
|
|
- **Ligne 107-123** : **FILTRE 1** - Filtre les tâches "done" du cache :
|
|
- Statuts filtrés : `0`, `3`, `5` (ou strings `'0'`, `'3'`, `'5'`, `'Done'`, `'done'`, `'DONE'`)
|
|
- Si des tâches "done" sont trouvées dans le cache, elles sont supprimées
|
|
- Le cache est mis à jour avec les tâches filtrées
|
|
- Si cache valide → retourne les tâches filtrées du cache (ligne 139)
|
|
|
|
### Étape 1.3 : Récupération de l'ID utilisateur Leantime
|
|
- **Ligne 146** : `getLeantimeUserId(session.user.email)`
|
|
- Appelle l'API Leantime `leantime.rpc.users.getAll`
|
|
- Trouve l'utilisateur par `username === email`
|
|
- Retourne `user.id` ou `null`
|
|
|
|
### Étape 1.4 : Appel API Leantime
|
|
- **Ligne 165-178** : Appelle `leantime.rpc.tickets.getAll` avec :
|
|
- `userId: userId`
|
|
- `status: "all"` (récupère TOUTES les tâches, tous statuts confondus)
|
|
- **Ligne 193-195** : Log toutes les tâches brutes reçues de Leantime
|
|
|
|
### Étape 1.5 : Filtrage des tâches
|
|
- **Ligne 217-249** : **FILTRE 2** - Filtre les tâches :
|
|
|
|
**a) Filtre par statut "done" (ligne 223-240)** :
|
|
- Statuts filtrés : `0`, `3`, `5` (ou strings `'0'`, `'3'`, `'5'`, `'done'`)
|
|
- Si `isDone === true` → la tâche est exclue (`return false`)
|
|
|
|
**b) Filtre par éditeur (ligne 242-248)** :
|
|
- Seules les tâches où `task.editorId === userId` sont gardées
|
|
- Si `taskEditorId !== currentUserId` → la tâche est exclue
|
|
|
|
### Étape 1.6 : Transformation des données
|
|
- **Ligne 250-266** : Transforme les tâches Leantime en format standard :
|
|
```typescript
|
|
{
|
|
id: task.id.toString(),
|
|
headline: task.headline,
|
|
projectName: task.projectName,
|
|
projectId: task.projectId,
|
|
status: task.status, // ⚠️ LE STATUT EST INCLUS ICI
|
|
dateToFinish: task.dateToFinish || null,
|
|
milestone: task.type || null,
|
|
details: task.description || null,
|
|
createdOn: task.dateCreated,
|
|
editedOn: task.editedOn || null,
|
|
editorId: task.editorId,
|
|
editorFirstname: task.editorFirstname,
|
|
editorLastname: task.editorLastname,
|
|
type: task.type || null,
|
|
dependingTicketId: task.dependingTicketId || null
|
|
}
|
|
```
|
|
|
|
### Étape 1.7 : Mise en cache
|
|
- **Ligne 292** : Met en cache les tâches filtrées dans Redis
|
|
- **Ligne 294** : Retourne les tâches filtrées en JSON
|
|
|
|
---
|
|
|
|
## 2. FRONTEND - Widget Devoirs (components/flow.tsx)
|
|
|
|
### Étape 2.1 : Appel API
|
|
- **Ligne 107-113** : Appelle `/api/leantime/tasks` (ou `/api/leantime/tasks?refresh=true`)
|
|
- **Ligne 117-127** : Récupère les données JSON et les assigne à `leantimeTasks`
|
|
- **Ligne 121-126** : Log toutes les tâches reçues avec leur statut
|
|
|
|
### Étape 2.2 : Détection des tâches "done" (pour log uniquement)
|
|
- **Ligne 129-143** : Détecte les tâches avec statut `5` ou `'done'` (⚠️ NE FILTRE PAS LE STATUT 0)
|
|
- Affiche un warning si des tâches "done" sont trouvées
|
|
|
|
### Étape 2.3 : Analyse des statuts (pour log uniquement)
|
|
- **Ligne 164-178** : Crée `leantimeStatusDetails` avec calcul de `isDone`
|
|
- **Ligne 168** : `isDone = statusNum === 0 || statusNum === 3 || statusNum === 5 || ...`
|
|
- **Ligne 193** : Filtre les tâches "done" pour le log `doneTasksCount`
|
|
- **Ligne 201-206** : Log le breakdown des statuts
|
|
|
|
### Étape 2.4 : Combinaison avec Twenty CRM
|
|
- **Ligne 161** : Combine `leantimeTasks` et `twentyCrmTasks` dans `allTasks`
|
|
|
|
### Étape 2.5 : Filtrage frontend
|
|
- **Ligne 242-281** : **FILTRE 3** - Filtre les tâches :
|
|
|
|
**a) Filtre par statut "done" (ligne 245-260)** :
|
|
- Statuts filtrés : `0`, `3`, `5` (ou strings `'0'`, `'3'`, `'5'`, `'done'`)
|
|
- Si le statut correspond → la tâche est exclue (`return false`)
|
|
|
|
**b) Filtre par date (ligne 262-280)** :
|
|
- Exclut les tâches sans `dateToFinish`
|
|
- Garde uniquement les tâches avec `dateToFinish <= today` (overdue ou due today)
|
|
|
|
### Étape 2.6 : Tri
|
|
- **Ligne 296-317** : Trie les tâches :
|
|
1. Par `dateToFinish` (oldest first)
|
|
2. Si dates égales, par statut (statut `4` en premier)
|
|
|
|
### Étape 2.7 : Notification badge
|
|
- **Ligne 362-366** : Met à jour le badge de notification avec le nombre de tâches
|
|
|
|
### Étape 2.8 : Affichage
|
|
- **Ligne 368** : `setTasks(sortedTasks)` - Met à jour l'état React
|
|
|
|
### Étape 2.9 : Filtrage avant notification Outlook
|
|
- **Ligne 372-390** : **FILTRE 4** - Filtre les tâches avant d'envoyer l'événement `tasks-updated` :
|
|
- **Ligne 380** : ⚠️ **PROBLÈME ICI** - Ne filtre que `3` et `5`, PAS le statut `0` !
|
|
- Si `isDone === true` → la tâche est exclue
|
|
- **Ligne 391-398** : Transforme les tâches pour l'événement (sans inclure le `status`)
|
|
|
|
---
|
|
|
|
## 3. PROBLÈMES IDENTIFIÉS
|
|
|
|
### Problème 1 : Filtre ligne 380 dans flow.tsx
|
|
- **Ligne 380** : `isDone = taskStatus === 3 || taskStatus === 5 || ...`
|
|
- **Manque** : `taskStatus === 0`
|
|
- **Impact** : Les tâches avec statut `0` passent le filtre et sont envoyées dans l'événement `tasks-updated`
|
|
|
|
### Problème 2 : Détection ligne 129-135 dans flow.tsx
|
|
- **Ligne 134** : Ne détecte que le statut `5`, pas `0` ni `3`
|
|
- **Impact** : Le log `⚠️ Received done tasks` ne détecte pas toutes les tâches "done"
|
|
|
|
### Problème 3 : Le statut n'est pas inclus dans l'événement tasks-updated
|
|
- **Ligne 391-398** : L'objet envoyé dans l'événement ne contient pas le champ `status`
|
|
- **Impact** : Les hooks qui écoutent `tasks-updated` ne peuvent pas filtrer par statut
|
|
|
|
---
|
|
|
|
## 4. FLOW RÉSUMÉ
|
|
|
|
```
|
|
1. API Leantime (toutes les tâches, tous statuts)
|
|
↓
|
|
2. FILTRE 1 (cache) : Exclut statuts 0, 3, 5
|
|
↓
|
|
3. FILTRE 2 (API backend) : Exclut statuts 0, 3, 5 + filtre par editorId
|
|
↓
|
|
4. Transformation + Cache Redis
|
|
↓
|
|
5. Frontend reçoit les tâches (avec statut inclus)
|
|
↓
|
|
6. FILTRE 3 (frontend) : Exclut statuts 0, 3, 5 + filtre par date
|
|
↓
|
|
7. Tri par date
|
|
↓
|
|
8. FILTRE 4 (avant notification) : ⚠️ Exclut seulement statuts 3, 5 (MANQUE 0)
|
|
↓
|
|
9. Événement tasks-updated (sans statut dans l'objet)
|
|
↓
|
|
10. Affichage dans le widget
|
|
```
|
|
|
|
---
|
|
|
|
## 5. CORRECTIONS NÉCESSAIRES
|
|
|
|
1. **Ligne 380 dans flow.tsx** : Ajouter `taskStatus === 0` au filtre ✅ CORRIGÉ
|
|
2. **Ligne 134 dans flow.tsx** : Ajouter détection des statuts `0` et `3` ✅ CORRIGÉ
|
|
3. **Ligne 391-398 dans flow.tsx** : Inclure le champ `status` dans l'objet envoyé dans l'événement
|
|
|
|
---
|
|
|
|
## 6. SIGNIFICATION DES STATUTS LEANTIME
|
|
|
|
D'après le code :
|
|
|
|
### Mapping standard (app/api/leantime/status-labels/route.ts) :
|
|
- **Status 1** = 'NEW'
|
|
- **Status 2** = 'INPROGRESS'
|
|
- **Status 3** = 'DONE' ⚠️
|
|
- **Status 0** = Non défini (tombe dans `default: 'UNKNOWN'`)
|
|
|
|
### Mapping dans le widget (components/flow.tsx) :
|
|
- **Status 1** = 'New'
|
|
- **Status 2** = 'Blocked'
|
|
- **Status 3** = 'In Progress' ⚠️ **INCOHÉRENCE avec status-labels**
|
|
- **Status 4** = 'Waiting for Approval'
|
|
- **Status 5** = 'Done'
|
|
- **Status 0** = 'Unknown' (par défaut)
|
|
|
|
### Statuts filtrés comme "done" :
|
|
- **Status 0** = "Done" (dans votre instance Leantime, configuration personnalisée)
|
|
- **Status 3** = "Done" (selon `status-labels/route.ts`)
|
|
- **Status 5** = "Done" (selon `flow.tsx`)
|
|
|
|
**Note** : Il y a une incohérence entre les deux mappings. Le statut 3 est mappé à "DONE" dans `status-labels` mais à "In Progress" dans `flow.tsx`. Le statut 0 n'est pas standard dans Leantime mais semble être utilisé comme "done" dans votre instance.
|