# 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)