8
n8n 한국어amn8n.com

지능형 워크플로우 유지보수 시스템

고급

이것은DevOps, Multimodal AI분야의자동화 워크플로우로, 42개의 노드를 포함합니다.주로 If, N8n, Code, Wait, Switch 등의 노드를 사용하며. 지능형 AI 필터링과 Google Workspace 통합을 지원하는 지능형 워크플로우 유지보수 시스템

사전 요구사항
  • HTTP Webhook 엔드포인트(n8n이 자동으로 생성)
  • Google Drive API 인증 정보
  • 대상 API의 인증 정보가 필요할 수 있음
  • Google Sheets API 인증 정보
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "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": "조건문",
      "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": "워크플로우1 가져오기",
      "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": "🔐 보안 검증기",
      "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": "🔀 액션 라우터",
      "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": "📊 감사 데이터 파싱",
      "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": "🔍 워크플로우 필터링",
      "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": "📋 워크플로우 상세 정보 가져오기",
      "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": "⚙️ 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": "🤖 중복 AI 필터",
      "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": "📋 중복 상세 정보 가져오기",
      "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": "🔄 중복 데이터 준비",
      "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": "📝 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": "🧠 내보내기 AI 필터",
      "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": "📤 내보내기 데이터 준비",
      "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": "💾 이진 응답 준비",
      "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": "📂 모든 워크플로우 가져오기",
      "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": "🔒 보안 감사 생성",
      "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": "⏸️ 일시정지할 워크플로우 가져오기",
      "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": "📋 복제할 워크플로우 가져오기",
      "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": "📦 내보낼 워크플로우 가져오기",
      "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": "⏸️ 워크플로우 비활성화",
      "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": "📄 워크플로우 상태 가져오기",
      "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": "⏰ 재활성화 8시간 대기",
      "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": "▶️ 워크플로우 재활성화",
      "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": "➕ 워크플로우 복제 생성",
      "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": "📅 일일 일시정지 예약 (22시)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2260,
        780
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 22
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3ac317e2-fe93-48aa-b9ea-9d4b5bdb4ea7",
      "name": "📅 주간 감사 예약 (월요일 21시)",
      "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": "📅 월간 내보내기 예약 (9시)",
      "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": "🎯 수동 테스트 트리거",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2260,
        960
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "59daa2b4-5a86-4b90-ab4a-ffb2792e6bb6",
      "name": "📊 예시: 감사 요청",
      "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": "⏸️ 예시: 일시정지 요청",
      "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": "🔄 예시: 복제 요청",
      "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": "📤 예시: 내보내기 요청",
      "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": "❌ 인증 오류",
      "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": "📈 Google 시트 저장",
      "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": "☁️ Google 드라이브 저장",
      "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": "스티키 노트",
      "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": "스티키 노트2",
      "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": "스티키 노트1",
      "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": "스티키 노트3",
      "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": "스티키 노트4",
      "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
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

고급 - 데브옵스, 멀티모달 AI

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
고급
노드 수42
카테고리2
노드 유형13
난이도 설명

고급 사용자를 위한 16+개 노드의 복잡한 워크플로우

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34