{
  "name": "SmartMart Operational Monitor",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "*/5 * * * *"
            }
          ]
        }
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000001",
      "name": "Every 5 minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [0, 0]
    },
    {
      "parameters": {
        "url": "={{ $env.SMARTMART_BASE_URL }}/api/v1/ai-operations/snapshot",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SMARTMART_N8N_TOKEN }}"
            },
            {
              "name": "Cookie",
              "value": "tunnel_phishing_protection=$env.TUNNEL_COOKIE"
            }
          ]
        },
        "sendQuery": false,
        "sendBody": false,
        "sendPreflight": false,
        "options": {
          "timeout": 10000
        }
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000002",
      "name": "Collect operational snapshot",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [220, 0]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const body = $input.first().json;\nconst snap = body.data ?? body;\nconst risk = snap && snap.risk ? snap.risk : { score: 0, severity: 'NORMAL' };\nconst active = (snap && Array.isArray(snap.active_incidents) && snap.active_incidents[0]) || null;\nreturn [{\n  json: {\n    snapshotId: snap ? snap.snapshot_id : null,\n    riskScore: Number(risk.score || 0),\n    riskSeverity: (risk.severity || 'NORMAL').toUpperCase(),\n    activeIncidentId: active ? active.incident_id : '',\n    context: snap\n  }\n}];"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000003",
      "name": "Normalize snapshot",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [440, 0]
    },
    {
      "parameters": {
        "conditions": {
          "number": {
            "number": [
              {
                "value1": "={{ $json.riskScore }}",
                "operation": "gte",
                "value2": 70
              }
            ]
          }
        },
        "options": {}
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000004",
      "name": "Risk check",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.1,
      "position": [660, 0]
    },
    {
      "parameters": {},
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000005",
      "name": "Monitor OK - no action",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 0.1,
      "position": [880, 200]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const item = $input.first().json;\nreturn [{\n  json: {\n    incidentId: item.activeIncidentId || '',\n    incidentType: item.riskSeverity === 'CRITICAL' ? 'fulfillment_sla' : 'operations_risk',\n    context: item.context,\n    riskScore: item.riskScore,\n    riskSeverity: item.riskSeverity\n  }\n}];"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000006",
      "name": "Incident decision",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [880, -200]
    },
    {
      "parameters": {
        "conditions": {
          "string": {
            "string": [
              {
                "value1": "={{ $json.incidentId }}",
                "operation": "notEmpty"
              }
            ]
          }
        },
        "options": {}
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000007",
      "name": "Incident exists?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.1,
      "position": [1100, -200]
    },
    {
      "parameters": {
        "url": "={{ $env.SMARTMART_BASE_URL }}/api/v1/ai-operations/incidents",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SMARTMART_N8N_TOKEN }}"
            },
            {
              "name": "Cookie",
              "value": "tunnel_phishing_protection=$env.TUNNEL_COOKIE"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "{\n  \"type\": \"{{ $json.incidentType }}\",\n  \"severity\": \"{{ $json.riskSeverity }}\",\n  \"risk_score\": {{ $json.riskScore }},\n  \"summary\": \"n8n monitor: operational risk {{ $json.riskScore }} ({{ $json.riskSeverity }}) detected.\",\n  \"status\": \"open\",\n  \"source\": \"n8n-operational-monitor\"\n}",
        "sendPreflight": false,
        "options": {
          "timeout": 10000
        }
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000008",
      "name": "Create incident",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1320, -360]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const body = $input.first().json;\nconst data = body.data ?? body;\nreturn [{\n  json: {\n    incidentId: data.incident_id || '',\n    incidentType: data.type || 'operations_risk'\n  }\n}];"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000009",
      "name": "Use created incident",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [1540, -360]
    },
    {
      "parameters": {
        "mode": "combine",
        "combineMode": "append"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000010",
      "name": "Merge incident",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.2,
      "position": [1760, -260]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const incident = $input.first().json;\nconst systemPrompt = 'You are the operations analyst for SmartMart. Identify fulfillment risks from the supplied operational context and respond with a SINGLE JSON object only. JSON must match this shape: { \"incident_type\": \"fulfillment_sla\", \"severity\": \"NORMAL|WATCH|ELEVATED|HIGH|CRITICAL\", \"confidence\": 0-1, \"summary\": string, \"root_causes\": [string], \"business_impact\": [string], \"affected_products\": [{sku,name}], \"recommended_actions\": [{ action, title, reason, requires_approval, payload }] }. ALLOWED actions: create_replenishment_task, create_task, send_internal_notification, escalate, reallocate_staff, create_supplier_purchase, request_refund. Mark requires_approval true only for reallocate_staff, create_supplier_purchase, request_refund. No prose, no code fences.';\nreturn [{\n  json: {\n    incidentId: incident.incidentId || '',\n    incidentType: incident.incidentType || 'operations_risk',\n    body: {\n      model: $env.AI_MODEL || 'gpt-4o-mini',\n      temperature: 0.2,\n      response_format: { type: 'json_object' },\n      messages: [\n        { role: 'system', content: systemPrompt },\n        { role: 'user', content: JSON.stringify(incident.context || {}) }\n      ]\n    }\n  }\n}];"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000011",
      "name": "Prepare AI request",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [1980, -260]
    },
    {
      "parameters": {
        "url": "={{ $env.OPENAI_BASE_URL || 'https://api.openai.com/v1' }}/chat/completions",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.OPENAI_API_KEY }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($('Prepare AI request').first().json.body) }}",
        "sendPreflight": false,
        "options": {
          "timeout": 30000
        }
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000012",
      "name": "Ask AI for analysis",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [2200, -260]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const body = $input.first().json;\nconst content = body.choices && body.choices[0] && body.choices[0].message\n  ? body.choices[0].message.content\n  : (body.error ? JSON.stringify({ summary: 'AI analysis failed: ' + body.error.message }) : '{}');\nlet analysis = {};\ntry {\n  analysis = typeof content === 'string' ? JSON.parse(content) : content;\n} catch (e) {\n  analysis = { summary: 'Could not parse AI analysis output', recommended_actions: [] };\n}\nconst incident = $('Merge incident').first().json;\nreturn [{\n  json: {\n    incident_id: incident.incidentId || '',\n    incident_type: incident.incidentType || analysis.incident_type || 'operations_risk',\n    provider: 'openai',\n    model: $env.AI_MODEL || 'gpt-4o-mini',\n    severity: (analysis.severity || 'ELEVATED').toUpperCase(),\n    confidence: Number(analysis.confidence || 0.7),\n    summary: analysis.summary || 'n8n AI analysis completed.',\n    root_causes: analysis.root_causes || [],\n    business_impact: analysis.business_impact || [],\n    evidence: analysis.evidence || [],\n    recommended_actions: (analysis.recommended_actions && analysis.recommended_actions.length ? analysis.recommended_actions : [])\n  }\n}];"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000013",
      "name": "Parse AI analysis",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [2420, -260]
    },
    {
      "parameters": {
        "url": "={{ $env.SMARTMART_BASE_URL }}/api/v1/ai-operations/recommendations",
        "authentication": "none",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SMARTMART_N8N_TOKEN }}"
            },
            {
              "name": "Cookie",
              "value": "tunnel_phishing_protection=$env.TUNNEL_COOKIE"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json) }}",
        "sendPreflight": false,
        "options": {
          "timeout": 15000
        }
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000014",
      "name": "Submit recommendation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [2640, -260]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const body = $input.first().json;\nreturn [{\n  json: {\n    recommendationSent: true,\n    response: body\n  }\n}];"
      },
      "id": "e1b7c9d0-1111-4b2a-9c3d-000000000015",
      "name": "Submission summary",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [2860, -260]
    }
  ],
  "connections": {
    "Every 5 minutes": {
      "main": [[{ "node": "Collect operational snapshot", "type": "main", "index": 0 }]]
    },
    "Collect operational snapshot": {
      "main": [[{ "node": "Normalize snapshot", "type": "main", "index": 0 }]]
    },
    "Normalize snapshot": {
      "main": [[{ "node": "Risk check", "type": "main", "index": 0 }]]
    },
    "Risk check": {
      "main": [
        [{ "node": "Incident decision", "type": "main", "index": 0 }],
        [{ "node": "Monitor OK - no action", "type": "main", "index": 0 }]
      ]
    },
    "Incident decision": {
      "main": [[{ "node": "Incident exists?", "type": "main", "index": 0 }]]
    },
    "Incident exists?": {
      "main": [
        [{ "node": "Merge incident", "type": "main", "index": 0 }],
        [{ "node": "Create incident", "type": "main", "index": 0 }]
      ]
    },
    "Create incident": {
      "main": [[{ "node": "Use created incident", "type": "main", "index": 0 }]]
    },
    "Use created incident": {
      "main": [[{ "node": "Merge incident", "type": "main", "index": 1 }]]
    },
    "Merge incident": {
      "main": [[{ "node": "Prepare AI request", "type": "main", "index": 0 }]]
    },
    "Prepare AI request": {
      "main": [[{ "node": "Ask AI for analysis", "type": "main", "index": 0 }]]
    },
    "Ask AI for analysis": {
      "main": [[{ "node": "Parse AI analysis", "type": "main", "index": 0 }]]
    },
    "Parse AI analysis": {
      "main": [[{ "node": "Submit recommendation", "type": "main", "index": 0 }]]
    },
    "Submit recommendation": {
      "main": [[{ "node": "Submission summary", "type": "main", "index": 0 }]]
    }
  },
  "settings": {
    "errorWorkflow": "SmartMart Error Handler",
    "timezone": "Africa/Lagos",
    "executionOrder": "v1"
  }
}