309 lines
7.0 KiB
Markdown
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)
|
|
|