[
  {
    "updatedAt": "2026-05-25T02:38:06.723Z",
    "createdAt": "2026-05-09T20:46:23.974Z",
    "id": "vdv7fILmnhQd9qL2",
    "name": "NFS Mount Watchdog + Auto-Heal v1.3",
    "description": null,
    "active": true,
    "isArchived": false,
    "nodes": [
      {
        "parameters": {
          "rule": {
            "interval": [
              {
                "field": "minutes"
              }
            ]
          }
        },
        "id": "d902559a-9099-4437-acf8-251ddc822dd8",
        "name": "Every 5 Minutes",
        "type": "n8n-nodes-base.scheduleTrigger",
        "typeVersion": 1.2,
        "position": [
          -2016,
          240
        ]
      },
      {
        "parameters": {
          "command": "mountpoint -q /mnt/unraid/data && echo DATA_OK || echo DATA_MISSING; mountpoint -q /mnt/unraid/immich && echo IMMICH_OK || echo IMMICH_MISSING"
        },
        "id": "81396ba5-a882-45c2-82f9-7838ce420d7f",
        "name": "Probe Mounts",
        "type": "n8n-nodes-base.ssh",
        "typeVersion": 1,
        "position": [
          -1792,
          240
        ],
        "credentials": {
          "sshPassword": {
            "id": "0irY4e4WHwyMXKhA",
            "name": "SSH Password account"
          }
        },
        "continueOnFail": true
      },
      {
        "parameters": {
          "jsCode": "const out = ($input.first().json.stdout || '') + ($input.first().json.stderr || '');\nconst dataOk   = out.includes('DATA_OK');\nconst immichOk = out.includes('IMMICH_OK');\nconst missing  = [];\nif (!dataOk)   missing.push({ mount: '/mnt/unraid/data',   label: 'data',\n                               containers: ['ix-plex-plex-1', 'ix-audiobookshelf-audiobookshelf-1', 'calibre-web-automated'] });\nif (!immichOk) missing.push({ mount: '/mnt/unraid/immich', label: 'immich',\n                               containers: ['ix-immich-immich-server-1', 'ix-immich-immich-machine-learning-1'] });\nreturn [{ json: { dataOk, immichOk, anyMissing: missing.length > 0, anyMissingStr: missing.length > 0 ? 'yes' : 'no', missing } }];\n"
        },
        "id": "cbc19d0e-ca0c-41a8-8db6-a5f9754d68bf",
        "name": "Parse Mount Status",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          -1568,
          240
        ]
      },
      {
        "parameters": {
          "conditions": {
            "options": {
              "caseSensitive": true,
              "leftValue": "",
              "typeValidation": "strict",
              "version": 1
            },
            "conditions": [
              {
                "id": "70384f84-9d15-4e45-b295-67202a39a227",
                "leftValue": "={{ $json.anyMissingStr }}",
                "rightValue": "yes",
                "operator": {
                  "type": "string",
                  "operation": "equals"
                }
              }
            ],
            "combinator": "and"
          },
          "options": {}
        },
        "id": "6c0f9f30-a2d3-4f85-a17d-99b215178652",
        "name": "Any Missing?",
        "type": "n8n-nodes-base.if",
        "typeVersion": 2.2,
        "position": [
          -1344,
          240
        ]
      },
      {
        "parameters": {
          "command": "sudo /usr/bin/bash /mnt/tank/docker/scripts/mount-unraid-nfs.sh"
        },
        "id": "764c3d6c-f5fb-4ce7-9291-20718ad3b598",
        "name": "Run Mount Script",
        "type": "n8n-nodes-base.ssh",
        "typeVersion": 1,
        "position": [
          -1120,
          128
        ],
        "credentials": {
          "sshPassword": {
            "id": "0irY4e4WHwyMXKhA",
            "name": "SSH Password account"
          }
        },
        "continueOnFail": true
      },
      {
        "parameters": {},
        "id": "1510ac5b-873f-46d8-b86b-071ab0d6ca26",
        "name": "Wait 10s",
        "type": "n8n-nodes-base.wait",
        "typeVersion": 1.1,
        "position": [
          -896,
          128
        ],
        "webhookId": "4e89e8d0-7f08-4378-a2b7-63756665b039"
      },
      {
        "parameters": {
          "command": "mountpoint -q /mnt/unraid/data && echo DATA_OK || echo DATA_MISSING; mountpoint -q /mnt/unraid/immich && echo IMMICH_OK || echo IMMICH_MISSING"
        },
        "id": "4c4bbe24-d496-435e-ba81-02a91f1fb0b7",
        "name": "Re-probe Mounts",
        "type": "n8n-nodes-base.ssh",
        "typeVersion": 1,
        "position": [
          -672,
          128
        ],
        "credentials": {
          "sshPassword": {
            "id": "0irY4e4WHwyMXKhA",
            "name": "SSH Password account"
          }
        },
        "continueOnFail": true
      },
      {
        "parameters": {
          "jsCode": "const out = ($input.first().json.stdout || '') + ($input.first().json.stderr || '');\nconst dataOk   = out.includes('DATA_OK');\nconst immichOk = out.includes('IMMICH_OK');\n\nconst originalMissing = $('Parse Mount Status').first().json.missing || [];\n\nconst healed = originalMissing.filter(m =>\n  (m.label === 'data'   && dataOk) ||\n  (m.label === 'immich' && immichOk)\n);\nconst stillDown = originalMissing.filter(m =>\n  (m.label === 'data'   && !dataOk) ||\n  (m.label === 'immich' && !immichOk)\n);\n\nconst containersToRestart = [...new Set(healed.flatMap(m => m.containers))];\nconst restartCmd = containersToRestart.length > 0\n  ? `sudo docker restart ${containersToRestart.join(' ')}`\n  : 'echo NO_RESTART_NEEDED';\n\nreturn [{ json: {\n  allHealed: stillDown.length === 0,\n  allHealedStr: stillDown.length === 0 ? 'yes' : 'no',\n  healed,\n  stillDown,\n  containersToRestart,\n  restartCmd,\n  originalMissing\n} }];\n"
        },
        "id": "66a1d989-f0a2-4b5a-b7e0-1cb767d010e6",
        "name": "Parse Heal Result",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          -448,
          128
        ]
      },
      {
        "parameters": {
          "conditions": {
            "options": {
              "caseSensitive": true,
              "leftValue": "",
              "typeValidation": "strict",
              "version": 1
            },
            "conditions": [
              {
                "id": "32b2dfd5-9958-45d4-94fc-410ce4d9543d",
                "leftValue": "={{ $json.allHealedStr }}",
                "rightValue": "yes",
                "operator": {
                  "type": "string",
                  "operation": "equals"
                }
              }
            ],
            "combinator": "and"
          },
          "options": {}
        },
        "id": "49d9ff7a-9227-405d-9887-a7537ce2b844",
        "name": "Healed?",
        "type": "n8n-nodes-base.if",
        "typeVersion": 2.2,
        "position": [
          -224,
          128
        ]
      },
      {
        "parameters": {
          "command": "={{ $json.restartCmd }}"
        },
        "id": "69951482-d5e3-400c-9d3a-3790f671c225",
        "name": "Restart Containers",
        "type": "n8n-nodes-base.ssh",
        "typeVersion": 1,
        "position": [
          0,
          0
        ],
        "credentials": {
          "sshPassword": {
            "id": "0irY4e4WHwyMXKhA",
            "name": "SSH Password account"
          }
        },
        "continueOnFail": true
      },
      {
        "parameters": {
          "jsCode": "const d = $('Parse Heal Result').first().json;\nconst mountList  = d.healed.map(m => `  • ${m.mount}`).join('\\n');\nconst containers = d.containersToRestart.join(', ') || 'none';\nconst body = `NFS mounts were missing and have been automatically remounted.\\n\\nRemounted:\\n${mountList}\\n\\nContainers restarted: ${containers}`;\nreturn [{ json: { title: '🔗 NFS Auto-Healed', message: body, priority: 5 } }];\n"
        },
        "id": "c109df43-532a-4a49-af80-4897bb0b7c1a",
        "name": "Format Healed Notify",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          224,
          0
        ]
      },
      {
        "parameters": {
          "message": "={{ $json.message }}",
          "additionalFields": {
            "priority": "={{ $json.priority }}",
            "title": "={{ $json.title }}"
          },
          "options": {
            "contentType": "text/plain"
          }
        },
        "id": "c8414235-8840-4302-a8e4-6644c3beadb9",
        "name": "Gotify (Healed)",
        "type": "n8n-nodes-base.gotify",
        "typeVersion": 1,
        "position": [
          448,
          0
        ],
        "credentials": {
          "gotifyApi": {
            "id": "K4p3mFrQrjDutIOU",
            "name": "Infrastructure"
          }
        }
      },
      {
        "parameters": {
          "jsCode": "const d = $('Parse Heal Result').first().json;\nconst downList = d.stillDown.map(m => `  • ${m.mount}`).join('\\n');\nconst healedList = d.healed.length > 0\n  ? `\\nPartially healed:\\n${d.healed.map(m => '  • ' + m.mount).join('\\n')}`\n  : '';\nconst body = `NFS mount script ran but the following paths are still unavailable. Manual intervention required.\\n\\nStill down:\\n${downList}${healedList}\\n\\nCheck Serenity (10.5.30.5) is up and NFS service is running.`;\nreturn [{ json: { title: '🚨 NFS Down — Manual Fix Needed', message: body, priority: 9 } }];\n"
        },
        "id": "ff65b3f1-ff81-48dd-a1e8-fd8adcef55d1",
        "name": "Format Escalation",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          0,
          224
        ]
      },
      {
        "parameters": {
          "message": "={{ $json.message }}",
          "additionalFields": {
            "priority": "={{ $json.priority }}",
            "title": "={{ $json.title }}"
          },
          "options": {
            "contentType": "text/plain"
          }
        },
        "id": "39d131f2-f933-4253-92ce-9e312f881b16",
        "name": "Gotify (Escalation)",
        "type": "n8n-nodes-base.gotify",
        "typeVersion": 1,
        "position": [
          224,
          224
        ],
        "credentials": {
          "gotifyApi": {
            "id": "K4p3mFrQrjDutIOU",
            "name": "Infrastructure"
          }
        }
      }
    ],
    "connections": {
      "Every 5 Minutes": {
        "main": [
          [
            {
              "node": "Probe Mounts",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Probe Mounts": {
        "main": [
          [
            {
              "node": "Parse Mount Status",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Parse Mount Status": {
        "main": [
          [
            {
              "node": "Any Missing?",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Any Missing?": {
        "main": [
          [
            {
              "node": "Run Mount Script",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Run Mount Script": {
        "main": [
          [
            {
              "node": "Wait 10s",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Wait 10s": {
        "main": [
          [
            {
              "node": "Re-probe Mounts",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Re-probe Mounts": {
        "main": [
          [
            {
              "node": "Parse Heal Result",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Parse Heal Result": {
        "main": [
          [
            {
              "node": "Healed?",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Healed?": {
        "main": [
          [
            {
              "node": "Restart Containers",
              "type": "main",
              "index": 0
            }
          ],
          [
            {
              "node": "Format Escalation",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Restart Containers": {
        "main": [
          [
            {
              "node": "Format Healed Notify",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Format Healed Notify": {
        "main": [
          [
            {
              "node": "Gotify (Healed)",
              "type": "main",
              "index": 0
            }
          ]
        ]
      },
      "Format Escalation": {
        "main": [
          [
            {
              "node": "Gotify (Escalation)",
              "type": "main",
              "index": 0
            }
          ]
        ]
      }
    },
    "settings": {
      "executionOrder": "v1",
      "binaryMode": "separate"
    },
    "staticData": {
      "node:Every 5 Minutes": {
        "recurrenceRules": []
      }
    },
    "meta": {
      "templateCredsSetupCompleted": true
    },
    "pinData": {},
    "versionId": "68cca20d-5a60-446f-863f-abef2a12639f",
    "activeVersionId": "68cca20d-5a60-446f-863f-abef2a12639f",
    "versionCounter": 45,
    "triggerCount": 1,
    "tags": [
      {
        "updatedAt": "2026-05-06T22:38:51.660Z",
        "createdAt": "2026-05-06T22:38:51.660Z",
        "id": "0ETpkL5jJ5wwgt8k",
        "name": "monitoring"
      },
      {
        "updatedAt": "2026-05-09T18:01:37.295Z",
        "createdAt": "2026-05-09T18:01:37.295Z",
        "id": "PYzt74cSdu6cC6P1",
        "name": "scheduled"
      },
      {
        "updatedAt": "2026-05-09T18:06:13.298Z",
        "createdAt": "2026-05-09T18:06:13.298Z",
        "id": "urlD2YH1LZ32LY2d",
        "name": "infrastructure"
      }
    ],
    "shared": [
      {
        "updatedAt": "2026-05-09T20:46:23.974Z",
        "createdAt": "2026-05-09T20:46:23.974Z",
        "role": "workflow:owner",
        "workflowId": "vdv7fILmnhQd9qL2",
        "projectId": "dxCRnBdX5uJizCGa",
        "project": {
          "updatedAt": "2026-05-06T01:10:37.484Z",
          "createdAt": "2026-05-06T01:08:07.721Z",
          "id": "dxCRnBdX5uJizCGa",
          "name": "Wilfred Fizzlepoof <admin@paccoco.com>",
          "type": "personal",
          "icon": null,
          "description": null,
          "creatorId": "47b2227f-2fc2-4a08-bd35-ea157b92df0d"
        }
      }
    ],
    "versionMetadata": {
      "name": "NFS Mount Watchdog + Auto-Heal v1.3",
      "description": null
    }
  }
]