This workflow corresponds to n8n.io template #18235 — we link there as the canonical source.
This workflow follows the Gmail → Google Drive recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "sWkIlmUgJKHT6H6c",
"name": "Assess an operating model and generate an AI transformation blueprint",
"tags": [],
"nodes": [
{
"id": "e05f308a-8c4d-44c5-b1b8-0e98191e5edd",
"name": "Community Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
100,
500
],
"parameters": {
"width": 650,
"height": 1850,
"content": "## Assess an operating model and generate an AI transformation blueprint\n\n### Who\u2019s it for\n\nTransformation consultants, automation teams and operations leaders who need to turn operating-model evidence into an evidence-led AI transformation pack.\n\n### What this workflow does\n\n1. Collects organisational evidence from Google Drive and Google Sheets.\n2. Normalises RACI, tool inventory, KPIs and user-provided benchmark data.\n3. Uses OpenAI to identify inefficiencies and map AI/automation opportunities.\n4. Generates a target operating model, future-state architecture and RACI.\n5. Models cautious, hybrid and aggressive financial scenarios.\n6. Assesses change readiness using ADKAR values supplied in the configuration node.\n7. Generates Mermaid diagrams, an executive transformation report and structured outputs.\n8. Writes results to Google Sheets and uploads the report to Google Drive.\n9. Includes optional Slack, Gmail, queue and Supabase modules.\n\n### Set up before first run\n\n- [ ] Open `Set Client Config`.\n- [ ] Enter your Google Drive source file ID.\n- [ ] Enter your master Google Sheet ID.\n- [ ] Enter your output Google Drive folder ID.\n- [ ] Review the financial assumptions.\n- [ ] Review the ADKAR scores and stakeholder JSON.\n- [ ] Select Google Drive credentials.\n- [ ] Select Google Sheets credentials.\n- [ ] Select OpenAI credentials.\n- [ ] Create the required Google Sheet tabs listed in the README.\n- [ ] Leave optional Slack, Gmail, queue and Supabase modules disabled until configured.\n\n### Important controls\n\n- Quantitative benchmarks are **not embedded**. Add your own evidence to the `Benchmarks` tab.\n- Financial assumptions are visible configuration inputs, not universal facts.\n- Change-readiness scores are user inputs, not fabricated by the workflow.\n- AI outputs should be reviewed before being presented as client recommendations.\n\n### Requirements\n\nn8n, OpenAI, Google Drive and Google Sheets. Slack, Gmail and Supabase are optional.\n\n### Customise\n\nChange input tabs, scoring logic, model prompts, financial assumptions, report format, notification channels or memory layer to fit your operating model."
},
"typeVersion": 1
},
{
"id": "70ee8869-e329-4b5a-b205-069e947efdfe",
"name": "Community Section 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
900,
500
],
"parameters": {
"color": 7,
"width": 1400,
"height": 880,
"content": "## Setup and trigger\n\nConfigure the assessment once, then run manually. An optional Google Sheets queue path is included as a disabled extension for teams that want repeatable multi-client intake."
},
"typeVersion": 1
},
{
"id": "289621e9-9a6d-4cd3-9f47-e4dc3a5d504a",
"name": "Community Section 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2600,
500
],
"parameters": {
"color": 7,
"width": 1400,
"height": 1130,
"content": "## Collect operating-model evidence\n\nCollects organisational evidence from Google Drive and a master Google Sheet: RACI, tools inventory, KPI snapshot and user-supplied benchmarks. The cleaner normalises inputs and records data quality."
},
"typeVersion": 1
},
{
"id": "7c5a32f2-b9a6-42ba-9ee7-29b8689d1d4b",
"name": "Community Section 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
4300,
500
],
"parameters": {
"color": 7,
"width": 1400,
"height": 880,
"content": "## Analyse current state and opportunities\n\nUses OpenAI for qualitative inefficiency analysis and AI/automation fit mapping, then combines this with user-provided benchmark evidence. Recommendations should remain evidence-led and subject to human review."
},
"typeVersion": 1
},
{
"id": "160fade9-0f59-4141-b176-fd0e54a26874",
"name": "Community Section 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
900,
2700
],
"parameters": {
"color": 7,
"width": 2200,
"height": 1130,
"content": "## Design the future operating model\n\nBuilds the target operating model, financial scenarios, change-readiness view, RACI, diagrams, KPI projections and executive narrative. Financial and ADKAR assumptions come from the visible configuration node."
},
"typeVersion": 1
},
{
"id": "7f51a530-b197-4308-87a7-0e080c913c71",
"name": "Community Section 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
3400,
2700
],
"parameters": {
"color": 7,
"width": 2800,
"height": 1130,
"content": "## Package and persist deliverables\n\nCreates the report payload, writes structured outputs to Google Sheets and uploads the professional report to Google Drive. Disabled split/write nodes are retained where they support optional output tables."
},
"typeVersion": 1
},
{
"id": "6f783daf-46ad-485a-b03a-a514267e89d4",
"name": "Community Section 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
6500,
2700
],
"parameters": {
"color": 7,
"width": 1500,
"height": 880,
"content": "## Optional delivery and memory extensions\n\nOptional floating modules for email, Slack, queue completion and Supabase memory. Configure credentials and destinations, then enable only the modules you need."
},
"typeVersion": 1
},
{
"id": "da6b33ce-369a-42fb-968f-55a3c9b4ceca",
"name": "Manual Trigger - Start Audit",
"type": "n8n-nodes-base.manualTrigger",
"disabled": false,
"position": [
990,
760
],
"parameters": {},
"typeVersion": 1
},
{
"id": "f6f4584d-594b-4826-861a-0c11431ed40e",
"name": "1.1 Google Drive - Org Data",
"type": "n8n-nodes-base.googleDrive",
"position": [
2690,
760
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set Client Config').first().json.org_drive_file_id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"drawingsToFormat": "application/pdf"
}
}
},
"operation": "download"
},
"typeVersion": 3
},
{
"id": "d272a164-74a2-444f-997f-dfb9e4dd536c",
"name": "1.2 Google Sheets - RACI Matrix",
"type": "n8n-nodes-base.googleSheets",
"position": [
3000,
760
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "RACI_Matrix"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set Client Config').first().json.master_sheet_id }}"
}
},
"typeVersion": 4.5
},
{
"id": "31cd514d-736d-4bd3-ae38-adad92ba3c0a",
"name": "1.4 KPI Snapshot - Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
2690,
1010
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "KPI_Snapshot"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set Client Config').first().json.master_sheet_id }}"
}
},
"typeVersion": 4.5
},
{
"id": "458483f0-aff6-4ef9-b521-efeddec8fe6c",
"name": "Merge Discovery Data",
"type": "n8n-nodes-base.merge",
"position": [
3310,
1010
],
"parameters": {},
"typeVersion": 3
},
{
"id": "1f70a537-51ba-40f9-bdad-80a21baf6984",
"name": "2.1 Data Cleaner",
"type": "n8n-nodes-base.code",
"position": [
2690,
1260
],
"parameters": {
"jsCode": "// Data Cleaner v5 - Enterprise Hardened Version\n// Google Sheets Compatible + Stable Client + Stable Audit ID\n\nconst items = $input.all();\n\n// ============================================================\n// HELPER FUNCTIONS\n// ============================================================\n\nfunction getField(obj, ...possibleNames) {\n for (const name of possibleNames) {\n if (obj[name] !== undefined) return obj[name];\n const lower = name.toLowerCase();\n for (const key of Object.keys(obj)) {\n if (key.toLowerCase() === lower) return obj[key];\n }\n }\n return null;\n}\n\nfunction safeGetNode(nodeName) {\n try {\n const node = $(nodeName);\n if (node && node.first) return node.first().json;\n } catch {}\n return null;\n}\n\nfunction safeNumber(val, fallback = 0) {\n const n = parseFloat(val);\n return isNaN(n) ? fallback : n;\n}\n\n// ============================================================\n// SAFE CLIENT + AUDIT RESOLUTION\n// ============================================================\n\nconst dynamicCfg = safeGetNode('Optional - Map Queue Row to Config') || {};\nconst clientConfig = safeGetNode('Set Client Config') || {};\nconst baseInput = $input.first()?.json || {};\n\nconst resolvedClient =\n clientConfig.client_name ||\n dynamicCfg.client_name ||\n baseInput.client_name ||\n baseInput.Client_Name ||\n \"Unknown Client\";\n\nconst resolvedAuditId =\n clientConfig.audit_id ||\n dynamicCfg.audit_id ||\n baseInput.audit_id ||\n baseInput.Audit_ID ||\n null; // Only generate if truly missing\n\nconst auditIdFinal = resolvedAuditId || `AUDIT_${Date.now()}`;\nconst auditTimestamp =\n clientConfig.audit_timestamp ||\n dynamicCfg.audit_timestamp ||\n new Date().toISOString();\n\n// ============================================================\n// INITIAL STRUCTURE\n// ============================================================\n\nconst currentModelData = {\n client_name: resolvedClient,\n audit_id: auditIdFinal,\n audit_timestamp: auditTimestamp,\n org_structure: [],\n tools: [],\n processes: [],\n kpis: {},\n raw_documents: [],\n data_quality: 0\n};\n\nlet raciCount = 0;\nlet toolCount = 0;\nlet kpiCount = 0;\n\n// ============================================================\n// PROCESS INPUT ROWS\n// ============================================================\n\nfor (const item of items) {\n const data = item.json || {};\n\n const hasRaciSignal =\n getField(data, 'Process/Task', 'Process', 'Task') &&\n getField(data, 'Responsible', 'R');\n\n const hasToolSignal =\n getField(data, 'ToolName', 'Tool Name', 'Tool') &&\n getField(data, 'Purpose', 'Description');\n\n const metric = getField(data, 'Metric', 'KPI', 'Name');\n const value = getField(data, 'Value', 'Vale', 'Amount', 'Score');\n\n // ---- RACI ----\n if (hasRaciSignal) {\n currentModelData.org_structure.push({\n type: 'raci_matrix',\n process: getField(data, 'Process/Task', 'Process', 'Task') || '',\n responsible: getField(data, 'Responsible', 'R') || '',\n accountable: getField(data, 'Accountable', 'A') || '',\n consulted: getField(data, 'Consulted', 'C') || '',\n informed: getField(data, 'Informed', 'I') || '',\n team: getField(data, 'Team', 'Department') || '',\n tool_used: getField(data, 'Tool Used', 'Tool', 'Tools') || '',\n frequency: getField(data, 'Frequency') || '',\n manual_pct: safeNumber(getField(data, 'Manual %', 'Manual')),\n source: 'google_sheets'\n });\n raciCount++;\n continue;\n }\n\n // ---- TOOLS ----\n if (hasToolSignal) {\n currentModelData.tools.push({\n name: getField(data, 'ToolName', 'Tool Name', 'Tool') || '',\n purpose: getField(data, 'Purpose', 'Description', 'Use') || '',\n users: safeNumber(getField(data, 'UserCount', 'User Count', 'Users')),\n overlap_score: safeNumber(getField(data, 'OverlapScore', 'Overlap Score')),\n annual_cost: safeNumber(getField(data, 'AnnualCost', 'Annual Cost', 'Cost')),\n source: 'google_sheets'\n });\n toolCount++;\n continue;\n }\n\n // ---- KPIs ----\n if (metric && value !== null) {\n const metricLower = String(metric).toLowerCase();\n const numValue = safeNumber(value);\n\n if (metricLower.includes('turnaround')) {\n currentModelData.kpis.turnaround_time_avg = numValue;\n } else if (metricLower.includes('utilization')) {\n currentModelData.kpis.fte_utilization = numValue;\n } else if (metricLower.includes('cost')) {\n currentModelData.kpis.cost_per_asset = numValue;\n } else if (metricLower.includes('error')) {\n currentModelData.kpis.error_rate = numValue;\n } else if (metricLower.includes('volume')) {\n currentModelData.kpis.volume_per_month = numValue;\n }\n\n kpiCount++;\n continue;\n }\n\n // ---- DOCUMENTS ----\n if (data.mimeType || item.binary) {\n currentModelData.raw_documents.push({\n name: data.name || 'Document',\n type: data.mimeType || 'unknown',\n source: 'google_drive'\n });\n }\n}\n\n// ============================================================\n// FALLBACK ONLY IF TRULY EMPTY\n// ============================================================\n\nif (raciCount === 0 && currentModelData.org_structure.length === 0) {\n currentModelData.org_structure = [];\n}\n\nif (toolCount === 0 && currentModelData.tools.length === 0) {\n currentModelData.tools = [];\n}\n\nif (Object.keys(currentModelData.kpis).length === 0) {\n currentModelData.kpis = {};\n}\n\n// ============================================================\n// DATA QUALITY SCORE\n// ============================================================\n\nconst dataQuality = Math.round(\n (raciCount > 0 ? 33 : 0) +\n (toolCount > 0 ? 33 : 0) +\n (kpiCount > 0 ? 34 : 0)\n);\n\ncurrentModelData.data_quality = dataQuality;\n\n// ============================================================\n// LOGGING\n// ============================================================\n\nconsole.log('Data Cleaner v5 Summary');\nconsole.log('- Client:', resolvedClient);\nconsole.log('- Audit ID:', auditIdFinal);\nconsole.log('- RACI rows:', raciCount);\nconsole.log('- Tools:', toolCount);\nconsole.log('- KPIs:', kpiCount);\nconsole.log('- Data quality:', dataQuality + '%');\n\n// ============================================================\n// RETURN SINGLE ITEM\n// ============================================================\n\nreturn [{ json: currentModelData }];"
},
"typeVersion": 2
},
{
"id": "3f8dee15-9d9a-46e2-acb0-0a37cbc07575",
"name": "2.3 Map AI and Automation Opportunities",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
4700,
760
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "GPT-4.1-MINI"
},
"options": {
"temperature": 0.4
},
"messages": {
"values": [
{
"content": "=You are an AI transformation specialist mapping automation opportunities.\n\nClient: {{ $('Industry Template Selector').first().json.client_name }}\nSector: {{ $('Industry Template Selector').first().json.sector }}\n\nRECOMMENDED AI SOLUTIONS FOR THIS SECTOR:\n{{ $('Industry Template Selector').first().json.sector_ai_solutions.join('\\n- ') }}\n\nCOMPLIANCE REQUIREMENTS:\n{{ $('Industry Template Selector').first().json.sector_compliance.join(', ') }}\n\nBased on this inefficiency analysis:\n```json\n{{ JSON.stringify($('2.2 Analyse Inefficiencies With OpenAI').first().json, null, 2) }}\n```\n\nFor each identified inefficiency, recommend specific AI/automation solutions.\nPrioritize solutions from the recommended list for this sector, but also consider:\n- content production automation tools\n- n8n workflow automations\n- GPT-4o agentic solutions\n- DeepL, Whisper, Vision APIs\n- Custom automation tools\n\nIMPORTANT: Ensure all recommendations comply with {{ $('Industry Template Selector').first().json.sector_compliance.join(', ') }}\n\nReturn as JSON:\n{\n \"recommendations\": [\n {\n \"process\": \"...\",\n \"ai_fit\": \"High|Medium|Low\",\n \"recommended_tech\": [\"tool1\", \"tool2\"],\n \"implementation_complexity\": \"Simple|Moderate|Complex\",\n \"potential_saving_pct\": 0-100,\n \"estimated_roi_months\": number,\n \"description\": \"How this would work\",\n \"compliance_notes\": \"Any regulatory considerations\"\n }\n ],\n \"sector_summary\": \"Summary of AI opportunities specific to {{ $('Industry Template Selector').first().json.sector }}\"\n}"
}
]
}
},
"typeVersion": 1.7
},
{
"id": "05f72479-fefe-485e-8343-30d53f59823f",
"name": "2.4a Google Sheets - Benchmarks",
"type": "n8n-nodes-base.googleSheets",
"position": [
3000,
1010
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Benchmarks"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set Client Config').first().json.master_sheet_id }}"
}
},
"typeVersion": 4.5
},
{
"id": "0074afb1-84af-4ae1-8009-98671f159f62",
"name": "2.4b Benchmark Comparator",
"type": "n8n-nodes-base.code",
"position": [
5010,
760
],
"parameters": {
"jsCode": "function s(v) {\n if (v === null || v === undefined) return '';\n if (typeof v === 'string') return v;\n try { return JSON.stringify(v); } catch (e) { return String(v); }\n}\n\nfunction stripFences(t) {\n return String(t || '')\n .replace(/```mermaid\\s*/gi, '')\n .replace(/```json\\s*/gi, '')\n .replace(/```/g, '')\n .trim();\n}\n\nfunction wrapMermaid(diagram) {\n const body = stripFences(diagram);\n return '```mermaid\\n' + body + '\\n```';\n}\n\nfunction makeArchitecture(auditId, clientName) {\n const id = auditId || 'unknown';\n const cn = clientName || 'unknown';\n return [\n 'flowchart TB',\n ' subgraph Intake',\n ' A[\"Brief intake\"] --> B[\"Triage and validate\"]',\n ' end',\n ' subgraph Design',\n ' B --> C[\"Operating model blueprint\"]',\n ' C --> D[\"RACI and governance\"]',\n ' end',\n ' subgraph Output',\n ' D --> E[\"Diagrams and reports\"]',\n ' E --> F[\"Write to Google Sheets\"]',\n ' end',\n ' %% audit_id: ' + id,\n ' %% client_name: ' + cn\n ].join('\\n');\n}\n\nfunction makeRoadmap(auditId, clientName) {\n const id = auditId || 'unknown';\n const cn = clientName || 'unknown';\n return [\n 'gantt',\n ' title Operating Model Delivery Roadmap',\n ' dateFormat YYYY-MM-DD',\n ' axisFormat %d %b',\n ' section Foundation',\n ' Data contract and schema :a1, 2026-01-01, 10d',\n ' Sheet upsert and dedupe :a2, after a1, 7d',\n ' section Build',\n ' Executive summary and RACI :b1, after a2, 10d',\n ' Diagrams and reporting pack :b2, after b1, 7d',\n ' section Scale',\n ' Performance tuning :c1, after b2, 7d',\n ' Governance and QA :c2, after c1, 7d',\n ' %% audit_id: ' + id,\n ' %% client_name: ' + cn\n ].join('\\n');\n}\n\nfunction makeProcessFlow(auditId, clientName) {\n const id = auditId || 'unknown';\n const cn = clientName || 'unknown';\n return [\n 'flowchart LR',\n ' I[\"Inputs\"] --> P[\"Process\"] --> O[\"Outputs\"]',\n ' subgraph Inputs',\n ' I1[\"Client config\"]',\n ' I2[\"Audit data\"]',\n ' end',\n ' subgraph Process',\n ' P1[\"Generate operating model\"]',\n ' P2[\"Generate executive summary\"]',\n ' P3[\"Generate RACI\"]',\n ' P4[\"Generate diagrams\"]',\n ' P5[\"Write to Sheets\"]',\n ' end',\n ' subgraph Outputs',\n ' O1[\"Operating model JSON\"]',\n ' O2[\"Executive summary\"]',\n ' O3[\"RACI\"]',\n ' O4[\"Mermaid diagrams\"]',\n ' end',\n ' I1 --> P1',\n ' I2 --> P1',\n ' P1 --> P2 --> P3 --> P4 --> P5',\n ' P5 --> O1',\n ' P5 --> O2',\n ' P5 --> O3',\n ' P5 --> O4',\n ' %% audit_id: ' + id,\n ' %% client_name: ' + cn\n ].join('\\n');\n}\n\nfunction makeTechStack(auditId, clientName) {\n const id = auditId || 'unknown';\n const cn = clientName || 'unknown';\n return [\n 'flowchart TB',\n ' U[\"Users and SMEs\"] --> N[\"n8n workflow\"]',\n ' N --> L[\"LLM calls\"]',\n ' N --> S[\"Google Sheets\"]',\n ' L --> R[\"Model outputs\"]',\n ' S --> R',\n ' subgraph LLM',\n ' L1[\"GPT model\"]',\n ' end',\n ' subgraph Storage',\n ' S1[\"Sheets tabs as store\"]',\n ' end',\n ' %% audit_id: ' + id,\n ' %% client_name: ' + cn\n ].join('\\n');\n}\n\nconst inputItem = $input.first().json || {};\n\nconst audit_id = s(inputItem.audit_id || inputItem.auditId || inputItem.audit || '').trim() || 'unknown';\nconst client_name = s(inputItem.client_name || inputItem.clientName || inputItem.client || '').trim() || 'unknown';\nconst created_at = new Date().toISOString();\nconst render_hint = 'mermaid';\n\nconst diagrams = [\n { diagram_type: 'architecture', mermaid_code: wrapMermaid(makeArchitecture(audit_id, client_name)) },\n { diagram_type: 'roadmap', mermaid_code: wrapMermaid(makeRoadmap(audit_id, client_name)) },\n { diagram_type: 'process_flow', mermaid_code: wrapMermaid(makeProcessFlow(audit_id, client_name)) },\n { diagram_type: 'tech_stack', mermaid_code: wrapMermaid(makeTechStack(audit_id, client_name)) },\n];\n\nreturn diagrams.map(d => {\n return {\n json: {\n row_key: client_name + '|' + audit_id + '|' + d.diagram_type,\n audit_id,\n diagram_type: d.diagram_type,\n mermaid_code: d.mermaid_code,\n render_hint,\n created_at,\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "751ec0b2-259d-4d34-9de1-ed022269d57a",
"name": "Merge Analysis Results",
"type": "n8n-nodes-base.merge",
"position": [
4390,
1010
],
"parameters": {},
"typeVersion": 3
},
{
"id": "9ed62c83-514e-442d-93f5-8ff2cc1e154a",
"name": "3.1 Generate Target Operating Model",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
990,
2960
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "GPT-4.1-MINI"
},
"options": {
"maxTokens": 5000,
"temperature": 0.3
},
"messages": {
"values": [
{
"content": "=You are an enterprise operating model architect specialising in AI-enabled marketing, content, and workflow ecosystems.\n\nYou design implementable, financially grounded, governance-safe target operating models for global organisations.\n\nYou must:\n\nProduce enterprise-grade structures aligned to business outcomes.\n\nDefine clear teams, roles, responsibilities and AI augmentation.\n\nDesign detailed future-state process flows with ownership and automation level.\n\nSpecify technology architecture including AI agents and orchestration workflows.\n\nQuantify impact where possible.\n\nEnsure governance, compliance and change management are addressed.\n\nAvoid generic statements.\n\nOutput strictly valid JSON only.\n\nNever include explanations, markdown, or commentary outside the JSON schema provided by the user.\n\nUSER PROMPT\n\nClient: {{ $json.client_name || \"\" }}\nSector: {{ $json.sector || \"\" }}\nMaturity Stage: {{ $json.maturity_stage || \"\" }}\nMarket Count: {{ $json.market_count || \"\" }}\n\nANALYSIS INPUT:\n{{ JSON.stringify($json, null, 2) }}\n\nDesign a COMPREHENSIVE AI-enabled target operating model aligned to the client context above.\n\nOutput ONLY valid JSON using the exact schema provided below.\n\n{\n\"organization_structure\": {\n\"model_type\": \"Hub-and-Spoke\",\n\"swim_lanes\": [\n{\n\"team\": \"Team Name\",\n\"responsibilities\": [],\n\"ai_augmentation\": \"\",\n\"headcount\": 0,\n\"key_roles\": []\n}\n],\n\"new_roles\": [],\n\"roles_to_eliminate\": []\n},\n\"process_flows\": [],\n\"technology_architecture\": {\n\"future_stack\": {\n\"core_platforms\": [],\n\"ai_layer\": []\n},\n\"ai_agents\": [],\n\"n8n_workflows\": [],\n\"tools_to_retire\": [],\n\"tools_to_add\": []\n},\n\"new_raci_matrix\": [],\n\"transformation_roadmap\": {\n\"phase_1_quick_wins\": {\n\"timeline\": \"\",\n\"objectives\": [],\n\"deliverables\": [],\n\"automation_implementations\": [],\n\"agent_deployments\": []\n},\n\"phase_2_foundation\": {\n\"timeline\": \"\",\n\"objectives\": [],\n\"platform_deployments\": []\n},\n\"phase_3_scale\": {\n\"timeline\": \"\",\n\"market_rollouts\": []\n},\n\"phase_4_optimize\": {\n\"timeline\": \"\",\n\"continuous_improvements\": []\n}\n},\n\"success_metrics\": {\n\"kpis_to_track\": []\n},\n\"change_management\": {\n\"training_required\": [],\n\"risk_mitigation\": []\n}\n}\n\nCRITICAL:\n\nReturn ONLY valid JSON.\n\nDo not add commentary.\n\nDo not wrap in markdown.\n\nDo not explain reasoning.\n\nDo not add fields outside this schema."
}
]
}
},
"typeVersion": 1.7
},
{
"id": "50c8cd39-a95c-4437-9d4e-e28e5a9d365b",
"name": "3.2 Financial Model Deep-Dive",
"type": "n8n-nodes-base.code",
"position": [
1300,
2960
],
"parameters": {
"jsCode": "// Financial Model Deep-Dive - CFO-Grade Financial Analysis\n// Hardened Version - Stable Client + Audit Resolution\n\n// ============================================================\n// SECTION 1: HELPER FUNCTIONS\n// ============================================================\n\nfunction parseAIResponse(content) {\n if (!content) return {};\n let cleaned = content.trim();\n\n if (cleaned.startsWith('```json')) cleaned = cleaned.slice(7);\n else if (cleaned.startsWith('```')) cleaned = cleaned.slice(3);\n if (cleaned.endsWith('```')) cleaned = cleaned.slice(0, -3);\n\n cleaned = cleaned.trim();\n\n try {\n return JSON.parse(cleaned);\n } catch {\n return {};\n }\n}\n\nfunction safeGetNode(nodeName) {\n try {\n const node = $(nodeName);\n if (node && node.first) return node.first().json;\n } catch {}\n return null;\n}\n\n// ============================================================\n// SECTION 2: SAFE INPUT RESOLUTION\n// ============================================================\n\nconst baseInput = $input.first()?.json || {};\n\nconst dynamicCfg = safeGetNode('Optional - Map Queue Row to Config') || {};\nconst clientConfig = safeGetNode('Set Client Config') || {};\nconst cleanedData = safeGetNode('2.1 Data Cleaner') || baseInput || {};\nconst ineffNode = safeGetNode('2.2 Inefficiency Scorer - GPT-4o');\nconst aiNode = safeGetNode('2.3 Map AI and Automation Opportunities');\nconst benchmarkData = safeGetNode('2.4b Benchmark Comparator') || {};\n\nlet inefficiencyData = {};\nlet aiRecommendations = {};\n\nif (ineffNode?.message?.content) {\n inefficiencyData = parseAIResponse(ineffNode.message.content);\n}\n\nif (aiNode?.message?.content) {\n aiRecommendations = parseAIResponse(aiNode.message.content);\n}\n\n// ---- Hardened Client + Audit Resolution ----\n\nconst resolvedClient =\n clientConfig.client_name ||\n dynamicCfg.client_name ||\n cleanedData.client_name ||\n baseInput.client_name ||\n baseInput.Client_Name ||\n \"Unknown Client\";\n\nconst resolvedAuditId =\n cleanedData.audit_id ||\n clientConfig.audit_id ||\n dynamicCfg.audit_id ||\n baseInput.audit_id ||\n baseInput.Audit_ID ||\n `AUDIT_${Date.now()}`;\n\n// ============================================================\n// SECTION 3: CONFIGURATION\n// ============================================================\n\nconst cfgNode = safeGetNode('Set Client Config') || dynamicCfg || clientConfig || {};\nconst config = {\n avg_fte_cost: Number(cfgNode.avg_fte_cost || 85000),\n hours_per_fte_year: Number(cfgNode.hours_per_fte_year || 1800),\n software_license_annual: Number(cfgNode.software_license_annual || 25000),\n integration_cost_per_system: Number(cfgNode.integration_cost_per_system || 15000),\n training_cost_per_fte: Number(cfgNode.training_cost_per_fte || 2500),\n change_management_pct: Number(cfgNode.change_management_pct || 0.15),\n discount_rate: Number(cfgNode.discount_rate || 0.10),\n tax_rate: 0.25,\n inflation_rate: 0.03,\n implementation_risk_buffer: Number(cfgNode.implementation_risk_buffer || 0.20),\n benefit_realization_factor: Number(cfgNode.benefit_realization_factor || 0.85),\n analysis_years: Number(cfgNode.analysis_years || 5),\n market_count: Number(cfgNode.market_count || 5)\n};\n\n// ============================================================\n// SECTION 4: TCO CALCULATION\n// ============================================================\n\nfunction calculateTCO(scenario) {\n\n const complexity_multiplier =\n scenario === 'cautious' ? 0.5 :\n scenario === 'aggressive' ? 1.8 :\n 1.0;\n\n const recommendations = aiRecommendations.recommendations || [];\n\n const simpleCount = recommendations.filter(r => r.implementation_complexity === 'Simple').length;\n const moderateCount = recommendations.filter(r => r.implementation_complexity === 'Moderate').length;\n const complexCount = recommendations.filter(r => r.implementation_complexity === 'Complex').length;\n\n const implementation =\n (2 + Math.floor(complexCount / 2)) * config.software_license_annual * complexity_multiplier +\n (simpleCount * 5000 + moderateCount * 15000 + complexCount * 40000) * complexity_multiplier +\n 20000 * complexity_multiplier;\n\n const contingency = implementation * config.implementation_risk_buffer;\n\n const implementationTotal = Math.round(implementation + contingency);\n\n const recurring = Math.round(\n (implementationTotal * 0.3) +\n config.avg_fte_cost * (scenario === 'aggressive' ? 1.5 : scenario === 'hybrid' ? 1 : 0.5)\n );\n\n return {\n implementation_total: implementationTotal,\n annual_recurring: recurring,\n five_year_total: implementationTotal + (recurring * config.analysis_years)\n };\n}\n\n// ============================================================\n// SECTION 5: BENEFIT CALCULATION\n// ============================================================\n\nfunction calculateBenefits(scenario) {\n\n const scenario_factor =\n scenario === 'cautious' ? 0.4 :\n scenario === 'aggressive' ? 0.8 :\n 0.6;\n\n const inefficiencies = inefficiencyData.inefficiencies || [];\n const total_inefficiency_cost = inefficiencies.reduce((sum, i) => sum + (i.annual_cost || 50000), 0);\n\n const annual_benefit = Math.round(\n total_inefficiency_cost *\n scenario_factor *\n config.benefit_realization_factor\n );\n\n const fte_equivalent = Math.round((annual_benefit / config.avg_fte_cost) * 10) / 10;\n\n return {\n total_annual: annual_benefit,\n fte_equivalent\n };\n}\n\n// ============================================================\n// SECTION 6: FINANCIAL METRICS\n// ============================================================\n\nfunction calculateNPV(initial, annual, recurring) {\n let npv = -initial;\n for (let y = 1; y <= config.analysis_years; y++) {\n const cash = annual - recurring;\n npv += cash / Math.pow(1 + config.discount_rate, y);\n }\n return Math.round(npv);\n}\n\nfunction calculateIRR(initial, annual, recurring) {\n const net = annual - recurring;\n if (net <= 0) return 0;\n return Math.round((net / initial) * 100);\n}\n\nfunction calculatePayback(initial, annual, recurring) {\n const net = annual - recurring;\n if (net <= 0) return null;\n return Math.round((initial / net) * 12);\n}\n\n// ============================================================\n// SECTION 7: BUILD SCENARIO\n// ============================================================\n\nfunction buildScenario(name) {\n\n const tco = calculateTCO(name);\n const benefits = calculateBenefits(name);\n\n const npv = calculateNPV(\n tco.implementation_total,\n benefits.total_annual,\n tco.annual_recurring\n );\n\n const irr = calculateIRR(\n tco.implementation_total,\n benefits.total_annual,\n tco.annual_recurring\n );\n\n const payback = calculatePayback(\n tco.implementation_total,\n benefits.total_annual,\n tco.annual_recurring\n );\n\n const fiveYearROI = Math.round(\n ((benefits.total_annual * config.analysis_years - tco.five_year_total) /\n tco.implementation_total) * 100\n );\n\n return {\n scenario_name: name,\n total_investment: tco.five_year_total,\n annual_benefit: benefits.total_annual,\n npv,\n irr_percentage: irr,\n payback_months: payback,\n five_year_roi: fiveYearROI,\n fte_saved: benefits.fte_equivalent\n };\n}\n\n// ============================================================\n// SECTION 8: EXECUTION\n// ============================================================\n\nconst cautious = buildScenario('cautious');\nconst hybrid = buildScenario('hybrid');\nconst aggressive = buildScenario('aggressive');\n\nconst result = {\n\n audit_id: resolvedAuditId,\n client_name: resolvedClient,\n analysis_date: new Date().toISOString(),\n\n recommended_scenario: 'hybrid',\n\n scenario_comparison: {\n cautious,\n hybrid,\n aggressive\n },\n\n implementation_cost: hybrid.total_investment,\n annual_saving: hybrid.annual_benefit,\n fte_saved: hybrid.fte_saved,\n efficiency_gain_pct: Math.round(\n (hybrid.annual_benefit /\n (hybrid.annual_benefit + calculateTCO('hybrid').annual_recurring)) * 100\n ),\n three_year_roi: hybrid.five_year_roi,\n payback_period_months: hybrid.payback_months\n};\n\nreturn [{ json: result }];"
},
"typeVersion": 2
},
{
"id": "0c7e58e9-6c86-4252-9130-30af2b09b231",
"name": "3.3 Visual Schema Builder",
"type": "n8n-nodes-base.code",
"position": [
1610,
2960
],
"parameters": {
"jsCode": "// Stable Aggregation Node\n// No hard dependency on Set Client Config\n// Works even if executed mid-workflow\n\nconst safeNodeJson = (nodeName) => {\n try {\n if ($(nodeName).isExecuted) {\n return $(nodeName).first().json;\n }\n } catch (e) {}\n return null;\n};\n\nconst base = $input.first()?.json || {};\n\n// Prefer Optional - Map Queue Row to Config\nconst dynamicCfg = safeNodeJson(\"Optional - Map Queue Row to Config\");\nconst setCfg = safeNodeJson(\"Set Client Config\");\n\nconst blueprint =\n safeNodeJson(\"3.1 Generate Target Operating Model\") ||\n base.blueprint ||\n {};\n\nconst roiData =\n safeNodeJson(\"3.2 Financial Model Deep-Dive\") ||\n base.financial_model ||\n {};\n\nconst cfg = {\n ...base,\n ...(dynamicCfg || {}),\n ...(setCfg || {})\n};\n\nconst clientName =\n cfg.client_name ||\n cfg.client ||\n cfg.organisation_name ||\n \"Unknown Client\";\n\nconst auditId =\n cfg.audit_id ||\n roiData.audit_id ||\n blueprint.audit_id ||\n base.audit_id ||\n \"\";\n\nreturn [{\n json: {\n client_name: clientName,\n audit_id: auditId,\n blueprint,\n roi: roiData\n }\n}];"
},
"typeVersion": 2
},
{
"id": "9b38d8f1-49f7-44ee-ac92-1d169a915e2b",
"name": "3.3b Change Management Framework",
"type": "n8n-nodes-base.code",
"position": [
2230,
2960
],
"parameters": {
"jsCode": "const safeNode = (name) => {\n try {\n if ($(name).isExecuted) return $(name).first().json;\n } catch (e) {}\n return null;\n};\n\nfunction parseAIResponse(content) {\n if (!content) return {};\n let cleaned = String(content).trim()\n .replace(/^```json/i, '')\n .replace(/^```/, '')\n .replace(/```$/, '')\n .trim();\n try { return JSON.parse(cleaned); } catch { return {}; }\n}\n\nconst base = $input.first()?.json || {};\nconst cfg = safeNode('Set Client Config') || safeNode('Optional - Map Queue Row to Config') || base;\nconst financialNode = safeNode('3.2 Financial Model Deep-Dive') || {};\nconst blueprintNode = safeNode('3.1 Generate Target Operating Model') || {};\n\nlet blueprint = {};\nif (blueprintNode?.message?.content) blueprint = parseAIResponse(blueprintNode.message.content);\n\nlet stakeholders = [];\ntry {\n stakeholders = JSON.parse(cfg.stakeholders_json || '[]');\n if (!Array.isArray(stakeholders)) stakeholders = [];\n} catch {\n stakeholders = [];\n}\n\nconst adkarScores = {\n awareness: Number(cfg.adkar_awareness || 5),\n desire: Number(cfg.adkar_desire || 5),\n knowledge: Number(cfg.adkar_knowledge || 5),\n ability: Number(cfg.adkar_ability || 5),\n reinforcement: Number(cfg.adkar_reinforcement || 5)\n};\n\nconst adkarOverall = Math.round(\n (adkarScores.awareness + adkarScores.desire + adkarScores.knowledge +\n adkarScores.ability + adkarScores.reinforcement) / 5\n);\n\nconst readinessLevel =\n adkarOverall >= 7 ? 'Ready' :\n adkarOverall >= 5 ? 'Moderate Risk' : 'High Risk';\n\nconst fteSaved =\n financialNode?.scenario_comparison?.hybrid?.fte_saved ||\n financialNode?.scenarios?.hybrid?.fte_saved || 0;\n\nconst trainingNeeds = [\n { role: 'AI / Automation Supervisors', headcount: Math.max(Math.ceil(fteSaved * 0.3), 1), training_hours: 40 },\n { role: 'Automation Builders', headcount: Math.max(Math.ceil(fteSaved * 0.2), 1), training_hours: 40 },\n { role: 'Operational Users', headcount: Math.max(Math.ceil(fteSaved), 1), training_hours: 12 }\n];\n\nconst totalTrainingHours = trainingNeeds.reduce((sum, t) => sum + (t.training_hours * t.headcount), 0);\nconst hourlyTrainingCost = Number(cfg.training_cost_per_fte || 2500) / 40;\nconst totalTrainingCost = Math.round(totalTrainingHours * hourlyTrainingCost);\n\nreturn [{\n json: {\n client_name: cfg.client_name || 'Example Organisation',\n audit_id: cfg.audit_id || '',\n stakeholder_summary: {\n total: stakeholders.length,\n supportive: stakeholders.filter(s => /support|champion/i.test(String(s.current_stance))).length,\n resistant: stakeholders.filter(s => /resist/i.test(String(s.current_stance))).length\n },\n stakeholders,\n adkar_assessment: {\n scores: adkarScores,\n overall_score: adkarOverall,\n readiness_level: readinessLevel\n },\n training_summary: {\n total_hours: totalTrainingHours,\n estimated_cost: totalTrainingCost,\n training_needs: trainingNeeds\n },\n blueprint\n }\n}];"
},
"typeVersion": 2
},
{
"id": "b541585e-4dc3-43a5-9dc6-a46af763fe2b",
"name": "3.4 Generate Executive Transformation Report",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
990,
3460
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "GPT-4.1-MINI"
},
"options": {
"maxTokens": 8000,
"temperature": 0.4
},
"messages": {
"values": [
{
"content": "=Client: {{ $('Optional - Map Queue Row to Config').first().json.client_name }}\nSector: {{ $('Optional - Map Queue Row to Config').first().json.sector }}\nMaturity Stage: {{ $('Optional - Map Queue Row to Config').first().json.maturity_stage }}\n\nData Sources:\n\nOperating Model Blueprint: {{ $json.blueprint_content }}\n\nFinancial Scenario Comparison: {{ JSON.stringify($json.financial_scenarios, null, 2) }}\n\nInefficiency Analysis: {{ $json.inefficiency_content }}\n\nAI Recommendations: {{ $json.recommendations_content }}\n\nFINANCIAL TABLES (Include these EXACTLY in Section 4):\n\n{{ $json.financial_tables.tco_table }}\n\n{{ $json.financial_tables.benefits_table }}\n\n{{ $json.financial_tables.cashflow_table }}\n\n{{ $json.financial_tables.sensitivity_table }}\n\nCreate a COMPREHENSIVE 8\u201310 page executive summary following standard consulting report structure:\n\n{{ $('Optional - Map Queue Row to Config').first().json.client_name }} AI-Enabled Operating Model Transformation\nExecutive Summary & Transformation Roadmap\n\nPrepared by: AI Strategy & Operations Team\nDate: {{ $now.format('MMMM DD, YYYY') }}\nConfidential\n\n1. EXECUTIVE OVERVIEW\n\n1.1 Situation Analysis\n2\u20133 paragraphs covering current state challenges, market context, urgency.\n\n1.2 Transformation Opportunity\n2\u20133 paragraphs covering AI-enabled future state and strategic alignment.\n\n1.3 Recommended Approach\n3\u20134 paragraphs describing Hybrid scenario, phased rollout, critical success factors.\n\n1.4 Expected Business Impact\n\nPresent key metrics from financial_scenarios.hybrid:\n\n5-Year NPV: ${{ $json.financial_scenarios.hybrid.npv.toLocaleString() }}\n\nIRR: {{ $json.financial_scenarios.hybrid.irr }}%\n\nPayback Period: {{ $json.financial_scenarios.hybrid.payback_months }} months\n\n5-Year ROI: {{ $json.financial_scenarios.hybrid.five_year_roi }}%\n\nTotal Investment: ${{ $json.financial_scenarios.hybrid.investment.toLocaleString() }}\n\nAnnual Benefit (Year 3): ${{ $json.financial_scenarios.hybrid.annual_benefit.toLocaleString() }}\n\nFTE Equivalent Savings: {{ $json.financial_scenarios.hybrid.fte_saved }} FTEs\n\n2. CURRENT STATE ASSESSMENT\n\n2.1 Operating Model Maturity\nAnalyze the \"{{ $('Optional - Map Queue Row to Config').first().json.maturity_stage }}\" stage operationally.\n\n2.2 Key Inefficiencies & Pain Points\n\nCreate table:\n\n| Process | Category | Annual Cost Impact | Automation Readiness | Priority |\n\nExtract from inefficiency_content.\n\nDetail top 5\u20137 inefficiencies including Description, Impact, Root Cause, Urgency.\n\n2.3 Cost of Inaction\nQuantify annual cost and 3\u20135 year compounding impact.\n\n3. FUTURE STATE VISION\n\n3.1 AI-Enabled Operating Model Overview\nDescribe architecture and orchestration.\n\n3.2 Core Capabilities Enabled\n6\u20138 new measurable capabilities.\n\n3.3 AI Agents & Automation Architecture\n\nCreate table:\n\n| Agent Name | Platform | Responsibilities | Integration Points | Human Touchpoints |\n\nInclude 6\u20138 agents.\n\n3.4 n8n Workflow Automation\n\nCreate table:\n\n| Workflow Name | Purpose | Trigger | Systems Connected | Frequency |\n\nInclude 6\u20138 workflows.\n\n3.5 New RACI Matrix\n\n| Process | AI Agent | Human Reviewer | Manager | Technology |\n\nShow AI moving into Responsible/Accountable roles where appropriate.\n\n4. FINANCIAL ANALYSIS & ROI\n\nCRITICAL: Include ALL financial tables exactly as provided above.\n\n4.1 TCO Analysis\nInclude TCO table exactly. Provide narrative.\n\n4.2 Benefits Analysis\nInclude benefits table exactly. Explain direct, productivity, strategic value.\n\n4.3 5-Year Cash Flow\nInclude cashflow table exactly. Explain ramp and break-even.\n\n4.4 Scenario Comparison\nCreate comparison narrative across Cautious, Hybrid, Aggressive using financial_scenarios object.\n\n4.5 Sensitivity Analysis\nInclude sensitivity table exactly. Explain risk-adjusted returns.\n\n4.6 Key Financial Assumptions\n\n| Assumption | Value | Rationale |\n\nUse assumptions object from $json.\n\n4.7 Recommendation\nJustify Hybrid scenario using NPV, IRR, payback and risk balance.\n\n5. IMPLEMENTATION ROADMAP\n\nPhase 1\u20134 sequencing with governance.\n\n6. RISKS & MITIGATION\n\nInclude risk matrix table.\n\n7. GOVERNANCE & DECISION FRAMEWORK\n8. NEXT STEPS & CALL TO ACTION"
},
{
"role": "system",
"content": "You are a senior management consultant creating a comprehensive executive summary for a C-suite AI transformation engagement. This is a professional deliverable document. Write in authoritative, data-driven, CFO-ready tone"
}
]
}
},
"typeVersion": 1.7
},
{
"id": "a9db943f-b5a3-4d14-b6e5-2efc4dce035a",
"name": "Optional - Send Slack Summary",
"type": "n8n-nodes-base.slack",
"disabled": true,
"position": [
6590,
2960
],
"parameters": {
"text": "=\ud83c\udfaf AI Operating Model Audit Complete\n\nClient: {{ $if($(\"Set Client Config\").isExecuted, $(\"Set Client Config\").first().json.client_name, ($json.client_name || \"Unknown Client\")) }}\nSector: {{ $if($(\"Set Client Config\").isExecuted, $(\"Set Client Config\").first().json.sector, ($json.sector || \"Unknown\")) }}\nMaturity: {{ $if($(\"Set Client Config\").isExecuted, $(\"Set Client Config\").first().json.maturity_stage, ($json.maturity_stage || \"\")) }}\nMarkets: {{ $if($(\"Set Client Config\").isExecuted, $(\"Set Client Config\").first().json.market_count, ($json.market_count || \"\")) }}\n\nAudit ID: {{ $if($(\"2.1 Data Cleaner\").isExecuted, $(\"2.1 Data Cleaner\").first().json.audit_id, ($json.audit_id || \"\")) }}\nStatus: Completed\nCreated At: {{ $now.toISO() }}\n\nRecommended Scenario: Hybrid\nAnnual Saving: {{ $if($(\"3.2 Financial Model Deep-Dive\").isExecuted, $(\"3.2 Financial Model Deep-Dive\").first().json.scenario_comparison.hybrid.annual_benefit, ($json.scenario_comparison?.hybrid?.annual_benefit || \"\")) }}\nPayback Months: {{ $if($(\"3.2 Financial Model Deep-Dive\").isExecuted, $(\"3.2 Financial Model Deep-Dive\").first().json.scenario_comparison.hybrid.payback_months, ($json.scenario_comparison?.hybrid?.payback_months || \"\")) }}\n5 Year ROI: {{ $if($(\"3.2 Financial Model Deep-Dive\").isExecuted, $(\"3.2 Financial Model Deep-Dive\").first().json.scenario_comparison.hybrid.five_year_roi, ($json.scenario_comparison?.hybrid?.five_year_roi || \"\")) }}\nNPV: {{ $if($(\"3.2 Financial Model Deep-Dive\").isExecuted, $(\"3.2 Financial Model Deep-Dive\").first().json.scenario_comparison.hybrid.npv, ($json.scenario_comparison?.hybrid?.npv || \"\")) }}\nIRR: {{ $if($(\"3.2 Financial Model Deep-Dive\").isExecuted, $(\"3.2 Financial Model Deep-Dive\").first().json.scenario_comparison.hybrid.irr, ($json.scenario_comparison?.hybrid?.irr || \"\")) }}\n\nExecutive Summary Preview:\n{{ $if($(\"3.4 Generate Executive Transformation Report\").isExecuted, $(\"3.4 Generate Executive Transformation Report\").first().json.message.content.substring(0, 1200), (($json.message?.content || $json.executive_summary || \"\").substring(0, 1200))) }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set Client Config').first().json.slack_channel_id }}"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "7caa8fed-ab3c-4434-941a-72c0fa4ec08d",
"name": "Optional - Send Email Summary",
"type": "n8n-nodes-base.gmail",
"disabled": true,
"position": [
6900,
2960
],
"parameters": {
"sendTo": "={{ $('Set Client Config').first().json.notification_email }}",
"message": "={{ $('Final Payload').first().json.email_body }}",
"options": {
"appendAttribution": true
},
"subject": "={{ $('Final Payload').first().json.email_subject || 'AI Operating Model Assessment Complete' }}"
},
"executeOnce": true,
"typeVersion": 2.1
},
{
"id": "3dca08c0-57fd-403e-8db4-eed57e63d371",
"name": "Optional - Store Assessment in Supabase",
"type": "n8n-nodes-base.supabase",
"disabled": true,
"position": [
6590,
3210
],
"parameters": {
"tableId": "creative_memory"
},
"typeVersion": 1
},
{
"id": "3622e126-3564-4c28-8bab-2840403c95a8",
"name": "Optional - Extract Reusable Patterns",
"type": "n8n-nodes-base.code",
"disabled": true,
"position": [
6900,
3210
],
"parameters": {
"jsCode": "// ===============================\n// SAFE NODE ACCESS\n// ===============================\n\nfunction safeNodeJson(nodeName) {\n try {\n const node = $(nodeName);\n if (node && node.isExecuted) {\n return node.first().json || {};\n }\n } catch (e) {}\n return {};\n}\n\nfunction safeContent(nodeName) {\n try {\n const node = $(nodeName);\n if (node && node.isExecuted) {\n return node.first().json?.message?.content || \"\";\n }\n } catch (e) {}\n return \"\";\n}\n\nfunction truncate(text, length = 5000) {\n if (!text) return \"\";\n return String(text).substring(0, length);\n}\n\n// ===============================\n// FETCH UPSTREAM DATA SAFELY\n// ===============================\n\nconst clientConfig = safeNodeJson(\"Set Client Config\");\nconst dataCleaner = safeNodeJson(\"2.1 Data Cleaner\");\nconst inefficiencyScorer = safeNodeJson(\"2.2 Inefficiency Scorer - GPT-4o\");\nconst aiFitMapper = safeNodeJson(\"2.3 Map AI and Automation Opportunities\");\nconst blueprint = safeNodeJson(\"3.1 Generate Target Operating Model\");\nconst roiSimulator = safeNodeJson(\"3.2 Financial Model Deep-Dive\");\n\n// ===============================\n// EXTRACT CONTENT\n// ===============================\n\nconst inefficiencies = safeContent(\"2.2 Inefficiency Scorer - GPT-4o\");\nconst recommendations = safeContent(\"2.3 Map AI and Automation Opportunities\");\nconst blueprintContent = safeContent(\"3.1 Generate Target Operating Model\");\n\n// ===============================\n// NORMALISE FINANCIAL STRUCTURE\n// ===============================\n\nconst scenarios = roiSimulator.scenario_comparison || roiSimulator.scenarios || {};\nconst hybrid = scenarios.hybrid || {};\n\nconst financialTables = roiSimulator.financial_tables || {\n tco_table: \"\",\n benefits_table: \"\",\n cashflow_table: \"\",\n sensitivity_table: \"\"\n};\n\nconst assumptions = roiSimulator.assumptions || {};\n\n// ===============================\n// BUILD CONTEXT OBJECT\n// ===============================\n\nconst context = {\n client_name: clientConfig.client_name || dataCleaner.client_name || $json.client_name || \"Unknown Client\",\n sector: clientConfig.sector || dataCleaner.sector || $json.sector || \"Unknown\",\n maturity_stage: clientConfig.maturity_stage || $json.maturity_stage || \"\",\n audit_id: dataCleaner.audit_id || clientConfig.audit_id || $json.audit_id || \"\",\n audit_date: new Date().toISOString(),\n\n blueprint_content: truncate(blueprintContent),\n inefficiency_content: truncate(inefficiencies),\n recommendations_content: truncate(recommendations),\n\n financial_scenarios: scenarios,\n financial_tables: financialTables,\n assumptions: assumptions,\n\n recommended_scenario: roiSimulator.recommended_scenario || \"hybrid\",\n\n hybrid_metrics: {\n three_year_roi: hybrid.three_year_roi || hybrid.five_year_roi || 0,\n npv: hybrid.npv || 0,\n irr: hybrid.irr || 0,\n payback_months: hybrid.payback_months || 0,\n investment: hybrid.investment || hybrid.implementation_cost || 0,\n annual_benefit: hybrid.annual_benefit || hybrid.annual_saving || 0,\n fte_saved: hybrid.fte_saved || 0\n },\n\n lessons_learned: [\n \"AI transformation for \" + (clientConfig.sector || \"Unknown sector\"),\n \"Maturity stage: \" + (clientConfig.maturity_stage || \"Unspecified\"),\n \"Hybrid ROI: \" + (hybrid.three_year_roi || hybrid.five_year_roi || 0) + \"%\"\n ]\n};\n\n// ===============================\n// LOG FOR DEBUG\n// ===============================\n\nconsole.log(\"Executive Summary Context Built:\");\nconsole.log(\"Client:\", context.client_name);\nconsole.log(\"Sector:\", context.sector);\nconsole.log(\"Scenario Keys:\", Object.keys(context.financial_scenarios || {}));\n\n// ===============================\n// RETURN SINGLE STRUCTURED OBJECT\n// ===============================\n\nreturn [{ json: context }];"
},
"typeVersion": 2
},
{
"id": "d2268325-5960-49cf-922d-abacfcf26d25",
"name": "Optional - Store Patterns in Supabase",
"type": "n8n-nodes-base.supabase",
"disabled": true,
"position": [
7210,
3210
],
"parameters": {
"tableId": "creative_memory"
},
"typeVersion": 1
},
{
"id": "c4588a3f-b1dd-4b06-b8b4-30935d9d945a",
"name": "4.1 Write Operating Model to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
3800,
3460
],
"parameters": {
"columns": {
"value": {
"sector": "={{ $json.sector }}",
"row_key": "={{ $json.row_key }}",
"audit_id": "={{ $json.audit_id }}",
"fte_saved": "={{ $json.fte_saved }}",
"created_at": "={{ $json.created_at }}",
"hybrid_npv": "={{ $json.hybrid_npv }}",
"client_name": "={{ $json.client_name }}",
"cautious_npv": "={{ $json.cautious_npv }}",
"annual_saving": "={{ $json.annual_saving }}",
"run_timestamp": "={{ $json.run_timestamp }}",
"aggressive_npv": "={{ $json.aggressive_npv }}",
"hybrid_irr_pct": "={{ $json.hybrid_irr_pct }}",
"maturity_stage": "={{ $json.maturity_stage }}",
"three_year_roi": "={{ $json.three_year_roi }}",
"cautious_irr_pct": "={{ $json.cautious_irr_pct }}",
"hybrid_fte_saved": "={{ $json.hybrid_fte_saved }}",
"aggressive_irr_pct": "={{ $json.aggressive_irr_pct }}",
"cautious_fte_saved": "={{ $json.cautious_fte_saved }}",
"efficiency_gain_pct": "={{ $json.efficiency_gain_pct }}",
"implementation_cost": "={{ $json.implementation_cost }}",
"aggressive_fte_saved": "={{ $json.aggressive_fte_saved }}",
"recommended_scenario": "={{ $json.recommended_scenario }}",
"hybrid_annual_benefit": "={{ $json.hybrid_annual_benefit }}",
"hybrid_payback_months": "={{ $json.hybrid_payback_months }}",
"payback_period_months": "={{ $json.payback_period_months }}",
"cautious_annual_benefit": "={{ $json.cautious_annual_benefit }}",
"cautious_payback_months": "={{ $json.cautious_payback_months }}",
"hybrid_total_investment": "={{ $json.hybrid_total_investment }}",
"aggressive_annual_benefit": "={{ $json.aggressive_annual_benefit }}",
"aggressive_payback_months": "={{ $json.aggressive_payback_months }}",
"cautious_total_investment": "={{ $json.cautious_total_investment }}",
"aggressive_total_investment": "={{ $json.aggressive_total_investment }}"
},
"schema": [
{
"id": "row_key",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "row_key",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "audit_id",
"type": "string",
"display": true,
"required": false,
"displayName": "audit_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "client_name",
"type": "string",
"display": true,
"required": false,
"displayName": "client_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sector",
"type": "string",
"display": true,
"required": false,
"displayName": "sector",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "maturity_stage",
"type": "string",
"display": true,
"required": false,
"displayName": "maturity_stage",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "run_timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "run_timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "recommended_scenario",
"type": "string",
"display": true,
"required": false,
"displayName": "recommended_scenario",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "implementation_cost",
"type": "string",
"display": true,
"required": false,
"displayName": "implementation_cost",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "annual_saving",
"type": "string",
"display": true,
"required": false,
"displayName": "annual_saving",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fte_saved",
"type": "string",
"display": true,
"required": false,
"displayName": "fte_saved",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "efficiency_gain_pct",
"type": "string",
"display": true,
"required": false,
"displayName": "efficiency_gain_pct",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "three_year_roi",
"type": "string",
"display": true,
"required": false,
"displayName": "three_year_roi",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "payback_period_months",
"type": "string",
"display": true,
"required": false,
"displayName": "payback_period_months",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "cautious_total_investment",
"type": "string",
"display": true,
"required": false,
"displayName": "cautious_total_investment",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "cautious_annual_benefit",
"type": "string",
"display": true,
"required": false,
"displayName": "cautious_annual_benefit",
"defaultMatch": false,
"canBeUsedToMatch": true
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs on demand to collect operating-model evidence from Google Drive and Google Sheets, analyzes inefficiencies and AI opportunities with OpenAI, and produces a target operating model, ROI scenarios, Mermaid diagrams, and an executive report saved back to Google…
Source: https://n8n.io/workflows/18235/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This template is ideal for HR teams, startup founders, operations leads, remote-first companies, and freelancers managing onboarding manually or across multiple tools.
Hiring teams often struggle with document follow-ups, offer letter generation, and stakeholder communication. Manual checks, email back-and-forth, and missing files slow down hiring and create chaos d
This template automates the complete hiring pipeline for digital agencies managing applications across multiple job roles. When a candidate submits a Google Form with their CV, the system scores it wi
n8n Recruitment. Uses gmailTrigger, openAi, googleSheets, gmail. Event-driven trigger; 20 nodes.
Deliver your product updates in a modern, accessible format. This workflow automatically transforms GitHub releases into podcast-style audio announcements and distributes them via email and Slack.