NeahNew/MISSION_INTEGRATION_IDS_FIX.md
2026-01-04 14:24:56 +01:00

309 lines
7.0 KiB
Markdown

# Fix : Sauvegarde des IDs d'Intégration N8N
## 🔍 Problème Identifié
Lors de la suppression d'une mission, le webhook N8N reçoit des IDs vides :
```json
{
"repoName": "",
"leantimeProjectId": 0,
"documentationCollectionId": "",
"rocketchatChannelId": ""
}
```
**Cause** : Les IDs retournés par N8N lors de la création des intégrations n'étaient **jamais sauvegardés en base**.
### Workflow Problématique
```
1. Frontend → POST /api/missions
2. Backend crée mission en Prisma
3. Backend upload fichiers Minio
4. Backend → POST N8N webhook (mission-created)
5. N8N crée intégrations (Gitea, Leantime, Outline, RocketChat)
6. N8N → POST /mission-created ❌ ENDPOINT N'EXISTAIT PAS
7. IDs jamais sauvegardés ❌
```
### Conséquence
Lors de la suppression :
- Les IDs sont `null` en base
- On envoie des valeurs vides à N8N
- N8N ne peut pas supprimer/fermer les intégrations
- Les ressources externes restent orphelines
---
## ✅ Solution Implémentée
### 1. Endpoint `/mission-created` Créé
**Fichier** : `app/api/missions/mission-created/route.ts`
**Fonctionnalités** :
- ✅ Reçoit les IDs des intégrations créées par N8N
- ✅ Vérifie l'API key (`x-api-key` header)
- ✅ Trouve la mission par `name` + `creatorId`
- ✅ Met à jour la mission avec les IDs
- ✅ Mappe correctement les champs :
- `gitRepoUrl``giteaRepositoryUrl`
- `documentationCollectionId``outlineCollectionId`
- `rocketchatChannelId``rocketChatChannelId`
- `leantimeProjectId``leantimeProjectId` (converti en string)
### 2. Format des Données
**N8N envoie** :
```json
{
"name": "Mission Example",
"creatorId": "user-id",
"gitRepoUrl": "https://gite.slm-lab.net/alma/mission-example",
"leantimeProjectId": "123",
"documentationCollectionId": "collection-456",
"rocketchatChannelId": "channel-789"
}
```
**Endpoint sauvegarde** :
```typescript
{
giteaRepositoryUrl: "https://gite.slm-lab.net/alma/mission-example",
leantimeProjectId: "123",
outlineCollectionId: "collection-456",
rocketChatChannelId: "channel-789"
}
```
### 3. Sécurité
- ✅ Vérification de l'API key (`x-api-key` header)
- ✅ Validation des champs requis (`name`, `creatorId`)
- ✅ Gestion d'erreurs complète
- ✅ Logging détaillé pour debugging
---
## 🔄 Nouveau Workflow
```
1. Frontend → POST /api/missions
2. Backend crée mission en Prisma
3. Backend upload fichiers Minio
4. Backend → POST N8N webhook (mission-created)
5. N8N crée intégrations (Gitea, Leantime, Outline, RocketChat)
6. N8N → POST /mission-created ✅ ENDPOINT EXISTE MAINTENANT
7. Backend sauvegarde les IDs ✅
8. Mission complète avec tous les IDs ✅
```
**Lors de la suppression** :
```
1. Frontend → DELETE /api/missions/[id]
2. Backend récupère mission (avec IDs sauvegardés)
3. Backend extrait/mappe les données
4. Backend → POST N8N webhook (mission-delete)
5. N8N reçoit les IDs ✅
6. N8N supprime/ferme les intégrations ✅
```
---
## 📋 Format de Requête
### POST /api/missions/mission-created
**Headers** :
```
Content-Type: application/json
x-api-key: {N8N_API_KEY}
Authorization: Bearer {keycloak_token} (optionnel)
```
**Body** :
```json
{
"name": "Mission Example",
"creatorId": "user-uuid",
"gitRepoUrl": "https://gite.slm-lab.net/alma/mission-example",
"leantimeProjectId": "123",
"documentationCollectionId": "collection-456",
"rocketchatChannelId": "channel-789",
"niveau": "default",
"intention": "...",
"description": "...",
"donneurDOrdre": "...",
"projection": "...",
"missionType": "remote"
}
```
**Réponse Succès** (200) :
```json
{
"success": true,
"message": "Mission updated successfully",
"mission": {
"id": "mission-uuid",
"name": "Mission Example",
"giteaRepositoryUrl": "https://gite.slm-lab.net/alma/mission-example",
"leantimeProjectId": "123",
"outlineCollectionId": "collection-456",
"rocketChatChannelId": "channel-789"
}
}
```
**Réponse Erreur** (400/404/500) :
```json
{
"error": "Error message",
"details": "Detailed error information"
}
```
---
## ⚠️ Missions Existantes
**Problème** : Les missions créées avant cette correction n'ont pas leurs IDs sauvegardés.
**Solutions possibles** :
### Option 1 : Migration Manuelle
Pour chaque mission existante, récupérer les IDs depuis les services externes et les mettre à jour manuellement.
### Option 2 : Script de Migration
Créer un script qui :
1. Liste toutes les missions sans IDs
2. Interroge les services externes (si possible)
3. Met à jour les missions
### Option 3 : Re-création
Supprimer et recréer les missions (si acceptable).
**Recommandation** : Option 1 pour les missions critiques, Option 2 pour un grand nombre.
---
## 🧪 Tests
### Test 1 : Création de Mission
1. Créer une nouvelle mission via le frontend
2. Vérifier que N8N appelle `/mission-created`
3. Vérifier que la mission en base a les IDs sauvegardés :
```sql
SELECT id, name, giteaRepositoryUrl, leantimeProjectId,
outlineCollectionId, rocketChatChannelId
FROM Mission
WHERE name = 'Mission Test';
```
### Test 2 : Suppression de Mission
1. Supprimer une mission avec IDs sauvegardés
2. Vérifier que N8N reçoit les IDs :
```json
{
"repoName": "mission-example",
"leantimeProjectId": 123,
"documentationCollectionId": "collection-456",
"rocketchatChannelId": "channel-789"
}
```
3. Vérifier que N8N supprime/ferme les intégrations
### Test 3 : API Key
1. Appeler `/mission-created` sans `x-api-key` → 401
2. Appeler avec mauvais `x-api-key` → 401
3. Appeler avec bon `x-api-key` → 200
---
## 📝 Logs à Surveiller
### Création
```
=== Mission Created Webhook Received ===
Received mission-created data: { ... }
Found mission: { id: "...", name: "..." }
Updating giteaRepositoryUrl: ...
Updating leantimeProjectId: ...
Mission updated successfully: { ... }
```
### Suppression
```
=== Starting N8N Deletion Workflow ===
Extracted repo name from URL: { url: "...", repoName: "..." }
Sending deletion data to N8N: { ... }
N8N Deletion Workflow Result: { success: true, ... }
```
---
## 🔧 Configuration Requise
### Variables d'Environnement
```env
N8N_API_KEY=your-api-key-here
NEXT_PUBLIC_API_URL=https://hub.slm-lab.net
```
### N8N Workflow
Le workflow N8N doit appeler :
- **URL** : `{{ MISSION_API_URL }}/mission-created`
- **Méthode** : POST
- **Headers** :
- `Content-Type: application/json`
- `x-api-key: {{ N8N_API_KEY }}`
- `Authorization: Bearer {{ Keycloak Token }}` (optionnel)
---
## ✅ Checklist
- [x] Endpoint `/mission-created` créé
- [x] Vérification API key implémentée
- [x] Mapping des champs correct
- [x] Gestion d'erreurs complète
- [x] Logging détaillé
- [ ] Tests manuels effectués
- [ ] Migration des missions existantes (si nécessaire)
- [ ] Documentation N8N mise à jour
---
**Date de correction** : $(date)
**Version** : 1.0
**Fichiers modifiés** :
- `app/api/missions/mission-created/route.ts` (nouveau)