9.0 KiB
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
- Webhook Delete : Reçoit POST sur
/mission-delete - Process Delete Data : Transforme les données d'entrée
- Get Keycloak Token : Obtient un token d'authentification
- Delete Gitea Repo : Supprime le repository Gitea (continueOnFail: true)
- Close Leantime Project : Ferme le projet Leantime (continueOnFail: true)
- Delete Outline Collection : Supprime la collection Outline (continueOnFail: true)
- Close RocketChat Channel : Ferme le canal RocketChat (continueOnFail: true)
- Combine Results : Combine les résultats de toutes les suppressions
- Save Deletion To API : Envoie les résultats à l'API
📊 Mapping des Données
Données Envoyées par Notre API
{
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 :
{
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
// 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-abchttps://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 :
{ "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)
{
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 :
{ "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,
repoNamesera vide - Le workflow N8N gérera le cas où
repoNameest 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
-
Extraction repo name :
Extracted repo name from URL: { url: "...", repoName: "..." } -
Données envoyées à N8N :
Sending deletion data to N8N: { ... } -
Résultat N8N :
N8N Deletion Workflow Result: { success: true, results: {...} }
Vérifications
-
Repo name extrait correctement ?
- Vérifier les logs d'extraction
- Format attendu : nom simple sans URL
-
Mapping des champs correct ?
documentationCollectionId=outlineCollectionIdrocketchatChannelId=rocketChatChannelId
-
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
{
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
{
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
{
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