# Mapping N8N Workflow - Mission Deletion ## 📋 Vue d'Ensemble Ce document décrit le mapping entre les données de notre API et le format attendu par le workflow N8N `NeahMissionDelete_Pro`. --- ## 🔄 Workflow N8N - Structure ### Nodes du Workflow 1. **Webhook Delete** : Reçoit POST sur `/mission-delete` 2. **Process Delete Data** : Transforme les données d'entrée 3. **Get Keycloak Token** : Obtient un token d'authentification 4. **Delete Gitea Repo** : Supprime le repository Gitea (continueOnFail: true) 5. **Close Leantime Project** : Ferme le projet Leantime (continueOnFail: true) 6. **Delete Outline Collection** : Supprime la collection Outline (continueOnFail: true) 7. **Close RocketChat Channel** : Ferme le canal RocketChat (continueOnFail: true) 8. **Combine Results** : Combine les résultats de toutes les suppressions 9. **Save Deletion To API** : Envoie les résultats à l'API --- ## 📊 Mapping des Données ### Données Envoyées par Notre API ```typescript { missionId: string, name: string, repoName: string, // Extrait de giteaRepositoryUrl leantimeProjectId: number | null, documentationCollectionId: string, // Mappé depuis outlineCollectionId rocketchatChannelId: string, // Mappé depuis rocketChatChannelId // Champs originaux conservés pour référence giteaRepositoryUrl: string | null, outlineCollectionId: string | null, rocketChatChannelId: string | null, penpotProjectId: string | null, config: { N8N_API_KEY: string, MISSION_API_URL: string } } ``` ### Données Attendues par N8N (Process Delete Data) Le node "Process Delete Data" transforme les données en : ```javascript { missionData: { repoName: input.repoName || '', leantimeId: input.leantimeProjectId || 0, collectionId: input.documentationCollectionId || '', rocketChatRoomId: input.rocketchatChannelId || '' }, config: { GITEA_API_URL: "https://gite.slm-lab.net/api/v1", GITEA_API_TOKEN: "...", GITEA_OWNER: "alma", LEANTIME_API_URL: "https://agilite.slm-lab.net", LEANTIME_API_TOKEN: "...", ROCKETCHAT_API_URL: "https://parole.slm-lab.net/", ROCKETCHAT_AUTH_TOKEN: "...", ROCKETCHAT_USER_ID: "...", OUTLINE_API_URL: "https://chapitre.slm-lab.net/api", OUTLINE_API_TOKEN: "...", MISSION_API_URL: "https://hub.slm-lab.net", KEYCLOAK_BASE_URL: "https://connect.slm-lab.net", KEYCLOAK_REALM: "cercle", KEYCLOAK_CLIENT_ID: "lab", KEYCLOAK_CLIENT_SECRET: "..." } } ``` --- ## 🔧 Transformations Effectuées ### 1. Extraction du Nom du Repository Gitea **Problème** : Notre base stocke `giteaRepositoryUrl` (URL complète), mais N8N attend `repoName` (nom seul) **Solution** : Extraction du nom depuis l'URL ```typescript // Format possible: // - https://gite.slm-lab.net/alma/repo-name // - https://gite.slm-lab.net/api/v1/repos/alma/repo-name let repoName = ''; if (mission.giteaRepositoryUrl) { try { const url = new URL(mission.giteaRepositoryUrl); const pathParts = url.pathname.split('/').filter(Boolean); repoName = pathParts[pathParts.length - 1] || ''; } catch (error) { // Fallback: extraction regex const match = mission.giteaRepositoryUrl.match(/\/([^\/]+)\/?$/); repoName = match ? match[1] : ''; } } ``` **Exemples** : - `https://gite.slm-lab.net/alma/mission-abc` → `mission-abc` - `https://gite.slm-lab.net/api/v1/repos/alma/mission-xyz` → `mission-xyz` ### 2. Mapping des Champs | Notre Base de Données | N8N Attend | Transformation | |----------------------|------------|----------------| | `giteaRepositoryUrl` | `repoName` | Extraction du nom depuis URL | | `leantimeProjectId` | `leantimeProjectId` | Direct (converti en number) | | `outlineCollectionId` | `documentationCollectionId` | Direct mapping | | `rocketChatChannelId` | `rocketchatChannelId` | Direct mapping (lowercase 'c') | --- ## 🎯 Actions N8N par Service ### 1. Gitea Repository **Node** : "Delete Gitea Repo" - **Méthode** : DELETE - **URL** : `{{ GITEA_API_URL }}/repos/{{ GITEA_OWNER }}/{{ repoName }}` - **Headers** : `Authorization: token {{ GITEA_API_TOKEN }}` - **ContinueOnFail** : `true` (continue même si échoue) **Résultat attendu** : Status 204 (No Content) = succès ### 2. Leantime Project **Node** : "Close Leantime Project" - **Méthode** : POST - **URL** : `{{ LEANTIME_API_URL }}/api/jsonrpc` - **Headers** : `X-API-Key: {{ LEANTIME_API_TOKEN }}` - **Body** : ```json { "method": "leantime.rpc.Projects.Projects.patch", "jsonrpc": "2.0", "id": 1, "params": { "id": {{ leantimeId }}, "params": { "status": "closed" } } } ``` - **ContinueOnFail** : `true` **Note** : Le projet est **fermé** (status: "closed"), pas supprimé ### 3. Outline Collection **Node** : "Delete Outline Collection" - **Méthode** : POST - **URL** : `{{ OUTLINE_API_URL }}/api/collections.delete` - **Headers** : `Authorization: Bearer {{ OUTLINE_API_TOKEN }}` - **Body** : `{ "id": "{{ collectionId }}" }` - **ContinueOnFail** : `true` **Résultat attendu** : Status 200 = succès ### 4. RocketChat Channel **Node** : "Close RocketChat Channel" - **Méthode** : POST - **URL** : `{{ ROCKETCHAT_API_URL }}/api/v1/channels.close` - **Headers** : - `X-Auth-Token: {{ ROCKETCHAT_AUTH_TOKEN }}` - `X-User-Id: {{ ROCKETCHAT_USER_ID }}` - **Body** : `{ "roomId": "{{ rocketChatRoomId }}" }` - **ContinueOnFail** : `true` **Note** : Le canal est **fermé**, pas supprimé --- ## 📤 Réponse N8N ### Format de Réponse (Combine Results) ```javascript { status: "deleted", timestamp: "2024-01-01T12:00:00.000Z", details: { gitea: true || "already_deleted", leantime: true || false, outline: true || false, rocketchat: true || false } } ``` ### Envoi à l'API (Save Deletion To API) Le workflow envoie ensuite les résultats à : - **URL** : `{{ MISSION_API_URL }}/mission-deleted` - **Méthode** : POST - **Headers** : `Authorization: Bearer {{ Keycloak Token }}` - **Body** : ```json { "status": "archived", "results": { "gitea": true, "leantime": true, "outline": true, "rocketchat": true } } ``` --- ## ⚠️ Points d'Attention ### 1. Gestion des Erreurs - Tous les nodes de suppression ont `continueOnFail: true` - Si une suppression échoue, le workflow continue avec les autres - Les résultats indiquent quelles suppressions ont réussi/échoué ### 2. Différences de Comportement - **Gitea** : Suppression complète du repository - **Leantime** : Fermeture (status: "closed"), pas suppression - **Outline** : Suppression complète de la collection - **RocketChat** : Fermeture du canal, pas suppression ### 3. Extraction du Repo Name - L'extraction doit gérer différents formats d'URL - Si l'extraction échoue, `repoName` sera vide - Le workflow N8N gérera le cas où `repoName` est vide ### 4. Mapping des Champs - **documentationCollectionId** : Mappé depuis `outlineCollectionId` - **rocketchatChannelId** : Mappé depuis `rocketChatChannelId` (attention au 'c' minuscule) - **leantimeProjectId** : Converti en number (0 si null) --- ## 🔍 Debugging ### Logs à Surveiller 1. **Extraction repo name** : ``` Extracted repo name from URL: { url: "...", repoName: "..." } ``` 2. **Données envoyées à N8N** : ``` Sending deletion data to N8N: { ... } ``` 3. **Résultat N8N** : ``` N8N Deletion Workflow Result: { success: true, results: {...} } ``` ### Vérifications 1. **Repo name extrait correctement** ? - Vérifier les logs d'extraction - Format attendu : nom simple sans URL 2. **Mapping des champs correct** ? - `documentationCollectionId` = `outlineCollectionId` - `rocketchatChannelId` = `rocketChatChannelId` 3. **N8N a reçu les données** ? - Vérifier les logs N8N - Vérifier le webhook a été appelé --- ## 📝 Exemple Complet ### Données en Base ```typescript { id: "abc-123", name: "Mission Example", giteaRepositoryUrl: "https://gite.slm-lab.net/alma/mission-example", leantimeProjectId: "123", outlineCollectionId: "collection-456", rocketChatChannelId: "channel-789" } ``` ### Données Envoyées à N8N ```typescript { missionId: "abc-123", name: "Mission Example", repoName: "mission-example", // Extrait de l'URL leantimeProjectId: 123, // Converti en number documentationCollectionId: "collection-456", // Mappé rocketchatChannelId: "channel-789", // Mappé (lowercase 'c') giteaRepositoryUrl: "https://gite.slm-lab.net/alma/mission-example", outlineCollectionId: "collection-456", rocketChatChannelId: "channel-789", config: { N8N_API_KEY: "...", MISSION_API_URL: "https://hub.slm-lab.net" } } ``` ### Données Traitées par N8N ```javascript { missionData: { repoName: "mission-example", leantimeId: 123, collectionId: "collection-456", rocketChatRoomId: "channel-789" }, config: { ... } } ``` --- **Document généré le** : $(date) **Version** : 1.0 **Workflow N8N** : NeahMissionDelete_Pro **Webhook URL** : https://brain.slm-lab.net/webhook-test/mission-delete