AutomationFlowsGeneral › Module Dependency Analysis with MySQL

Module Dependency Analysis with MySQL

Original n8n title: Module Dependency Analysis

Module Dependency Analysis. Uses scheduleTrigger, httpRequest, splitInBatches, mySql. Webhook trigger; 11 nodes.

Webhook trigger★★★★☆ complexity11 nodesHTTP RequestMySQL
General Trigger: Webhook Nodes: 11 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Module Dependency Analysis",
  "nodes": [
    {
      "parameters": {
        "path": "module-analysis",
        "httpMethod": "POST",
        "authentication": "none",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 2
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        240,
        500
      ]
    },
    {
      "parameters": {
        "url": "http://host.docker.internal:3010/api/execute",
        "method": "POST",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "command",
              "value": "cd /workspace && npx depcruise --output-type json ."
            }
          ]
        },
        "options": {}
      },
      "id": "run-depcruise",
      "name": "Run Dependency Cruiser",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        460,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "// Parse dependency-cruiser output and build enhanced analysis\nconst response = $input.item.json;\nconst rawData = JSON.parse(response.stdout);\n\nconst modules = {};\nconst dependencies = [];\nconst dependents = {};\n\n// Helper: Get package from path\nfunction getPackage(filePath) {\n  if (filePath.startsWith('apps/whatsfresh/')) return 'whatsfresh';\n  if (filePath.startsWith('apps/server/')) return 'server';\n  if (filePath.startsWith('apps/admin/')) return 'admin';\n  if (filePath.startsWith('apps/studio/')) return 'studio';\n  if (filePath.startsWith('apps/login/')) return 'login';\n  if (filePath.startsWith('packages/shared-imports/')) return 'shared-imports';\n  if (filePath.startsWith('packages/db-connect/')) return 'db-connect';\n  return 'other';\n}\n\n// Helper: Get module type from path\nfunction getModuleType(filePath) {\n  if (filePath.includes('/controller/')) return 'controller';\n  if (filePath.includes('/component/') || filePath.includes('/components/')) return 'component';\n  if (filePath.includes('/util/') || filePath.includes('/utils/')) return 'utility';\n  if (filePath.includes('/route/') || filePath.includes('/routes/')) return 'routing';\n  if (filePath.includes('.config.')) return 'config';\n  if (filePath.includes('.test.') || filePath.includes('.spec.')) return 'test';\n  return 'module';\n}\n\n// Process dependency-cruiser data - format is: { modules: [{source: \"file.js\", dependencies: [{resolved: \"dep.js\"}]}] }\nfor (const module of rawData.modules || []) {\n  const filePath = module.source;\n  const pkg = getPackage(filePath);\n  const moduleType = getModuleType(filePath);\n  \n  // Extract dependency paths (only local files, exclude node_modules)\n  const deps = (module.dependencies || [])\n    .map(d => d.resolved)\n    .filter(d => d && !d.includes('node_modules') && (d.startsWith('apps/') || d.startsWith('packages/')));\n\n  modules[filePath] = {\n    file_path: filePath,\n    package: pkg,\n    module_type: moduleType,\n    dependencies: deps,\n    dependency_count: deps.length\n  };\n\n  // Build dependencies and reverse map\n  for (const depPath of deps) {\n    dependencies.push({\n      from_path: filePath,\n      to_path: depPath\n    });\n\n    // Build reverse dependency map\n    if (!dependents[depPath]) {\n      dependents[depPath] = [];\n    }\n    dependents[depPath].push(filePath);\n  }\n}\n\n// Calculate dependent counts and blast radius\nfor (const [filePath, moduleData] of Object.entries(modules)) {\n  const dependentCount = (dependents[filePath] || []).length;\n  \n  moduleData.dependent_count = dependentCount;\n  \n  // Calculate blast radius\n  if (dependentCount >= 8) {\n    moduleData.blast_radius = 'high';\n  } else if (dependentCount >= 4) {\n    moduleData.blast_radius = 'medium';\n  } else {\n    moduleData.blast_radius = 'low';\n  }\n}\n\n// Batch modules (100 per batch)\nconst BATCH_SIZE = 100;\nconst moduleArray = Object.values(modules);\nconst moduleBatches = [];\nfor (let i = 0; i < moduleArray.length; i += BATCH_SIZE) {\n  moduleBatches.push(moduleArray.slice(i, i + BATCH_SIZE));\n}\n\n// Batch dependencies\nconst depBatches = [];\nfor (let i = 0; i < dependencies.length; i += BATCH_SIZE) {\n  depBatches.push(dependencies.slice(i, i + BATCH_SIZE));\n}\n\nconsole.log(`Processed ${moduleArray.length} modules in ${moduleBatches.length} batches`);\nconsole.log(`Processed ${dependencies.length} dependencies in ${depBatches.length} batches`);\n\nreturn {\n  json: {\n    moduleBatches,\n    depBatches,\n    totalModules: moduleArray.length,\n    totalDependencies: dependencies.length\n  }\n};"
      },
      "id": "analyze-dependencies",
      "name": "Analyze Dependencies",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        400
      ]
    },
    {
      "parameters": {
        "batchSize": 100,
        "options": {}
      },
      "id": "split-module-batches",
      "name": "Split Module Batches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Split In Batches already grouped items - just serialize them\nconst allItems = $input.all();\nconst batch = allItems.map(item => item.json);\n\nreturn {\n  json: {\n    modulesJson: JSON.stringify(batch),\n    batchSize: batch.length\n  }\n};"
      },
      "id": "prepare-module-batch",
      "name": "Prepare Module Batch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CALL api_wf.sp_module_load(?, 'n8n-automation')",
        "options": {
          "queryParameters": "={{ $json.modulesJson }}"
        }
      },
      "id": "load-modules",
      "name": "Load Modules",
      "type": "n8n-nodes-base.mySql",
      "typeVersion": 2.5,
      "position": [
        1340,
        300
      ],
      "credentials": {
        "mySql": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "batchSize": 100,
        "options": {}
      },
      "id": "split-dep-batches",
      "name": "Split Dependency Batches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        900,
        500
      ]
    },
    {
      "parameters": {
        "jsCode": "// Split In Batches already grouped items - just serialize them\nconst allItems = $input.all();\nconst batch = allItems.map(item => item.json);\n\nreturn {\n  json: {\n    depsJson: JSON.stringify(batch),\n    batchSize: batch.length\n  }\n};"
      },
      "id": "prepare-dep-batch",
      "name": "Prepare Dependency Batch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        500
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CALL api_wf.sp_module_map(?, 'n8n-automation')",
        "options": {
          "queryParameters": "={{ $json.depsJson }}"
        }
      },
      "id": "map-dependencies",
      "name": "Map Dependencies",
      "type": "n8n-nodes-base.mySql",
      "typeVersion": 2.5,
      "position": [
        1340,
        500
      ],
      "credentials": {
        "mySql": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "=Module analysis complete. Processed modules and dependencies.",
        "options": {}
      },
      "id": "respond-webhook",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        1560,
        300
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Run Madge Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Run Madge Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Madge Analysis": {
      "main": [
        [
          {
            "node": "Analyze Dependencies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Dependencies": {
      "main": [
        [
          {
            "node": "Split Module Batches",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Split Dependency Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Module Batches": {
      "main": [
        [
          {
            "node": "Prepare Module Batch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Module Batch": {
      "main": [
        [
          {
            "node": "Load Modules",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Modules": {
      "main": [
        [
          {
            "node": "Split Module Batches",
            "type": "main",
            "index": 0
          }
        ],
        null,
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Dependency Batches": {
      "main": [
        [
          {
            "node": "Prepare Dependency Batch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Dependency Batch": {
      "main": [
        [
          {
            "node": "Map Dependencies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Dependencies": {
      "main": [
        [
          {
            "node": "Split Dependency Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

How this works

This workflow automates the analysis of module dependencies in your codebase, helping developers and teams identify potential issues like circular references or outdated links without manual effort. It suits software engineers maintaining large JavaScript projects who need regular insights to ensure code stability and reduce refactoring risks. The key step involves using HTTP requests to run Dependency Cruiser on your repository, followed by batching and MySQL storage of the results for easy querying and reporting.

Use this workflow for periodic scans in CI/CD pipelines or nightly checks on evolving codebases to catch dependency problems early. Avoid it for one-off analyses or non-JavaScript projects, as it relies on specific tools like Dependency Cruiser. Common variations include integrating with GitHub webhooks for on-commit triggers or expanding the MySQL schema to track historical dependency trends over time.

About this workflow

Module Dependency Analysis. Uses scheduleTrigger, httpRequest, splitInBatches, mySql. Webhook trigger; 11 nodes.

Source: https://github.com/pchambless/wf-monorepo/blob/47cd16469735c59a12b7c76e2552861f899e335d/.n8n/workflows/module-dependency-analysis.json — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

General

Module Dependency Analysis. Uses scheduleTrigger, mySql, respondToWebhook, httpRequest. Webhook trigger; 12 nodes.

MySQL, HTTP Request
General

Send Dingtalk Message On New Azure Devops Pull Request. Uses mySql, httpRequest, stickyNote. Webhook trigger; 5 nodes.

MySQL, HTTP Request
General

Portfolio Orchestrator. Uses httpRequest. Webhook trigger; 59 nodes.

HTTP Request
General

jump-section: Comment Fix Pipeline. Uses httpRequest. Webhook trigger; 24 nodes.

HTTP Request
General

GitHub Issues Router (Linear / Jira / ClickUp). Uses stickyNote, httpRequest, respondToWebhook. Webhook trigger; 23 nodes.

HTTP Request