Système intelligent de maintenance de workflows

Avancé

Ceci est unDevOps, Multimodal AIworkflow d'automatisation du domainecontenant 42 nœuds.Utilise principalement des nœuds comme If, N8n, Code, Wait, Switch. Système de maintenance de flux de travail intelligent avec filtrage IA et intégration Google Workspace

Prérequis
  • Point de terminaison HTTP Webhook (généré automatiquement par n8n)
  • Informations d'identification Google Drive API
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
  • Informations d'identification Google Sheets API
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "8599d7845a778242eb2b590f9276e0b22e25a242e7728a8fa6887cb7c35c668a",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "968b5375-141c-4cad-b077-f0d5a84e162e",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1700,
        780
      ],
      "webhookId": "0624042d-08fd-4e8f-8399-e3defa12a95d",
      "parameters": {
        "path": "ops/n8n",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "THpi8axJMuZwMUJB",
          "name": "n8n_audit_header"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "1d426d09-8892-4e4d-807f-15fcd89036c1",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -1220,
        780
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "189fc963-efff-4b59-b455-a53cb1d7f07a",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "success"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "804eff08-b03e-44e6-8fef-8792d7df7d57",
      "name": "Obtenir un workflow1",
      "type": "n8n-nodes-base.n8n",
      "position": [
        220,
        1180
      ],
      "parameters": {
        "operation": "get",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ef30f65a-2699-4d1b-830a-8d2197c1b768",
      "name": "🔐 Validateur de Sécurité",
      "type": "n8n-nodes-base.code",
      "position": [
        -1440,
        780
      ],
      "parameters": {
        "jsCode": "// Accéder aux headers du webhook via $json.headers\nconst authHeader = $json.headers?.authorization || '';\nconst expectedToken = 'Bearer Bearer YOUR_WEBHOOK_TOKEN_HERE';\n\n// Validation du token\nif (!authHeader.startsWith('Bearer ')) {\n  return [{ json: {\n    status: 'error',\n    code: 401,\n    message: 'Missing or invalid Authorization header format. Expected: Bearer <token>'\n  }}];\n}\n\nif (authHeader !== expectedToken) {\n  return [{ json: {\n    status: 'error',\n    code: 401,\n    message: 'Invalid authorization token'\n  }}];\n}\n\n// Accéder au body du webhook via $json.body\nconst body = $json.body;\nif (!body || !body.action) {\n  return [{ json: {\n    status: 'error',\n    code: 400,\n    message: 'Missing required field: action'\n  }}];\n}\n\n// Validation des actions supportées\nconst validActions = ['audit', 'pause', 'resume', 'duplicate', 'export', 'cleanup'];\nif (!validActions.includes(body.action)) {\n  return [{ json: {\n    status: 'error',\n    code: 400,\n    message: `Invalid action. Supported: ${validActions.join(', ')}`\n  }}];\n}\n\n// Si tout est OK\nreturn [{ json: {\n  status: 'success',\n  action: body.action,\n  filters: body.filters || {},\n  options: body.options || {},\n  originalBody: body\n}}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1e6b87f0-39a0-48c3-9e45-a3e005b2044d",
      "name": "🔀 Routeur d'Actions",
      "type": "n8n-nodes-base.switch",
      "position": [
        -920,
        560
      ],
      "parameters": {
        "mode": "expression",
        "output": "={{\n  $json.action === 'audit' ? 0 :\n  $json.action === 'pause' ? 1 :\n  $json.action === 'duplicate' ? 2 :\n  $json.action === 'export' ? 3 :0\n}}\n\n"
      },
      "typeVersion": 3.2
    },
    {
      "id": "cedc60ed-38c6-440e-bb70-fe037e57b238",
      "name": "📊 Analyser les Données d'Audit",
      "type": "n8n-nodes-base.code",
      "position": [
        220,
        60
      ],
      "parameters": {
        "jsCode": "// Node Code à ajouter avant Google Sheets\nconst auditData = $input.all()[0].json;\nconst processedRows = [];\n\n// Traiter chaque type de rapport (Credentials, Nodes, Instance)\nObject.entries(auditData).forEach(([reportKey, reportData]) => {\n  if (reportData && reportData.sections) {\n    reportData.sections.forEach(section => {\n      processedRows.push({\n        date: new Date().toISOString(),\n        risk_type: reportData.risk,\n        report_category: reportKey,\n        section_title: section.title,\n        description: section.description,\n        recommendation: section.recommendation,\n        issues_count: section.location ? section.location.length : 0,\n        severity: getSeverity(reportData.risk, section.title),\n        affected_workflows: section.location ? \n          [...new Set(section.location.map(item => item.workflowId).filter(Boolean))].join('; ') : 'N/A',\n        issue_types: section.location ? \n          [...new Set(section.location.map(item => item.kind))].join('; ') : 'N/A'\n      });\n    });\n  }\n});\n\nfunction getSeverity(riskType, sectionTitle) {\n  if (riskType === 'nodes' && sectionTitle.includes('risky')) return 'Critical';\n  if (riskType === 'instance' && sectionTitle.includes('webhook')) return 'High';\n  if (riskType === 'credentials') return 'Medium';\n  return 'Low';\n}\n\nreturn processedRows.map(row => ({ json: row }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "43ebdd05-9eba-4a78-a143-229ce0f0b61f",
      "name": "🔍 Filtrer les Workflows",
      "type": "n8n-nodes-base.code",
      "position": [
        -60,
        280
      ],
      "parameters": {
        "jsCode": "// Filtrer les workflows selon les critères spécifiés\nconst workflows = $input.all();\nconst filters = $('🔀 Action Router').item.json.filters || {};\nconst options = $('🔀 Action Router').item.json.options || {};\n\n// Workflows protégés - sécurité renforcée\nconst protectedWorkflows = [\n  'n8n-auto-maintenance', // Ne pas pauser le workflow de maintenance !\n  'Security',\n  'Backup'\n];\n\nlet filteredWorkflows = workflows;\n\n// Filtrer par nom si spécifié\nif (filters.namePattern) {\n  const regex = new RegExp(filters.namePattern, 'i');\n  filteredWorkflows = filteredWorkflows.filter(wf => \n    regex.test(wf.json.name)\n  );\n}\n\n// Filtrer par tags si spécifié\nif (filters.tags) {\n  const requiredTags = filters.tags.split(',').map(t => t.trim());\n  filteredWorkflows = filteredWorkflows.filter(wf =>\n    requiredTags.some(tag => \n      wf.json.tags?.some(wfTag => wfTag.name === tag)\n    )\n  );\n}\n\n// Exclure les workflows protégés (sécurité prioritaire)\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n  if (protectedWorkflows.includes(wf.json.name)) {\n    console.warn(`⚠️ Workflow protégé exclu du filtrage: ${wf.json.name}`);\n    return false;\n  }\n  return true;\n});\n\n// Exclure certains workflows critiques (logique existante)\nconst criticalWorkflows = options.excludeCritical ? \n  ['Security Audit', 'Backup System', 'Health Check'] : [];\nfilteredWorkflows = filteredWorkflows.filter(wf =>\n  !criticalWorkflows.includes(wf.json.name)\n);\n\nreturn filteredWorkflows.map(wf => ({\n  json: {\n    id: wf.json.id,\n    name: wf.json.name,\n    active: wf.json.active,\n    tags: wf.json.tags,\n    action: 'pause'\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6297b646-2788-49a1-b9ca-133892d34c13",
      "name": "📋 Obtenir les Détails du Workflow",
      "type": "n8n-nodes-base.n8n",
      "position": [
        220,
        280
      ],
      "parameters": {
        "operation": "get",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca",
      "name": "⚙️ Préparer la Mise à Jour JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        500,
        280
      ],
      "parameters": {
        "jsCode": "const workflowData = $('📋 Get Workflow Details').item.json;\n\n// ✅ Propriétés settings MINIMALES et généralement autorisées\nconst minimalSettings = {\n  executionOrder: workflowData.settings?.executionOrder || \"v1\"\n};\n\nconst updatePayload = {\n  name: workflowData.name,\n  nodes: workflowData.nodes,\n  connections: workflowData.connections,\n  settings: minimalSettings,  // ✅ Settings minimal mais requis\n  active: false,\n  staticData: workflowData.staticData || {}\n};\n\nreturn [{ \n  json: { \n    workflowJSON: JSON.stringify(updatePayload),\n    workflowId: workflowData.id\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "83e91c12-b93b-4280-8165-e9c5721fa128",
      "name": "🤖 Filtre IA pour les Doublons",
      "type": "n8n-nodes-base.code",
      "position": [
        -60,
        740
      ],
      "parameters": {
        "jsCode": "// Filtrer les workflows pour duplication selon les critères optimisés avec IA\nconst workflows = $input.all();\nconst filters = $('🔀 Action Router').item.json.filters || {};\nconst options = $('🔀 Action Router').item.json.options || {};\n\n// Workflows protégés - sécurité renforcée\nconst protectedWorkflows = [\n  'n8n-auto-maintenance', // Ne pas dupliquer le workflow de maintenance !\n  'Security',\n  'Backup'\n];\n\nlet filteredWorkflows = workflows;\n\n// Filtrer par nom si spécifié\nif (filters.namePattern) {\n  const regex = new RegExp(filters.namePattern, 'i');\n  filteredWorkflows = filteredWorkflows.filter(wf => \n    regex.test(wf.json.name)\n  );\n}\n\n// Filtrer par tags si spécifié\nif (filters.tags) {\n  const requiredTags = filters.tags.split(',').map(t => t.trim());\n  filteredWorkflows = filteredWorkflows.filter(wf =>\n    requiredTags.some(tag => \n      wf.json.tags?.some(wfTag => wfTag.name === tag)\n    )\n  );\n}\n\n// Exclure les workflows protégés (sécurité prioritaire)\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n  if (protectedWorkflows.includes(wf.json.name)) {\n    console.warn(`⚠️ Workflow protégé exclu de la duplication: ${wf.json.name}`);\n    return false;\n  }\n  return true;\n});\n\n// Exclure certains workflows critiques\nconst criticalWorkflows = options.excludeCritical ? \n  ['Security Audit', 'Backup System', 'Health Check'] : [];\nfilteredWorkflows = filteredWorkflows.filter(wf =>\n  !criticalWorkflows.includes(wf.json.name)\n);\n\n// 🚀 **LOGIQUE D'INTELLIGENCE ARTIFICIELLE POUR ÉVALUER L'INTÉRÊT**\n\n// Fonction utilitaire pour calculer les jours depuis une date\nfunction daysSince(dateString) {\n  const date = new Date(dateString);\n  const diffTime = Math.abs(new Date() - date);\n  return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n// Système de scoring intelligent\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n  const json = wf.json;\n  let score = 0;\n  let reasons = [];\n\n  // 📊 CRITÈRE 1: Statut d'activité (+2 points)\n  if (json.active) {\n    score += 2;\n    reasons.push('actif');\n  }\n\n  // 🔧 CRITÈRE 2: Complexité du workflow (basée sur le nombre de nœuds)\n  if (json.nodes && json.nodes.length > 20) {\n    score += 3;\n    reasons.push(`complexe (${json.nodes.length} nœuds)`);\n  } else if (json.nodes && json.nodes.length > 10) {\n    score += 1;\n    reasons.push(`modérément complexe (${json.nodes.length} nœuds)`);\n  }\n\n  // 🏷️ CRITÈRE 3: Tags prioritaires (+3 points chacun)\n  const priorityTags = ['important', 'critical', 'core', 'production', 'business'];\n  if (json.tags) {\n    for (const tag of json.tags) {\n      if (priorityTags.includes(tag.name.toLowerCase())) {\n        score += 3;\n        reasons.push(`tag prioritaire: ${tag.name}`);\n      }\n    }\n  }\n\n  // ⏰ CRITÈRE 4: Récence des modifications\n  if (json.updatedAt) {\n    const days = daysSince(json.updatedAt);\n    if (days < 7) {\n      score += 3;\n      reasons.push('récemment modifié (<7j)');\n    } else if (days < 30) {\n      score += 1;\n      reasons.push('modifié récemment (<30j)');\n    }\n  }\n\n  // 💼 CRITÈRE 5: Analyse sémantique du nom (patterns business-critiques)\n  const businessPatterns = [\n    /production/i, /business/i, /core/i, /main/i, /primary/i,\n    /client/i, /customer/i, /order/i, /payment/i, /integration/i\n  ];\n  \n  const isBusinessCritical = businessPatterns.some(pattern => \n    pattern.test(json.name)\n  );\n  \n  if (isBusinessCritical) {\n    score += 2;\n    reasons.push('nom suggérant un workflow business-critique');\n  }\n\n  // 📈 CRITÈRE 6: Déclencheurs multiples (workflows complexes)\n  if (json.triggerCount && json.triggerCount > 1) {\n    score += 1;\n    reasons.push(`${json.triggerCount} déclencheurs`);\n  }\n\n  // 🎯 DÉCISION FINALE : Seuil d'intérêt\n  const isInteresting = score >= 3;\n  \n  // Logging pour debug\n  if (isInteresting) {\n    console.log(`✅ Workflow \"${json.name}\" sélectionné (score: ${score}) - Raisons: ${reasons.join(', ')}`);\n  } else {\n    console.log(`❌ Workflow \"${json.name}\" ignoré (score: ${score}) - Raisons: ${reasons.join(', ')}`);\n  }\n\n  return isInteresting;\n});\n\nreturn filteredWorkflows.map(wf => ({\n  json: {\n    id: wf.json.id,\n    name: wf.json.name,\n    active: wf.json.active,\n    tags: wf.json.tags,\n    action: 'duplicate'\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7f396759-1d1e-45c7-8233-610876dc2dda",
      "name": "📋 Obtenir les Détails pour Doublon",
      "type": "n8n-nodes-base.n8n",
      "position": [
        220,
        740
      ],
      "parameters": {
        "operation": "get",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ad6d2c80-08da-4f73-9295-f6332d7e869c",
      "name": "🔄 Préparer les Données du Doublon",
      "type": "n8n-nodes-base.code",
      "position": [
        500,
        740
      ],
      "parameters": {
        "jsCode": "// Préparer les données pour dupliquer TOUS les workflows\nconst allWorkflowsData = $('📋 Get Details for Duplicate').all();\n\nconsole.log(`🔄 Traitement de ${allWorkflowsData.length} workflows pour duplication`);\n\nconst results = [];\n\nallWorkflowsData.forEach((workflowItem, index) => {\n  const workflowData = workflowItem.json;\n  \n  // Générer un nom unique pour chaque copie\n  const originalName = workflowData.name;\n  const timestamp = new Date().toISOString().split('T')[0]; // Format YYYY-MM-DD\n  const duplicateName = `${originalName} - Backup ${timestamp}`;\n\n  // Préparer le payload pour la création d'une copie\n  const duplicatePayload = {\n    name: duplicateName,\n    nodes: workflowData.nodes,\n    connections: workflowData.connections,\n    settings: workflowData.settings || { executionOrder: \"v1\" },\n    active: false, // Créer inactif par sécurité\n    staticData: workflowData.staticData || {},\n    tags: [\n      ...(workflowData.tags || []),\n      { \n        name: \"backup\",\n        id: \"backup-\" + Date.now() + \"-\" + index\n      },\n      {\n        name: \"duplicate\",\n        id: \"duplicate-\" + Date.now() + \"-\" + index\n      }\n    ]\n  };\n\n  // Nettoyer les IDs des nœuds pour éviter les conflits\n  if (duplicatePayload.nodes) {\n    duplicatePayload.nodes = duplicatePayload.nodes.map(node => {\n      const newNode = { ...node };\n      // Générer un nouvel ID unique\n      newNode.id = 'dup-' + Math.random().toString(36).substr(2, 9) + '-' + Date.now().toString(36) + '-' + index;\n      return newNode;\n    });\n  }\n\n  console.log(`🔄 Préparation duplication ${index + 1}/${allWorkflowsData.length}: \"${originalName}\" → \"${duplicateName}\"`);\n  console.log(`📊 Nœuds à copier: ${duplicatePayload.nodes?.length || 0}`);\n\n  results.push({ \n    json: { \n      workflowJSON: duplicatePayload,\n      originalName: originalName,\n      duplicateName: duplicateName,\n      originalId: workflowData.id,\n      batchIndex: index + 1,\n      totalInBatch: allWorkflowsData.length\n    }\n  });\n});\n\nconsole.log(`✅ ${results.length} workflows préparés pour duplication`);\nconsole.log(`🏷️ Tags ajoutés: backup, duplicate (avec index unique)`);\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6af5e73e-4fb2-449e-8570-d8faa702913a",
      "name": "📝 Convertir en Chaîne JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        220,
        960
      ],
      "parameters": {
        "jsCode": "// Convertir l'objet workflow en JSON string pour l'API n8n\nconst workflowObj = $json.workflowJSON;\n\nreturn [{\n  json: {\n    workflowJSON: JSON.stringify(workflowObj),\n    originalName: $json.originalName,\n    duplicateName: $json.duplicateName,\n    originalId: $json.originalId,\n    batchIndex: $json.batchIndex,\n    totalInBatch: $json.totalInBatch\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "65fd019c-c128-47ca-b519-659547d67dd8",
      "name": "🧠 Filtre IA pour l'Export",
      "type": "n8n-nodes-base.code",
      "position": [
        -60,
        1180
      ],
      "parameters": {
        "jsCode": "// Filtrage intelligent des workflows pour export\nconst workflows = $input.all();\nconst filters = $('🔀 Action Router').item.json.filters || {};\nconst options = $('🔀 Action Router').item.json.options || {};\n\n// Workflows système (toujours inclus en export car critiques)\nconst systemWorkflows = ['n8n-auto-maintenance', 'Security', 'Backup'];\n\nlet filteredWorkflows = workflows;\n\n// 🧠 INTELLIGENCE ARTIFICIELLE : Système de scoring pour workflows pertinents\nfunction calculateExportValue(workflow) {\n  const json = workflow.json;\n  let score = 0;\n  let reasons = [];\n\n  // 🔥 CRITÈRE 1: Workflows système (toujours prioritaires)\n  if (systemWorkflows.includes(json.name)) {\n    score += 10;\n    reasons.push('workflow système critique');\n  }\n\n  // 💼 CRITÈRE 2: Workflows business-critiques (analyse sémantique)\n  const businessPatterns = [\n    /production/i, /business/i, /core/i, /main/i, /primary/i,\n    /client/i, /customer/i, /order/i, /payment/i, /integration/i,\n    /api/i, /webhook/i, /sync/i, /import/i, /export/i, /notification/i\n  ];\n  \n  const isBusinessCritical = businessPatterns.some(pattern => \n    pattern.test(json.name)\n  );\n  \n  if (isBusinessCritical) {\n    score += 5;\n    reasons.push('nom suggérant un workflow business-critique');\n  }\n\n  // 🏷️ CRITÈRE 3: Tags prioritaires\n  const priorityTags = ['important', 'critical', 'core', 'production', 'business', 'live'];\n  if (json.tags) {\n    for (const tag of json.tags) {\n      if (priorityTags.includes(tag.name.toLowerCase())) {\n        score += 4;\n        reasons.push(`tag prioritaire: ${tag.name}`);\n      }\n    }\n  }\n\n  // ⚡ CRITÈRE 4: Workflows actifs (en utilisation)\n  if (json.active) {\n    score += 3;\n    reasons.push('workflow actif');\n  }\n\n  // 🔧 CRITÈRE 5: Complexité technique (workflows sophistiqués)\n  if (json.nodes && json.nodes.length > 15) {\n    score += 3;\n    reasons.push(`workflow complexe (${json.nodes.length} nœuds)`);\n  } else if (json.nodes && json.nodes.length > 8) {\n    score += 1;\n    reasons.push(`workflow modérément complexe (${json.nodes.length} nœuds)`);\n  }\n\n  // ⏰ CRITÈRE 6: Activité récente (workflows maintenus)\n  if (json.updatedAt) {\n    const daysSince = Math.ceil((new Date() - new Date(json.updatedAt)) / (1000 * 60 * 60 * 24));\n    if (daysSince < 30) {\n      score += 2;\n      reasons.push('récemment modifié (<30j)');\n    } else if (daysSince < 90) {\n      score += 1;\n      reasons.push('modifié récemment (<90j)');\n    }\n  }\n\n  // 📈 CRITÈRE 7: Workflows avec déclencheurs (automation active)\n  if (json.triggerCount && json.triggerCount > 0) {\n    score += 2;\n    reasons.push(`${json.triggerCount} déclencheur(s)`);\n  }\n\n  // 🚫 CRITÈRES DE PÉNALITÉ (workflows à éviter)\n  \n  // Pénalité pour workflows de test\n  const testPatterns = [/test/i, /demo/i, /example/i, /sample/i, /backup.*\\d{4}/i];\n  const isTestWorkflow = testPatterns.some(pattern => pattern.test(json.name));\n  \n  if (isTestWorkflow) {\n    score -= 3;\n    reasons.push('semble être un workflow de test/demo');\n  }\n\n  // Pénalité pour workflows inactifs depuis longtemps\n  if (!json.active && json.updatedAt) {\n    const daysSince = Math.ceil((new Date() - new Date(json.updatedAt)) / (1000 * 60 * 60 * 24));\n    if (daysSince > 180) {\n      score -= 2;\n      reasons.push('inactif depuis >6 mois');\n    }\n  }\n\n  return { score, reasons };\n}\n\n// Appliquer les filtres manuels d'abord\nif (filters.namePattern) {\n  const regex = new RegExp(filters.namePattern, 'i');\n  filteredWorkflows = filteredWorkflows.filter(wf => \n    regex.test(wf.json.name)\n  );\n  console.log(`🔍 Filtrage par nom: ${filteredWorkflows.length} workflows correspondent à \"${filters.namePattern}\"`);\n}\n\nif (filters.tags) {\n  const requiredTags = filters.tags.split(',').map(t => t.trim());\n  filteredWorkflows = filteredWorkflows.filter(wf =>\n    requiredTags.some(tag => \n      wf.json.tags?.some(wfTag => wfTag.name === tag)\n    )\n  );\n  console.log(`🏷️ Filtrage par tags: ${filteredWorkflows.length} workflows avec tags requis`);\n}\n\n// 🧠 SÉLECTION INTELLIGENTE : Appliquer le scoring\nconst scoredWorkflows = filteredWorkflows.map(wf => {\n  const analysis = calculateExportValue(wf);\n  return {\n    workflow: wf,\n    score: analysis.score,\n    reasons: analysis.reasons\n  };\n});\n\n// Seuil intelligent : workflows avec score >= 5 OU workflows système\nconst selectedWorkflows = scoredWorkflows.filter(item => {\n  const isSelected = item.score >= 5 || systemWorkflows.includes(item.workflow.json.name);\n  \n  if (isSelected) {\n    console.log(`✅ \"${item.workflow.json.name}\" sélectionné (score: ${item.score}) - ${item.reasons.join(', ')}`);\n  } else {\n    console.log(`❌ \"${item.workflow.json.name}\" ignoré (score: ${item.score}) - ${item.reasons.join(', ')}`);\n  }\n  \n  return isSelected;\n});\n\n// Si mode \"force include\" activé, inclure aussi les workflows avec score 3-4\nif (options.includeModerateWorkflows) {\n  const moderateWorkflows = scoredWorkflows.filter(item => \n    item.score >= 3 && item.score < 5 && !systemWorkflows.includes(item.workflow.json.name)\n  );\n  \n  moderateWorkflows.forEach(item => {\n    selectedWorkflows.push(item);\n    console.log(`🟡 \"${item.workflow.json.name}\" inclus (mode étendu - score: ${item.score})`);\n  });\n}\n\n// Statistiques finales\nconst stats = {\n  total: workflows.length,\n  afterFilters: filteredWorkflows.length,\n  selected: selectedWorkflows.length,\n  highValue: selectedWorkflows.filter(item => item.score >= 8).length,\n  systemWorkflows: selectedWorkflows.filter(item => \n    systemWorkflows.includes(item.workflow.json.name)\n  ).length\n};\n\nconsole.log(`📊 STATISTIQUES EXPORT:`);\nconsole.log(`📦 Total workflows: ${stats.total}`);\nconsole.log(`🔍 Après filtres manuels: ${stats.afterFilters}`);\nconsole.log(`✅ Sélectionnés pour export: ${stats.selected}`);\nconsole.log(`🔥 Haute valeur (score ≥8): ${stats.highValue}`);\nconsole.log(`⚙️ Workflows système: ${stats.systemWorkflows}`);\n\nreturn selectedWorkflows.map(item => ({\n  json: {\n    id: item.workflow.json.id,\n    name: item.workflow.json.name,\n    active: item.workflow.json.active,\n    tags: item.workflow.json.tags,\n    action: 'export',\n    exportScore: item.score,\n    exportReasons: item.reasons\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "a443f5ba-9dd8-4771-9531-0da98494d514",
      "name": "📤 Préparer les Données d'Export",
      "type": "n8n-nodes-base.code",
      "position": [
        500,
        1180
      ],
      "parameters": {
        "jsCode": "// Préparer les données d'export avec métadonnées complètes - VERSION CORRIGÉE\nconst allWorkflows = $input.all();\nconst exportTimestamp = new Date().toISOString();\nconst exportDate = exportTimestamp.split('T')[0]; // Format YYYY-MM-DD\n\nconsole.log(`📤 Préparation export de ${allWorkflows.length} workflows sélectionnés intelligemment`);\n\n// Statistiques en temps réel\nlet stats = {\n  totalWorkflows: allWorkflows.length,\n  activeWorkflows: 0,\n  inactiveWorkflows: 0,\n  totalNodes: 0,\n  workflowsWithCredentials: 0,\n  workflowsWithTriggers: 0,\n  systemWorkflows: 0,\n  businessCritical: 0,\n  highValueWorkflows: 0\n};\n\n// Traitement intelligent de chaque workflow\nconst processedWorkflows = allWorkflows.map((item, index) => {\n  const workflow = item.json;\n  const nodeCount = workflow.nodes?.length || 0;\n  \n  // Mise à jour des statistiques\n  stats.totalNodes += nodeCount;\n  if (workflow.active) stats.activeWorkflows++;\n  else stats.inactiveWorkflows++;\n  \n  // Détection des credentials\n  const hasCredentials = workflow.nodes?.some(node => \n    node.credentials && Object.keys(node.credentials).length > 0\n  ) || false;\n  if (hasCredentials) stats.workflowsWithCredentials++;\n  \n  // Détection des triggers\n  const triggerCount = workflow.nodes?.filter(node => \n    node.type.includes('Trigger') || node.type.includes('trigger')\n  ).length || 0;\n  if (triggerCount > 0) stats.workflowsWithTriggers++;\n  \n  // Classification intelligente\n  const systemWorkflows = ['n8n-auto-maintenance', 'Security', 'Backup'];\n  const isSystemWorkflow = systemWorkflows.includes(workflow.name);\n  if (isSystemWorkflow) stats.systemWorkflows++;\n  \n  const businessPatterns = [\n    /production/i, /business/i, /core/i, /main/i, /primary/i,\n    /client/i, /customer/i, /order/i, /payment/i, /integration/i,\n    /api/i, /webhook/i, /sync/i, /import/i, /export/i, /notification/i\n  ];\n  const isBusinessCritical = businessPatterns.some(pattern => \n    pattern.test(workflow.name)\n  );\n  if (isBusinessCritical) stats.businessCritical++;\n  \n  // ✅ CORRECTION : Récupérer le score depuis les données du nœud actuel\n  const exportScore = item.json.exportScore || 5; // Score par défaut si absent\n  const exportReasons = item.json.exportReasons || ['sélectionné par filtrage intelligent'];\n  if (exportScore >= 8) stats.highValueWorkflows++;\n  \n  // Structure d'export optimisée\n  return {\n    // Métadonnées principales\n    id: workflow.id,\n    name: workflow.name,\n    active: workflow.active,\n    versionId: workflow.versionId,\n    \n    // Timestamps\n    createdAt: workflow.createdAt,\n    updatedAt: workflow.updatedAt,\n    exportedAt: exportTimestamp,\n    \n    // Structure workflow\n    nodes: workflow.nodes,\n    connections: workflow.connections,\n    settings: workflow.settings || { executionOrder: \"v1\" },\n    staticData: workflow.staticData || {},\n    \n    // Métadonnées organisationnelles\n    tags: workflow.tags || [],\n    \n    // Analytics et insights pour l'import\n    exportMetadata: {\n      originallyActive: workflow.active,\n      nodeCount: nodeCount,\n      triggerCount: triggerCount,\n      hasCredentials: hasCredentials,\n      isSystemWorkflow: isSystemWorkflow,\n      isBusinessCritical: isBusinessCritical,\n      exportScore: exportScore,\n      exportReasons: exportReasons,\n      \n      // Types de nœuds (pour statistiques)\n      nodeTypes: workflow.nodes ? \n        [...new Set(workflow.nodes.map(node => node.type))].sort() : [],\n      \n      // Credentials utilisés (noms seulement, pas les valeurs)\n      credentialTypes: hasCredentials ? \n        [...new Set(workflow.nodes.flatMap(node => \n          node.credentials ? Object.keys(node.credentials) : []\n        ))].sort() : [],\n        \n      // Estimation de complexité\n      complexityLevel: nodeCount < 5 ? 'Simple' : \n                      nodeCount < 15 ? 'Moderate' : \n                      nodeCount < 30 ? 'Complex' : 'Very Complex'\n    }\n  };\n});\n\n// Calculs statistiques finaux\nstats.averageNodesPerWorkflow = Math.round(stats.totalNodes / stats.totalWorkflows);\nstats.credentialCoverage = Math.round((stats.workflowsWithCredentials / stats.totalWorkflows) * 100);\nstats.activationRate = Math.round((stats.activeWorkflows / stats.totalWorkflows) * 100);\n\n// Structure d'export complète avec métadonnées riches\nconst exportData = {\n  // En-tête d'export\n  metadata: {\n    exportDate: exportDate,\n    exportTimestamp: exportTimestamp,\n    exportedBy: 'n8n-auto-maintenance',\n    exportVersion: '2.0',\n    sourceInstance: 'n8n-production', // À adapter\n    \n    // Statistiques détaillées\n    statistics: stats,\n    \n    // Configuration d'export\n    exportConfig: {\n      intelligentFiltering: true,\n      includeMetadata: true,\n      includeSettings: true,\n      includeStaticData: true,\n      credentialsHandling: 'references-only'\n    }\n  },\n  \n  // Données des workflows\n  workflows: processedWorkflows\n};\n\n// Génération du nom de fichier intelligent\nconst filenamePrefix = stats.businessCritical > 0 ? 'n8n-business-workflows' : 'n8n-workflows';\nconst filename = `${filenamePrefix}-export-${exportDate}.json`;\n\n// Logs détaillés pour monitoring\nconsole.log(`📊 === STATISTIQUES D'EXPORT DÉTAILLÉES ===`);\nconsole.log(`📦 Total workflows exportés: ${stats.totalWorkflows}`);\nconsole.log(`⚡ Workflows actifs: ${stats.activeWorkflows} (${stats.activationRate}%)`);\nconsole.log(`💤 Workflows inactifs: ${stats.inactiveWorkflows}`);\nconsole.log(`🔧 Total nœuds: ${stats.totalNodes} (moyenne: ${stats.averageNodesPerWorkflow})`);\nconsole.log(`🔑 Avec credentials: ${stats.workflowsWithCredentials} (${stats.credentialCoverage}%)`);\nconsole.log(`⚡ Avec triggers: ${stats.workflowsWithTriggers}`);\nconsole.log(`⚙️ Workflows système: ${stats.systemWorkflows}`);\nconsole.log(`💼 Business-critiques: ${stats.businessCritical}`);\nconsole.log(`🔥 Haute valeur (score ≥8): ${stats.highValueWorkflows}`);\nconsole.log(`📄 Taille export: ${JSON.stringify(exportData).length} caractères`);\nconsole.log(`📁 Nom fichier: ${filename}`);\n\nreturn [{\n  json: {\n    exportData: exportData,\n    stats: stats,\n    filename: filename,\n    success: true\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4b886cf9-9006-4895-8070-8c4cfd9d45d3",
      "name": "💾 Préparer la Réponse Binaire",
      "type": "n8n-nodes-base.code",
      "position": [
        -320,
        960
      ],
      "parameters": {
        "jsCode": "// Préparer la réponse binaire pour téléchargement - VERSION CORRIGÉE\nconst exportData = $json.exportData;\nconst filename = $json.filename;\nconst stats = $json.stats;\n\nconsole.log(`📤 Préparation réponse binaire pour export: ${filename}`);\nconsole.log(`📊 Workflows à télécharger: ${stats.totalWorkflows}`);\n\n// ✅ CORRECTION : Créer le contenu JSON avec Buffer.from()\nconst jsonContent = JSON.stringify(exportData, null, 2);\nconst binaryData = Buffer.from(jsonContent, 'utf8');\n\nconsole.log(`📄 Taille fichier: ${binaryData.length} bytes (${Math.round(binaryData.length/1024)} KB)`);\n\n// ✅ CORRECTION : Structure exacte requise par n8n\nreturn [{\n  json: {\n    filename: filename,\n    fileSize: binaryData.length,\n    stats: stats,\n    downloadReady: true\n  },\n  binary: {\n    exportData: {\n      data: binaryData,\n      mimeType: 'application/json',\n      fileName: filename\n    }\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d6e01bb8-c5d3-48fd-88ae-5b5a3a6b7081",
      "name": "📂 Obtenir Tous les Workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -320,
        60
      ],
      "parameters": {
        "filters": {
          "tags": "",
          "activeWorkflows": false
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3010eed3-58c7-41ca-8107-8e1409247c63",
      "name": "🔒 Générer un Audit de Sécurité",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -60,
        60
      ],
      "parameters": {
        "resource": "audit",
        "operation": "generate",
        "requestOptions": {},
        "additionalOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1e898452-a205-43a7-bf15-ec90305a9e8d",
      "name": "⏸️ Obtenir les Workflows à Suspendre",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -320,
        280
      ],
      "parameters": {
        "filters": {
          "activeWorkflows": true
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4221c708-7abe-441f-b6ec-b094e827f934",
      "name": "📋 Obtenir les Workflows à Dupliquer",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -320,
        740
      ],
      "parameters": {
        "filters": {
          "activeWorkflows": true
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "09650916-d4b7-46d0-933e-916814e2bc33",
      "name": "📦 Obtenir les Workflows pour Export",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -320,
        1180
      ],
      "parameters": {
        "filters": {
          "activeWorkflows": false
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9cdc509c-5b1f-44c6-b4c4-8202cd9ff234",
      "name": "⏸️ Désactiver le Workflow",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -320,
        500
      ],
      "parameters": {
        "operation": "deactivate",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.workflowId }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b655347c-9fda-4a4e-a7a2-12bbd7e6b246",
      "name": "📄 Obtenir le Statut du Workflow",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -60,
        500
      ],
      "parameters": {
        "operation": "get",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "52b35908-e231-4c4f-b739-a559f2cf84b8",
      "name": "⏰ Attendre 8h pour Réactivation",
      "type": "n8n-nodes-base.wait",
      "position": [
        220,
        500
      ],
      "webhookId": "186c8076-cf20-46de-b9da-9dc0f1bfa764",
      "parameters": {
        "unit": "hours",
        "amount": 8
      },
      "typeVersion": 1.1
    },
    {
      "id": "fe7de858-3240-4828-bade-9f8e02cb5d4a",
      "name": "▶️ Réactiver les Workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        500,
        500
      ],
      "parameters": {
        "operation": "activate",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3e16c955-9ec6-4814-9fd2-afb85d1e89ae",
      "name": "➕ Créer un Workflow en Doublon",
      "type": "n8n-nodes-base.n8n",
      "position": [
        500,
        960
      ],
      "parameters": {
        "operation": "create",
        "requestOptions": {},
        "workflowObject": "={{ $json.workflowJSON }}"
      },
      "credentials": {
        "n8nApi": {
          "id": "vg8fTUqz9p4BdZGi",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8bb9df05-663d-42e5-b2c4-b99350c1438e",
      "name": "📅 Planification de Suspension Quotidienne (22h)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2260,
        780
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 22
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3ac317e2-fe93-48aa-b9ea-9d4b5bdb4ea7",
      "name": "📅 Planification d'Audit Hebdomadaire (Lun 21h)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2260,
        600
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 21
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "113734a6-70eb-40ef-b527-07455e4e8253",
      "name": "📅 Planification d'Export Mensuel (9h)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2260,
        1160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months",
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "05bd883f-a194-4e1f-bf60-291874c733cf",
      "name": "🎯 Déclencheur de Test Manuel",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2260,
        960
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "59daa2b4-5a86-4b90-ab4a-ffb2792e6bb6",
      "name": "📊 Exemple : Requête d'Audit",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1980,
        600
      ],
      "parameters": {
        "url": "https://your-n8n-instance.com/webhook/ops/n8n",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"action\": \"audit\",\n  \"filters\": {\n    \"tags\": \"maintenance,test\",\n    \"namePattern\": \"Test.*\"\n  },\n  \"options\": {\n    \"excludeCritical\": true,\n    \"reason\": \"Scheduled maintenance\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "856af42e-b2df-4f16-a601-8c4b51a3e3fc",
      "name": "⏸️ Exemple : Requête de Suspension",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1980,
        780
      ],
      "parameters": {
        "url": "https://your-n8n-instance.com/webhook/ops/n8n",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"action\": \"pause\",\n  \"filters\": {\n    \"tags\": \"maintenance,test\",\n    \"namePattern\": \"Test.*\"\n  },\n  \"options\": {\n    \"excludeCritical\": true,\n    \"reason\": \"Scheduled maintenance\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "91c0a34b-d8d9-4fa4-879e-9864e616feec",
      "name": "🔄 Exemple : Requête de Duplication",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1980,
        960
      ],
      "parameters": {
        "url": "https://your-n8n-instance.com/webhook/ops/n8n",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"action\": \"duplicate\",\n  \"filters\": {\n    \"tags\": \"maintenance,test\",\n    \"namePattern\": \"Test.*\"\n  },\n  \"options\": {\n    \"excludeCritical\": true,\n    \"reason\": \"Scheduled maintenance\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "eb3140eb-0075-45e3-be18-c41b9c22021a",
      "name": "📤 Exemple : Requête d'Export",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1980,
        1160
      ],
      "parameters": {
        "url": "https://your-n8n-instance.com/webhook/ops/n8n",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"action\": \"export\",\n  \"filters\": {\n    \"tags\": \"maintenance,test\",\n    \"namePattern\": \"Test.*\"\n  },\n  \"options\": {\n    \"excludeCritical\": true,\n    \"reason\": \"Scheduled maintenance\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "29741645-14c0-41de-b385-bd8a7a415513",
      "name": "❌ Erreur d'Authentification",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -960,
        1000
      ],
      "parameters": {
        "options": {
          "responseCode": "={{ $json.code }}"
        },
        "respondWith": "json",
        "responseBody": "{\n  \"success\": false,\n  \"error\": \"{{ $json.message }}\",\n  \"timestamp\": \"{{ $now }}\"\n}\n"
      },
      "typeVersion": 1.4
    },
    {
      "id": "3025cc68-8d55-4ac4-b4f6-7ed8ea7176b6",
      "name": "📈 Sauvegarder dans Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        500,
        60
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SHEET_ID_HERE"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID_HERE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "lmJOtRvKMOD3WkGJ",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "d3a47b59-93b1-4c10-ae8d-0e7a1a8db5bc",
      "name": "☁️ Sauvegarder dans Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -60,
        960
      ],
      "parameters": {
        "name": "={{ $json.filename }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        },
        "inputDataFieldName": "exportData"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "q3CEz3EULOFD0Ybj",
          "name": "Google Drive account 2"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "683fb61e-0867-4766-9f2f-c463a6045e2a",
      "name": "Note Adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2780,
        520
      ],
      "parameters": {
        "width": 1000,
        "height": 840,
        "content": "# 🔧 n8n Auto-Maintenance System\n\n## Overview\nAdvanced workflow automation with AI-powered intelligent selection\n\n## 🎯 Core Actions\n- **🔒 AUDIT**: Security analysis & reporting\n- **⏸️ PAUSE**: Temporary workflow suspension  \n- **🔄 DUPLICATE**: Smart backup creation\n- **📤 EXPORT**: Complete system backup\n\n## ✨ Key Features\n- 🤖 AI-driven workflow filtering\n- 🔐 Secure token-based authentication\n- 📊 Automated reporting to Google Sheets\n- ☁️ Google Drive integration\n- ⚡ Scheduled maintenance cycles\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8faa0c78-0d50-4674-a6b9-e85b7d3436fa",
      "name": "Note Adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -980,
        -220
      ],
      "parameters": {
        "color": 6,
        "width": 600,
        "height": 540,
        "content": "# 🧠 Artificial Intelligence Engine\n\n## Smart Scoring System\n| Criteria | Points | Description |\n|----------|--------|-------------|\n| **Active Status** | +2 | Currently running |\n| **Complexity** | +1-3 | Node count based |\n| **Priority Tags** | +3 | Critical/Important |\n| **Business Critical** | +2-5 | Production patterns |\n| **Recent Updates** | +1-3 | Maintenance activity |\n\n## 🎯 Selection Thresholds\n- **Duplicate**: ≥3 points\n- **Export**: ≥5 points or system workflow\n\n## 🔍 Pattern Recognition\nAutomatically detects business-critical workflows using semantic analysis\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7b387337-4df9-42aa-8ba2-d136911184cc",
      "name": "Note Adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1700,
        120
      ],
      "parameters": {
        "color": 3,
        "width": 660,
        "height": 520,
        "content": "# 🔐 Security Framework\n\n## Authentication\n- ✅ **Bearer Token** validation required\n- ✅ **Request format** validation\n- ✅ **Action whitelist** enforcement\n- ✅ **Error handling** with proper HTTP codes\n\n## Protected Workflows\n> **⚠️ Never modified by automation**\n\n- `n8n-auto-maintenance`\n- `Security` \n- `Backup`\n\n## Supported Actions\n`audit` • `pause` • `resume` • `duplicate` • `export` • `cleanup`\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bf26f38f-da76-4498-a671-85044372dc21",
      "name": "Note Adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1700,
        1100
      ],
      "parameters": {
        "color": 4,
        "width": 760,
        "height": 500,
        "content": "# ⚙️ Configuration & Scheduling\n\n## Default Schedules\n- **🔒 Audit**: Weekly (Monday 21:00)\n- **⏸️ Pause**: Daily (22:00) \n- **📤 Export**: Monthly (Day 1, 09:00)\n\n## Required Credentials\n1. **n8n API**: Full workflow access\n2. **Google Sheets**: Audit logging\n3. **Google Drive**: Export storage\n4. **Webhook Auth**: Security validation\n\n## Environment Variables\nWEBHOOK_TOKEN=your_secure_token_here\nGOOGLE_SHEET_ID=your_sheet_id\nMAINTENANCE_HOUR=22\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "301da1ba-dbc5-49e5-8c59-1f194f2fcec9",
      "name": "Note Adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        840,
        -1220
      ],
      "parameters": {
        "width": 1600,
        "height": 4160,
        "content": "# 🔧 n8n Advanced Auto-Maintenance System\n\n[![n8n](https://img.shields.io/badge/n8n-Template-FF6D5A?logo=n8n)](https://n8n.io)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/yourusername/n8n-auto-maintenance/graphs/commit-activity)\n\n## 📋 Overview\n\nAdvanced workflow automation system with **AI-powered intelligent selection** for n8n maintenance operations. Automates security audits, workflow management, backups, and exports with smart filtering capabilities.\n\n### ✨ Key Features\n\n- **🤖 AI-Driven Selection**: Intelligent workflow filtering using multi-criteria scoring\n- **🔐 Secure Authentication**: Token-based security with protected workflows  \n- **📊 Automated Reporting**: Security audit results to Google Sheets\n- **☁️ Cloud Integration**: Export backups to Google Drive\n- **⚡ Scheduled Operations**: Automated maintenance cycles\n- **🎯 Granular Control**: Tag-based and pattern filtering\n\n## 🎯 Core Actions\n\n| Action | Description | Trigger | AI Filter |\n|--------|-------------|---------|-----------|\n| **🔒 AUDIT** | Security analysis & reporting | Weekly (Mon 21:00) | ❌ |\n| **⏸️ PAUSE** | Temporary workflow suspension | Daily (22:00) | ✅ |  \n| **🔄 DUPLICATE** | Smart backup creation | On-demand | ✅ (≥3 pts) |\n| **📤 EXPORT** | Complete system backup | Monthly (1st, 09:00) | ✅ (≥5 pts) |\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- n8n instance (v1.0+) with API enabled\n- Google Workspace account (Sheets + Drive)\n- Webhook endpoint access\n\n### Installation\n\n1. **Import Template**\n\nDownload the workflow JSON\ncurl -O https://github.com/yourusername/n8n-auto-maintenance/raw/main/workflow.json\n\nImport in n8n interface: Settings → Import workflow\n\n\n2. **Configure Credentials**\n- `your_n8n_api_credential`: n8n API credentials\n- `your_google_sheets_credential`: Google Sheets OAuth2\n- `your_google_drive_credential`: Google Drive OAuth2\n- `your_webhook_auth_credential`: Header auth with token\n\n3. **Environment Setup**\nWEBHOOK_TOKEN=your_secure_token_here_32_chars_min\nGOOGLE_SHEET_ID=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms\nMAINTENANCE_HOUR=22\n\n\n4. **Test Setup**\ncurl -X POST https://your-instance.com/webhook/ops/n8n\n-H \"Authorization: Bearer YOUR_WEBHOOK_TOKEN_HERE\"\n-H \"Content-Type: application/json\"\n-d '{\"action\":\"audit\",\"options\":{\"reason\":\"Setup test\"}}'\n\n\n## 📖 Detailed Documentation\n\n- [📋 Installation Guide](docs/installation.md)\n- [🔧 Configuration Reference](docs/configuration.md)\n- [🤖 AI Filtering Logic](docs/ai-filtering.md)\n- [🔒 Security Best Practices](docs/security.md)\n- [🐛 Troubleshooting](docs/troubleshooting.md)\n\n## 🤖 AI Intelligence\n\n### Smart Scoring System\n\n| Criteria | Points | Logic |\n|----------|--------|-------|\n| **Active Status** | +2 | Currently running workflows |\n| **Complexity** | +1-3 | Based on node count (>10: +1, >20: +3) |\n| **Priority Tags** | +3 | `critical`, `important`, `core`, `production` |\n| **Business Critical** | +2-5 | Semantic analysis of workflow names |\n| **Recent Activity** | +1-3 | Last modification (<7d: +3, <30d: +1) |\n\n### Selection Thresholds\n- **Duplicate**: ≥3 points (smart backup selection)\n- **Export**: ≥5 points or system workflow (comprehensive backup)\n\n## 🔐 Security\n\n### Protected Workflows\nThese workflows are **never** modified by automation:\n- `n8n-auto-maintenance` (this workflow itself)\n- `Security` (security-related workflows)  \n- `Backup` (backup workflows)\n\n### Authentication\n- Bearer token required for all operations\n- Request validation and sanitization\n- Action whitelist enforcement\n- Comprehensive error handling\n\n## 📊 Monitoring & Logging\n\n- **Google Sheets**: Audit results with severity classification\n- **Console Logs**: Detailed execution information\n- **Error Responses**: Structured JSON with HTTP status codes\n- **Statistics**: Workflow counts, success rates, performance metrics\n\n## 🛠️ API Reference\n\n### Request Format\n{\n\"action\": \"audit|pause|duplicate|export\",\n\"filters\": {\n\"tags\": \"production,critical\",\n\"namePattern\": \".Business.\"\n},\n\"options\": {\n\"excludeCritical\": true,\n\"reason\": \"Scheduled maintenance\"\n}\n}\n\n### Response Format\n{\n\"success\": true,\n\"message\": \"Action completed successfully\",\n\"timestamp\": \"2025-08-16T08:47:00Z\",\n\"affected_workflows\": 5,\n\"statistics\": {\n\"processed\": 12,\n\"selected\": 5,\n\"skipped\": 7\n}\n}\n\n\n## 📈 Changelog\n\n### v2.0.0 (Latest)\n- ✨ AI-powered workflow selection\n- 🔒 Enhanced security framework\n- 📊 Advanced reporting capabilities\n- ☁️ Google Drive integration\n- 🎯 Granular filtering options\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit changes (`git commit -m 'Add amazing feature'`)\n4. Push to branch (`git push origin feature/amazing-feature`)  \n5. Open a Pull Request\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- n8n community for the amazing automation platform\n- AI/ML community for intelligent filtering concepts\n- Contributors and beta testers\n\n---\n\n⭐ **Star this repo if it helped you automate your n8n maintenance!**\n\n"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "1d426d09-8892-4e4d-807f-15fcd89036c1": {
      "main": [
        [
          {
            "node": "1e6b87f0-39a0-48c3-9e45-a3e005b2044d",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "29741645-14c0-41de-b385-bd8a7a415513",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "968b5375-141c-4cad-b077-f0d5a84e162e": {
      "main": [
        [
          {
            "node": "ef30f65a-2699-4d1b-830a-8d2197c1b768",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "804eff08-b03e-44e6-8fef-8792d7df7d57": {
      "main": [
        [
          {
            "node": "a443f5ba-9dd8-4771-9531-0da98494d514",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1e6b87f0-39a0-48c3-9e45-a3e005b2044d": {
      "main": [
        [
          {
            "node": "d6e01bb8-c5d3-48fd-88ae-5b5a3a6b7081",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "1e898452-a205-43a7-bf15-ec90305a9e8d",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "4221c708-7abe-441f-b6ec-b094e827f934",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "09650916-d4b7-46d0-933e-916814e2bc33",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cedc60ed-38c6-440e-bb70-fe037e57b238": {
      "main": [
        [
          {
            "node": "3025cc68-8d55-4ac4-b4f6-7ed8ea7176b6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "43ebdd05-9eba-4a78-a143-229ce0f0b61f": {
      "main": [
        [
          {
            "node": "6297b646-2788-49a1-b9ca-133892d34c13",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d6e01bb8-c5d3-48fd-88ae-5b5a3a6b7081": {
      "main": [
        [
          {
            "node": "3010eed3-58c7-41ca-8107-8e1409247c63",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ef30f65a-2699-4d1b-830a-8d2197c1b768": {
      "main": [
        [
          {
            "node": "1d426d09-8892-4e4d-807f-15fcd89036c1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "05bd883f-a194-4e1f-bf60-291874c733cf": {
      "main": [
        [
          {
            "node": "91c0a34b-d8d9-4fa4-879e-9864e616feec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b655347c-9fda-4a4e-a7a2-12bbd7e6b246": {
      "main": [
        [
          {
            "node": "52b35908-e231-4c4f-b739-a559f2cf84b8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a443f5ba-9dd8-4771-9531-0da98494d514": {
      "main": [
        [
          {
            "node": "4b886cf9-9006-4895-8070-8c4cfd9d45d3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6297b646-2788-49a1-b9ca-133892d34c13": {
      "main": [
        [
          {
            "node": "2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "65fd019c-c128-47ca-b519-659547d67dd8": {
      "main": [
        [
          {
            "node": "804eff08-b03e-44e6-8fef-8792d7df7d57",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9cdc509c-5b1f-44c6-b4c4-8202cd9ff234": {
      "main": [
        [
          {
            "node": "b655347c-9fda-4a4e-a7a2-12bbd7e6b246",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca": {
      "main": [
        [
          {
            "node": "9cdc509c-5b1f-44c6-b4c4-8202cd9ff234",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6af5e73e-4fb2-449e-8570-d8faa702913a": {
      "main": [
        [
          {
            "node": "3e16c955-9ec6-4814-9fd2-afb85d1e89ae",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ad6d2c80-08da-4f73-9295-f6332d7e869c": {
      "main": [
        [
          {
            "node": "6af5e73e-4fb2-449e-8570-d8faa702913a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "52b35908-e231-4c4f-b739-a559f2cf84b8": {
      "main": [
        [
          {
            "node": "fe7de858-3240-4828-bade-9f8e02cb5d4a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4b886cf9-9006-4895-8070-8c4cfd9d45d3": {
      "main": [
        [
          {
            "node": "d3a47b59-93b1-4c10-ae8d-0e7a1a8db5bc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3010eed3-58c7-41ca-8107-8e1409247c63": {
      "main": [
        [
          {
            "node": "cedc60ed-38c6-440e-bb70-fe037e57b238",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "83e91c12-b93b-4280-8165-e9c5721fa128": {
      "main": [
        [
          {
            "node": "7f396759-1d1e-45c7-8233-610876dc2dda",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1e898452-a205-43a7-bf15-ec90305a9e8d": {
      "main": [
        [
          {
            "node": "43ebdd05-9eba-4a78-a143-229ce0f0b61f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "09650916-d4b7-46d0-933e-916814e2bc33": {
      "main": [
        [
          {
            "node": "65fd019c-c128-47ca-b519-659547d67dd8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7f396759-1d1e-45c7-8233-610876dc2dda": {
      "main": [
        [
          {
            "node": "ad6d2c80-08da-4f73-9295-f6332d7e869c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8bb9df05-663d-42e5-b2c4-b99350c1438e": {
      "main": [
        [
          {
            "node": "856af42e-b2df-4f16-a601-8c4b51a3e3fc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4221c708-7abe-441f-b6ec-b094e827f934": {
      "main": [
        [
          {
            "node": "83e91c12-b93b-4280-8165-e9c5721fa128",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "113734a6-70eb-40ef-b527-07455e4e8253": {
      "main": [
        [
          {
            "node": "eb3140eb-0075-45e3-be18-c41b9c22021a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3ac317e2-fe93-48aa-b9ea-9d4b5bdb4ea7": {
      "main": [
        [
          {
            "node": "59daa2b4-5a86-4b90-ab4a-ffb2792e6bb6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - DevOps, IA Multimodale

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds42
Catégorie2
Types de nœuds13
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34