diff --git a/flows/rcm-api.json b/flows/rcm-api.json
new file mode 100644
index 0000000000000000000000000000000000000000..96b63496b25188877561ffbea26743bbde394113
--- /dev/null
+++ b/flows/rcm-api.json
@@ -0,0 +1,2774 @@
+[
+    {
+        "id": "cd1a3aa5b0f95c03",
+        "type": "tab",
+        "label": "rcm-api",
+        "disabled": false,
+        "info": "",
+        "env": []
+    },
+    {
+        "id": "e0c1be655f611144",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "let clusters = [];\n\nfor (let key in msg.payload) {\n    if (key !== '_id') {\n        const cluster = {\n            uuid: msg.payload[key].uuid,\n            name: msg.payload[key].name\n        };\n        clusters.push(cluster);\n    }\n}\n\nmsg.payload = clusters;\nmsg.statusCode = 200;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1020,
+        "y": 120,
+        "wires": [
+            [
+                "ea838ae9449513a2"
+            ]
+        ]
+    },
+    {
+        "id": "ea838ae9449513a2",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1230,
+        "y": 120,
+        "wires": []
+    },
+    {
+        "id": "a7309fefd9edb232",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/",
+        "url": "clusters/",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 150,
+        "y": 120,
+        "wires": [
+            [
+                "4202f8efc990bb4b"
+            ]
+        ]
+    },
+    {
+        "id": "272d1c67f10c2030",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1230,
+        "y": 320,
+        "wires": []
+    },
+    {
+        "id": "57b8ebba50b154ce",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[post] clusters/new",
+        "url": "clusters/new",
+        "method": "post",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 170,
+        "y": 320,
+        "wires": [
+            [
+                "fa0e9ee85f83ba12"
+            ]
+        ]
+    },
+    {
+        "id": "fa0e9ee85f83ba12",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "create cluster",
+        "func": "const uuid = global.get('uuid');\n\nvar cluster = {\n    uuid: uuid.v4().slice(-12),\n    name: msg.payload.name\n};\n\nmsg.payload = cluster;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 520,
+        "y": 320,
+        "wires": [
+            [
+                "09718255f8f6741e"
+            ]
+        ]
+    },
+    {
+        "id": "b17f699e373c6674",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid",
+        "url": "clusters/:cluster_uuid",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 170,
+        "y": 220,
+        "wires": [
+            [
+                "1e854f8ae9200b77"
+            ]
+        ]
+    },
+    {
+        "id": "1e854f8ae9200b77",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 220,
+        "wires": [
+            [
+                "5a7acb94e97d4b82"
+            ]
+        ]
+    },
+    {
+        "id": "9dd38453f326ee5e",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1230,
+        "y": 220,
+        "wires": []
+    },
+    {
+        "id": "09babeec3890ae81",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (!msg.payload.hasOwnProperty('uuid')) {\n    msg.statusCode = 404;\n    msg.payload = {'message': 'Cluster not found'};\n} else {\n    const cluster = {\n        uuid: msg.payload.uuid,\n        name: msg.payload.name\n    };\n    msg.payload = cluster;\n    msg.statusCode = 200;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1020,
+        "y": 220,
+        "wires": [
+            [
+                "9dd38453f326ee5e"
+            ]
+        ]
+    },
+    {
+        "id": "77970b3b8ab1e284",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "const cluster = {\n    uuid: msg.payload.ops[0].uuid,\n    name: msg.payload.ops[0].name\n};\nmsg.payload = cluster;\nmsg.statusCode = 201;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1020,
+        "y": 320,
+        "wires": [
+            [
+                "272d1c67f10c2030"
+            ]
+        ]
+    },
+    {
+        "id": "f591f1548d119c8d",
+        "type": "comment",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "clusters routes",
+        "info": "",
+        "x": 160,
+        "y": 40,
+        "wires": []
+    },
+    {
+        "id": "6b7457bf5bc3abd6",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[delete] clusters/:uuid",
+        "url": "clusters/:cluster_uuid",
+        "method": "delete",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 180,
+        "y": 520,
+        "wires": [
+            [
+                "d48be77db5af4929",
+                "7ebf2f661907fc1f"
+            ]
+        ]
+    },
+    {
+        "id": "d48be77db5af4929",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 520,
+        "wires": [
+            [
+                "d4c2e5b1c98210ea"
+            ]
+        ]
+    },
+    {
+        "id": "15354853a0f76f8e",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1230,
+        "y": 520,
+        "wires": []
+    },
+    {
+        "id": "a3d42eaeb44a1d12",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (msg.payload.value === null) {\n    msg.payload = {'message': 'Cluster not found'};\n    msg.statusCode = 404;\n} else {\n    msg.statusCode = 204;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1020,
+        "y": 520,
+        "wires": [
+            [
+                "15354853a0f76f8e"
+            ]
+        ]
+    },
+    {
+        "id": "d1162fd649690134",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "let devices = [];\n\nfor (let key in msg.payload) {\n    const device = {\n        cluster_uuid: msg.payload[key].cluster_uuid,\n        mac: msg.payload[key].mac,\n        type: msg.payload[key].type,\n        peers: msg.payload[key].peers,\n        gatekeeper: msg.payload[key].gatekeeper,\n        name: msg.payload[key].name\n    };\n    devices.push(device);\n}\n\nmsg.payload = devices;\nmsg.statusCode = 200;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 860,
+        "wires": [
+            [
+                "59cbc4a2396fcb07"
+            ]
+        ]
+    },
+    {
+        "id": "59cbc4a2396fcb07",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 860,
+        "wires": []
+    },
+    {
+        "id": "9cf350e91795988d",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid/devices/",
+        "url": "clusters/:cluster_uuid/devices/",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 190,
+        "y": 860,
+        "wires": [
+            [
+                "7498eb3819ddf4bb"
+            ]
+        ]
+    },
+    {
+        "id": "5160222454aebe76",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid/devices/:mac",
+        "url": "clusters/:cluster_uuid/devices/:mac",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 210,
+        "y": 960,
+        "wires": [
+            [
+                "ec8faba7314174ed"
+            ]
+        ]
+    },
+    {
+        "id": "ec8faba7314174ed",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const mac = msg.req.params.mac.replace(/:/g, '').toLowerCase();\n\nconst query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    mac: mac\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 960,
+        "wires": [
+            [
+                "4899a3a25eed1561"
+            ]
+        ]
+    },
+    {
+        "id": "fcc392c105ebd8c8",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 960,
+        "wires": []
+    },
+    {
+        "id": "d136cdf1d492ef68",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (!msg.payload.hasOwnProperty('mac')) {\n    msg.statusCode = 404;\n    msg.payload = {'message': 'Device not found'};\n} else {\n    const device = {\n        cluster_uuid: msg.payload.cluster_uuid,\n        mac: msg.payload.mac,\n        type: msg.payload.type,\n        peers: msg.payload.peers,\n        gatekeeper: msg.payload.gatekeeper,\n        name: msg.payload.name\n    };\n    msg.payload = device;\n    msg.statusCode = 200;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 960,
+        "wires": [
+            [
+                "fcc392c105ebd8c8"
+            ]
+        ]
+    },
+    {
+        "id": "835832d57bd6f0ac",
+        "type": "comment",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "device routes",
+        "info": "",
+        "x": 150,
+        "y": 780,
+        "wires": []
+    },
+    {
+        "id": "0406a3e9415e28e0",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const mac = msg.req.params.mac.replace(/:/g, '').toLowerCase();\n\nconst query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    mac: mac\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 1740,
+        "wires": [
+            [
+                "168cd3decc642e07"
+            ]
+        ]
+    },
+    {
+        "id": "f11fdbe14655bd62",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (msg.payload.value === null) {\n    msg.payload = {'message': 'Device not found'};\n    msg.statusCode = 404;\n} else {\n    msg.statusCode = 204;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1740,
+        "wires": [
+            [
+                "0001aa12e0168693"
+            ]
+        ]
+    },
+    {
+        "id": "7498eb3819ddf4bb",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 860,
+        "wires": [
+            [
+                "250d9638935f13bd"
+            ]
+        ]
+    },
+    {
+        "id": "7e6b7e76c1c82ec9",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[post] clusters/:uuid/devices/new",
+        "url": "clusters/:cluster_uuid/devices/new",
+        "method": "post",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 210,
+        "y": 1060,
+        "wires": [
+            [
+                "52b343a9804681a3"
+            ]
+        ]
+    },
+    {
+        "id": "e076d396f4f6fc7e",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 1140,
+        "wires": [
+            [
+                "354aa033d8444dac"
+            ],
+            [
+                "abae71d63cb43859"
+            ]
+        ]
+    },
+    {
+        "id": "eb831647f06748c6",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 1060,
+        "wires": []
+    },
+    {
+        "id": "5ec5cceb83a35720",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Mandatory properties missing'};\nmsg.statusCode = 400;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1060,
+        "wires": [
+            [
+                "eb831647f06748c6"
+            ]
+        ]
+    },
+    {
+        "id": "17c935378270b7cc",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 1140,
+        "wires": [
+            [
+                "f175b19af278ea53"
+            ]
+        ]
+    },
+    {
+        "id": "118dcc1368a712cc",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "create device",
+        "func": "const mac = msg.device.mac.replace(/:/g, '').toLowerCase();\n\nconst device = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    mac: mac,\n    type: msg.device.type,\n    peers: msg.device.peers,\n    gatekeeper: msg.device.gatekeeper,\n    name: msg.device.name\n};\n\nmsg.payload = device;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 510,
+        "y": 1300,
+        "wires": [
+            [
+                "84821e5acf338578"
+            ]
+        ]
+    },
+    {
+        "id": "52b343a9804681a3",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "validate input",
+        "func": "msg.valid = true;\n\nif (!msg.payload.hasOwnProperty('mac') ||\n    !msg.payload.hasOwnProperty('type') ||\n    !msg.payload.hasOwnProperty('gatekeeper')) {\n    msg.valid = false;\n}\n\nmsg.device = msg.payload;\n\nif (!msg.payload.hasOwnProperty('peers')) {\n    msg.device.peers = [];\n}\n\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 510,
+        "y": 1060,
+        "wires": [
+            [
+                "1c21d598ad0815cb"
+            ]
+        ]
+    },
+    {
+        "id": "1c21d598ad0815cb",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "input invalid",
+        "property": "valid",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "false"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1010,
+        "y": 1060,
+        "wires": [
+            [
+                "5ec5cceb83a35720"
+            ],
+            [
+                "17c935378270b7cc"
+            ]
+        ]
+    },
+    {
+        "id": "354aa033d8444dac",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1140,
+        "wires": [
+            [
+                "eb831647f06748c6"
+            ]
+        ]
+    },
+    {
+        "id": "93efefe17363902c",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "const device = {\n    cluster_uuid: msg.payload.ops[0].cluster_uuid,\n    mac: msg.payload.ops[0].mac,\n    type: msg.payload.ops[0].type,\n    peers: msg.payload.ops[0].peers,\n    gatekeeper: msg.payload.ops[0].gatekeeper,\n    name: msg.payload.ops[0].name\n};\nmsg.payload = device;\nmsg.statusCode = 201;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1300,
+        "wires": [
+            [
+                "eb831647f06748c6"
+            ]
+        ]
+    },
+    {
+        "id": "7ebf2f661907fc1f",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 580,
+        "wires": [
+            [
+                "b7df39d3b97df8c1",
+                "e026531a626b3444",
+                "b733024bad560aaf"
+            ]
+        ]
+    },
+    {
+        "id": "e410aa38b1107029",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 1660,
+        "wires": [
+            [
+                "ddc998456d395149"
+            ],
+            [
+                "0406a3e9415e28e0"
+            ]
+        ]
+    },
+    {
+        "id": "fc2f9a748e2f46de",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 1660,
+        "wires": [
+            [
+                "5f3acf4d8f64bc66"
+            ]
+        ]
+    },
+    {
+        "id": "ddc998456d395149",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1660,
+        "wires": [
+            [
+                "0001aa12e0168693"
+            ]
+        ]
+    },
+    {
+        "id": "0001aa12e0168693",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 1660,
+        "wires": []
+    },
+    {
+        "id": "4fa74e6c7f41aeed",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[delete] clusters/:uuid/devices/:mac",
+        "url": "clusters/:cluster_uuid/devices/:mac",
+        "method": "delete",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 220,
+        "y": 1660,
+        "wires": [
+            [
+                "fc2f9a748e2f46de"
+            ]
+        ]
+    },
+    {
+        "id": "c35bb61a594d331a",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "device exists",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "nempty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1010,
+        "y": 1220,
+        "wires": [
+            [
+                "5201fa380816b214"
+            ],
+            [
+                "118dcc1368a712cc"
+            ]
+        ]
+    },
+    {
+        "id": "abae71d63cb43859",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const mac = msg.device.mac.replace(/:/g, '').toLowerCase();\n\nconst query = {\n    mac: mac\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 1220,
+        "wires": [
+            [
+                "affa6ac058c92d89"
+            ]
+        ]
+    },
+    {
+        "id": "5201fa380816b214",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Device already exists'};\nmsg.statusCode = 409;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1220,
+        "wires": [
+            [
+                "eb831647f06748c6"
+            ]
+        ]
+    },
+    {
+        "id": "7857e2f187574637",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "let devices = [];\n\nfor (let key in msg.payload) {\n    const device = {\n        cluster_uuid: msg.payload[key].cluster_uuid,\n        mac: msg.payload[key].mac,\n        type: msg.payload[key].type,\n        peers: msg.payload[key].peers,\n        gatekeeper: msg.payload[key].gatekeeper,\n        name: msg.payload[key].name\n    };\n    devices.push(device);\n}\n\nmsg.payload = devices;\nmsg.statusCode = 200;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1900,
+        "wires": [
+            [
+                "1c756725670b2fe1"
+            ]
+        ]
+    },
+    {
+        "id": "1c756725670b2fe1",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 1900,
+        "wires": []
+    },
+    {
+        "id": "c81dc1558c04f5db",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid/files/",
+        "url": "clusters/:cluster_uuid/files/",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 180,
+        "y": 1900,
+        "wires": [
+            [
+                "f825fed3b3ae98cb"
+            ]
+        ]
+    },
+    {
+        "id": "b31cb4668dc9d7fc",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid/files/:uuid",
+        "url": "clusters/:cluster_uuid/files/:file_uuid",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 200,
+        "y": 2000,
+        "wires": [
+            [
+                "1259d84d5ba54448"
+            ]
+        ]
+    },
+    {
+        "id": "1259d84d5ba54448",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: msg.req.params.file_uuid,\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2000,
+        "wires": [
+            [
+                "a4b4879712f47604"
+            ]
+        ]
+    },
+    {
+        "id": "e9a0cc40050fbdd4",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 2000,
+        "wires": []
+    },
+    {
+        "id": "24ab6d7ad83581f3",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (!msg.payload.hasOwnProperty('uuid')) {\n    msg.statusCode = 404;\n    msg.payload = {'message': 'File not found'};\n} else {\n    msg.headers = {\n        \"Content-Disposition\": \"attachment; filename=\" + msg.payload.name,\n        \"Content-Type\": \"application/octet-stream\"\n    };\n    msg.payload = msg.payload.content.toString('ascii');\n    msg.statusCode = 200;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2000,
+        "wires": [
+            [
+                "e9a0cc40050fbdd4"
+            ]
+        ]
+    },
+    {
+        "id": "a49c8ae78144e7a9",
+        "type": "comment",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "files routes",
+        "info": "",
+        "x": 140,
+        "y": 1820,
+        "wires": []
+    },
+    {
+        "id": "19a41948582f4f1c",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: msg.req.params.file_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2440,
+        "wires": [
+            [
+                "0c67fbf600095cde"
+            ]
+        ]
+    },
+    {
+        "id": "8bdd3328a9f3b607",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (msg.payload.value === null) {\n    msg.payload = {'message': 'File not found'};\n    msg.statusCode = 404;\n} else {\n    msg.statusCode = 204;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2440,
+        "wires": [
+            [
+                "1bd75021fdddf3d5"
+            ]
+        ]
+    },
+    {
+        "id": "f825fed3b3ae98cb",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 1900,
+        "wires": [
+            [
+                "659948615a5f8ae9"
+            ]
+        ]
+    },
+    {
+        "id": "73d9f757bc0accf3",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[post] clusters/:uuid/files/new",
+        "url": "clusters/:cluster_uuid/files/new",
+        "method": "post",
+        "upload": true,
+        "swaggerDoc": "",
+        "x": 200,
+        "y": 2100,
+        "wires": [
+            [
+                "5e4e911b962d65e9"
+            ]
+        ]
+    },
+    {
+        "id": "b872ed061b1b0169",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 2180,
+        "wires": [
+            [
+                "9bc08c21cfa5b9c3"
+            ],
+            [
+                "1ad18860012aa07f"
+            ]
+        ]
+    },
+    {
+        "id": "82ee99229a3da714",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 2100,
+        "wires": []
+    },
+    {
+        "id": "90cb98f8db293363",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2180,
+        "wires": [
+            [
+                "449156b1e1645445"
+            ]
+        ]
+    },
+    {
+        "id": "1ad18860012aa07f",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "create file",
+        "func": "const uuid = global.get('uuid');\n\nconst file = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: uuid.v4().slice(-12),\n    name: msg.req.files[0].originalname,\n    description: msg.req.body.description,\n    content: msg.req.files[0].buffer\n};\n\nmsg.payload = file;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2260,
+        "wires": [
+            [
+                "0827ca8dd204de7a"
+            ]
+        ]
+    },
+    {
+        "id": "9bc08c21cfa5b9c3",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2180,
+        "wires": [
+            [
+                "82ee99229a3da714"
+            ]
+        ]
+    },
+    {
+        "id": "9405da8f6960b53d",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "const file = {\n    cluster_uuid: msg.payload.ops[0].cluster_uuid,\n    uuid: msg.payload.ops[0].uuid,\n    name: msg.payload.ops[0].name,\n    description: msg.payload.ops[0].description\n};\nmsg.payload = file;\nmsg.statusCode = 201;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2260,
+        "wires": [
+            [
+                "82ee99229a3da714"
+            ]
+        ]
+    },
+    {
+        "id": "bdd50c9c33588485",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 2360,
+        "wires": [
+            [
+                "5e3ba3d9402105ca"
+            ],
+            [
+                "19a41948582f4f1c"
+            ]
+        ]
+    },
+    {
+        "id": "b1c9e26800e234b9",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2360,
+        "wires": [
+            [
+                "31900f558ea92278"
+            ]
+        ]
+    },
+    {
+        "id": "5e3ba3d9402105ca",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2360,
+        "wires": [
+            [
+                "1bd75021fdddf3d5"
+            ]
+        ]
+    },
+    {
+        "id": "1bd75021fdddf3d5",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 2360,
+        "wires": []
+    },
+    {
+        "id": "e2a7efccafcd0e49",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[delete] clusters/:uuid/files/:uuid",
+        "url": "clusters/:cluster_uuid/files/:file_uuid",
+        "method": "delete",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 210,
+        "y": 2360,
+        "wires": [
+            [
+                "b1c9e26800e234b9"
+            ]
+        ]
+    },
+    {
+        "id": "bda22bbc39de12e7",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Invalid input'};\nmsg.statusCode = 400;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2100,
+        "wires": [
+            [
+                "82ee99229a3da714"
+            ]
+        ]
+    },
+    {
+        "id": "5e4e911b962d65e9",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "validate input",
+        "func": "msg.valid = msg.req.files.length > 0;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 510,
+        "y": 2100,
+        "wires": [
+            [
+                "0d0364a42f4b75f1"
+            ]
+        ]
+    },
+    {
+        "id": "0d0364a42f4b75f1",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "input invalid",
+        "property": "valid",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "false"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1010,
+        "y": 2100,
+        "wires": [
+            [
+                "bda22bbc39de12e7"
+            ],
+            [
+                "90cb98f8db293363"
+            ]
+        ]
+    },
+    {
+        "id": "4202f8efc990bb4b",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find clusters",
+        "collection": "clusters",
+        "operation": "find.toArray",
+        "x": 770,
+        "y": 120,
+        "wires": [
+            [
+                "e0c1be655f611144"
+            ]
+        ]
+    },
+    {
+        "id": "5a7acb94e97d4b82",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 220,
+        "wires": [
+            [
+                "09babeec3890ae81"
+            ]
+        ]
+    },
+    {
+        "id": "d4c2e5b1c98210ea",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete cluster",
+        "collection": "clusters",
+        "operation": "findOneAndDelete",
+        "x": 770,
+        "y": 520,
+        "wires": [
+            [
+                "a3d42eaeb44a1d12"
+            ]
+        ]
+    },
+    {
+        "id": "09718255f8f6741e",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "insert cluster",
+        "collection": "clusters",
+        "operation": "insert",
+        "x": 770,
+        "y": 320,
+        "wires": [
+            [
+                "77970b3b8ab1e284"
+            ]
+        ]
+    },
+    {
+        "id": "250d9638935f13bd",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find devices",
+        "collection": "devices",
+        "operation": "find.toArray",
+        "x": 770,
+        "y": 860,
+        "wires": [
+            [
+                "d1162fd649690134"
+            ]
+        ]
+    },
+    {
+        "id": "4899a3a25eed1561",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find device",
+        "collection": "devices",
+        "operation": "findOne",
+        "x": 770,
+        "y": 960,
+        "wires": [
+            [
+                "d136cdf1d492ef68"
+            ]
+        ]
+    },
+    {
+        "id": "168cd3decc642e07",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete device",
+        "collection": "devices",
+        "operation": "findOneAndDelete",
+        "x": 770,
+        "y": 1740,
+        "wires": [
+            [
+                "f11fdbe14655bd62"
+            ]
+        ]
+    },
+    {
+        "id": "b7df39d3b97df8c1",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete devices",
+        "collection": "devices",
+        "operation": "deleteMany",
+        "x": 780,
+        "y": 580,
+        "wires": [
+            []
+        ]
+    },
+    {
+        "id": "f175b19af278ea53",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 1140,
+        "wires": [
+            [
+                "e076d396f4f6fc7e"
+            ]
+        ]
+    },
+    {
+        "id": "84821e5acf338578",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "insert device",
+        "collection": "devices",
+        "operation": "insert",
+        "x": 770,
+        "y": 1300,
+        "wires": [
+            [
+                "93efefe17363902c"
+            ]
+        ]
+    },
+    {
+        "id": "5f3acf4d8f64bc66",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 1660,
+        "wires": [
+            [
+                "e410aa38b1107029"
+            ]
+        ]
+    },
+    {
+        "id": "affa6ac058c92d89",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find device",
+        "collection": "devices",
+        "operation": "findOne",
+        "x": 770,
+        "y": 1220,
+        "wires": [
+            [
+                "c35bb61a594d331a"
+            ]
+        ]
+    },
+    {
+        "id": "659948615a5f8ae9",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find files",
+        "collection": "files",
+        "operation": "find.toArray",
+        "x": 760,
+        "y": 1900,
+        "wires": [
+            [
+                "7857e2f187574637"
+            ]
+        ]
+    },
+    {
+        "id": "a4b4879712f47604",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find file",
+        "collection": "files",
+        "operation": "findOne",
+        "x": 760,
+        "y": 2000,
+        "wires": [
+            [
+                "24ab6d7ad83581f3"
+            ]
+        ]
+    },
+    {
+        "id": "0c67fbf600095cde",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete file",
+        "collection": "files",
+        "operation": "findOneAndDelete",
+        "x": 760,
+        "y": 2440,
+        "wires": [
+            [
+                "8bdd3328a9f3b607"
+            ]
+        ]
+    },
+    {
+        "id": "449156b1e1645445",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 2180,
+        "wires": [
+            [
+                "b872ed061b1b0169"
+            ]
+        ]
+    },
+    {
+        "id": "0827ca8dd204de7a",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "insert files",
+        "collection": "file",
+        "operation": "insert",
+        "x": 760,
+        "y": 2260,
+        "wires": [
+            [
+                "9405da8f6960b53d"
+            ]
+        ]
+    },
+    {
+        "id": "31900f558ea92278",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 2360,
+        "wires": [
+            [
+                "bdd50c9c33588485"
+            ]
+        ]
+    },
+    {
+        "id": "e026531a626b3444",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete files",
+        "collection": "files",
+        "operation": "deleteMany",
+        "x": 770,
+        "y": 640,
+        "wires": [
+            []
+        ]
+    },
+    {
+        "id": "521b652f385282c6",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "let devices = [];\n\nfor (let key in msg.payload) {\n    if (msg.req.query.hasOwnProperty('compact')) {\n        const configuration = {\n            uuid: msg.payload[key].uuid,\n            files: msg.payload[key].files,\n            commands: msg.payload[key].commands\n        };\n        devices.push(configuration);\n    }\n    else {\n        const configuration = {\n            cluster_uuid: msg.payload[key].cluster_uuid,\n            uuid: msg.payload[key].uuid,\n            status: msg.payload[key].status,\n            gatekeeper_mac: msg.payload[key].gatekeeper_mac,\n            files: msg.payload[key].files,\n            commands: msg.payload[key].commands\n        };\n        devices.push(configuration);\n    }\n}\n\nmsg.payload = devices;\nmsg.statusCode = 200;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2600,
+        "wires": [
+            [
+                "f436e3b4af08c19f"
+            ]
+        ]
+    },
+    {
+        "id": "f436e3b4af08c19f",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 2600,
+        "wires": []
+    },
+    {
+        "id": "0c4868683d223c9a",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid/configurations/",
+        "url": "clusters/:cluster_uuid/configurations/",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 210,
+        "y": 2600,
+        "wires": [
+            [
+                "6bc05c0377927d89"
+            ]
+        ]
+    },
+    {
+        "id": "b4d251e730d3453c",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[get] clusters/:uuid/configurations/:uuid",
+        "url": "clusters/:cluster_uuid/configurations/:configuration_uuid",
+        "method": "get",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 230,
+        "y": 2700,
+        "wires": [
+            [
+                "b6d24ca4798f3e91"
+            ]
+        ]
+    },
+    {
+        "id": "b6d24ca4798f3e91",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: msg.req.params.configuration_uuid,\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2700,
+        "wires": [
+            [
+                "8b25b7b640f6ee34"
+            ]
+        ]
+    },
+    {
+        "id": "d33208d42107ebac",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 2700,
+        "wires": []
+    },
+    {
+        "id": "8c04f7b8950778d2",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (!msg.payload.hasOwnProperty('uuid')) {\n    msg.statusCode = 404;\n    msg.payload = {'message': 'Configuration not found'};\n} else {\n    let configuration = {\n        uuid: msg.payload.uuid,\n        files: msg.payload.files,\n        commands: msg.payload.commands\n    };\n\n    if (!msg.req.query.hasOwnProperty('compact')) {\n            configuration.cluster_uuid = msg.payload.cluster_uuid,\n            configuration.status = msg.payload.status,\n            configuration.gatekeeper_mac = msg.payload.gatekeeper_mac,\n            configuration.files = msg.payload.files,\n            configuration.commands = msg.payload.commands\n    }\n    \n    msg.payload = configuration;\n    msg.statusCode = 200;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2700,
+        "wires": [
+            [
+                "d33208d42107ebac"
+            ]
+        ]
+    },
+    {
+        "id": "4b1c1d47f937e7b1",
+        "type": "comment",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "configurations routes",
+        "info": "",
+        "x": 170,
+        "y": 2520,
+        "wires": []
+    },
+    {
+        "id": "13a1c5722081680e",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: msg.req.params.configuration_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 3400,
+        "wires": [
+            [
+                "129bab5127fb1b91"
+            ]
+        ]
+    },
+    {
+        "id": "d97fe010905f8a54",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (msg.payload.value === null) {\n    msg.payload = {'message': 'Configuration not found'};\n    msg.statusCode = 404;\n} else {\n    msg.statusCode = 204;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 3400,
+        "wires": [
+            [
+                "7e7dbd87468ad124"
+            ]
+        ]
+    },
+    {
+        "id": "6bc05c0377927d89",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "let query = {\n    cluster_uuid: msg.req.params.cluster_uuid\n};\n\nif (msg.req.query.hasOwnProperty('gatekeeper_mac')) {\n    query.gatekeeper_mac = msg.req.query.gatekeeper_mac.replace(/:/g, '').toLowerCase();\n}\nif (msg.req.query.hasOwnProperty('status')) {\n    query.status = msg.req.query.status;\n}\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2600,
+        "wires": [
+            [
+                "1dc74b141d7c211a"
+            ]
+        ]
+    },
+    {
+        "id": "5e737f8b8bd443ee",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[post] clusters/:uuid/configurations/new",
+        "url": "clusters/:cluster_uuid/configurations/new",
+        "method": "post",
+        "upload": true,
+        "swaggerDoc": "",
+        "x": 230,
+        "y": 2800,
+        "wires": [
+            [
+                "cc66150b17c6f92a"
+            ]
+        ]
+    },
+    {
+        "id": "c02e392904f7b083",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 2880,
+        "wires": [
+            [
+                "20e0b3f5bd53df5c"
+            ],
+            [
+                "464fb86dc11eaa17"
+            ]
+        ]
+    },
+    {
+        "id": "945dbe575969713f",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 2800,
+        "wires": []
+    },
+    {
+        "id": "240a36c11ceb3d3c",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 2880,
+        "wires": [
+            [
+                "312bc44faaacc3fa"
+            ]
+        ]
+    },
+    {
+        "id": "464fb86dc11eaa17",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "create configuration",
+        "func": "const uuid = global.get('uuid');\nconst gatekeeper_mac = msg.configuration.gatekeeper_mac.replace(/:/g, '').toLowerCase();\n\nconst configuration = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: uuid.v4().slice(-12),\n    status: 'pending',\n    gatekeeper_mac: gatekeeper_mac,\n    configurations: msg.configuration.configurations\n};\n\nmsg.payload = configuration;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 530,
+        "y": 2960,
+        "wires": [
+            [
+                "f7d5bd57ac377b04"
+            ]
+        ]
+    },
+    {
+        "id": "20e0b3f5bd53df5c",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2880,
+        "wires": [
+            [
+                "945dbe575969713f"
+            ]
+        ]
+    },
+    {
+        "id": "f9355de17a4c0459",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "const configuration = {\n    cluster_uuid: msg.payload.ops[0].cluster_uuid,\n    uuid: msg.payload.ops[0].uuid,\n    status: msg.payload.ops[0].status,\n    gatekeeper_mac: msg.payload.ops[0].gatekeeper_mac,\n    configurations: msg.payload.ops[0].configurations\n};\nmsg.payload = configuration;\nmsg.statusCode = 201;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2960,
+        "wires": [
+            [
+                "945dbe575969713f"
+            ]
+        ]
+    },
+    {
+        "id": "dc3b4049d5279ffb",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 3320,
+        "wires": [
+            [
+                "be780c12369d6509"
+            ],
+            [
+                "13a1c5722081680e"
+            ]
+        ]
+    },
+    {
+        "id": "ca0ad89e576f715c",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 3320,
+        "wires": [
+            [
+                "2f1f20145445d24b"
+            ]
+        ]
+    },
+    {
+        "id": "be780c12369d6509",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 3320,
+        "wires": [
+            [
+                "7e7dbd87468ad124"
+            ]
+        ]
+    },
+    {
+        "id": "7e7dbd87468ad124",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 3320,
+        "wires": []
+    },
+    {
+        "id": "dbc8337383756120",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[delete] clusters/:uuid/configurations/:uuid",
+        "url": "clusters/:cluster_uuid/configurations/:configuration_uuid",
+        "method": "delete",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 240,
+        "y": 3320,
+        "wires": [
+            [
+                "ca0ad89e576f715c"
+            ]
+        ]
+    },
+    {
+        "id": "8d35d8650db34cb6",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Invalid input'};\nmsg.statusCode = 400;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 2800,
+        "wires": [
+            [
+                "945dbe575969713f"
+            ]
+        ]
+    },
+    {
+        "id": "cc66150b17c6f92a",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "validate input",
+        "func": "msg.valid = true;\n\nif (!msg.payload.hasOwnProperty('gatekeeper_mac')) {\n    msg.valid = false;\n}\n\nmsg.configuration = msg.payload;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 510,
+        "y": 2800,
+        "wires": [
+            [
+                "6d6ea3cd189ceaee"
+            ]
+        ]
+    },
+    {
+        "id": "6d6ea3cd189ceaee",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "input invalid",
+        "property": "valid",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "false"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1010,
+        "y": 2800,
+        "wires": [
+            [
+                "8d35d8650db34cb6"
+            ],
+            [
+                "240a36c11ceb3d3c"
+            ]
+        ]
+    },
+    {
+        "id": "1dc74b141d7c211a",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find configurations",
+        "collection": "configurations",
+        "operation": "find.toArray",
+        "x": 790,
+        "y": 2600,
+        "wires": [
+            [
+                "521b652f385282c6"
+            ]
+        ]
+    },
+    {
+        "id": "8b25b7b640f6ee34",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find configuration",
+        "collection": "configurations",
+        "operation": "findOne",
+        "x": 790,
+        "y": 2700,
+        "wires": [
+            [
+                "8c04f7b8950778d2"
+            ]
+        ]
+    },
+    {
+        "id": "129bab5127fb1b91",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete configuration",
+        "collection": "configurations",
+        "operation": "findOneAndDelete",
+        "x": 790,
+        "y": 3400,
+        "wires": [
+            [
+                "d97fe010905f8a54"
+            ]
+        ]
+    },
+    {
+        "id": "312bc44faaacc3fa",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 2880,
+        "wires": [
+            [
+                "c02e392904f7b083"
+            ]
+        ]
+    },
+    {
+        "id": "f7d5bd57ac377b04",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "insert configuration",
+        "collection": "configurations",
+        "operation": "insert",
+        "x": 790,
+        "y": 2960,
+        "wires": [
+            [
+                "f9355de17a4c0459"
+            ]
+        ]
+    },
+    {
+        "id": "2f1f20145445d24b",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 3320,
+        "wires": [
+            [
+                "dc3b4049d5279ffb"
+            ]
+        ]
+    },
+    {
+        "id": "b733024bad560aaf",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "delete configurations",
+        "collection": "configurations",
+        "operation": "deleteMany",
+        "x": 800,
+        "y": 700,
+        "wires": [
+            []
+        ]
+    },
+    {
+        "id": "460de50e61ce1c62",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[patch] clusters/:uuid/configurations/:uuid",
+        "url": "clusters/:cluster_uuid/configurations/:configuration_uuid",
+        "method": "patch",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 240,
+        "y": 3060,
+        "wires": [
+            [
+                "6415b26b26a2f5c3"
+            ]
+        ]
+    },
+    {
+        "id": "7c05ce3c8c1fa314",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 3060,
+        "wires": []
+    },
+    {
+        "id": "053df46cb9d9401c",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (msg.payload.result.n > 0) {\n    msg.payload = { 'message': 'Configuration updated successfully' };\n    msg.statusCode = 200;\n} else {\n    msg.payload = { 'message': 'Configuration not found' };\n    msg.statusCode = 404;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 3220,
+        "wires": [
+            [
+                "7c05ce3c8c1fa314"
+            ]
+        ]
+    },
+    {
+        "id": "d7fc37d7b3a7ffe2",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "update configuration",
+        "collection": "configurations",
+        "operation": "update",
+        "x": 800,
+        "y": 3220,
+        "wires": [
+            [
+                "053df46cb9d9401c"
+            ]
+        ]
+    },
+    {
+        "id": "622ec794d84bc45b",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "update configuration",
+        "func": "const query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    uuid: msg.req.params.configuration_uuid\n};\n\nconst update = {\n    $set: {\n            status: msg.configuration.status\n        }\n};\n\nmsg.payload = [query, update];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 540,
+        "y": 3220,
+        "wires": [
+            [
+                "d7fc37d7b3a7ffe2"
+            ]
+        ]
+    },
+    {
+        "id": "945b819bfbb033b4",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Invalid input'};\nmsg.statusCode = 400;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 3060,
+        "wires": [
+            [
+                "7c05ce3c8c1fa314"
+            ]
+        ]
+    },
+    {
+        "id": "6415b26b26a2f5c3",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "validate input",
+        "func": "msg.valid = true;\n\nif (!msg.payload.hasOwnProperty('status') || (msg.payload.status !== \"pending\" && msg.payload.status !== \"processing\" && msg.payload.status !== \"finished\")) {\n    msg.valid = false;\n}\n\nmsg.configuration = msg.payload;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 510,
+        "y": 3060,
+        "wires": [
+            [
+                "d7f17ba41a4398d6"
+            ]
+        ]
+    },
+    {
+        "id": "d7f17ba41a4398d6",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "input invalid",
+        "property": "valid",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "false"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1010,
+        "y": 3060,
+        "wires": [
+            [
+                "945b819bfbb033b4"
+            ],
+            [
+                "6e053c045974807a"
+            ]
+        ]
+    },
+    {
+        "id": "56f5cc4dcb84a2b0",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 3140,
+        "wires": [
+            [
+                "c8b6d4375c622696"
+            ],
+            [
+                "622ec794d84bc45b"
+            ]
+        ]
+    },
+    {
+        "id": "6e053c045974807a",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 3140,
+        "wires": [
+            [
+                "dc3aa8bd48ac0b33"
+            ]
+        ]
+    },
+    {
+        "id": "c8b6d4375c622696",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 3140,
+        "wires": [
+            [
+                "7c05ce3c8c1fa314"
+            ]
+        ]
+    },
+    {
+        "id": "dc3aa8bd48ac0b33",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 3140,
+        "wires": [
+            [
+                "56f5cc4dcb84a2b0"
+            ]
+        ]
+    },
+    {
+        "id": "115070324bfe512a",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[patch] clusters/:uuid/devices/:mac",
+        "url": "clusters/:cluster_uuid/devices/:mac",
+        "method": "patch",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 220,
+        "y": 1400,
+        "wires": [
+            [
+                "266282a66c85574b"
+            ]
+        ]
+    },
+    {
+        "id": "37128a192e805527",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1490,
+        "y": 1400,
+        "wires": []
+    },
+    {
+        "id": "1fb84143090dcd74",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (msg.payload.result.n > 0) {\n    msg.payload = { 'message': 'Configuration updated successfully' };\n    msg.statusCode = 200;\n} else {\n    msg.payload = { 'message': 'Configuration not found' };\n    msg.statusCode = 404;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1560,
+        "wires": [
+            [
+                "37128a192e805527"
+            ]
+        ]
+    },
+    {
+        "id": "62d7f3d71e91d649",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "update device",
+        "collection": "devices",
+        "operation": "update",
+        "x": 780,
+        "y": 1560,
+        "wires": [
+            [
+                "1fb84143090dcd74"
+            ]
+        ]
+    },
+    {
+        "id": "91f73e2bca602bc0",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "update device",
+        "func": "const mac = msg.req.params.mac.replace(/:/g, '').toLowerCase();\n\nconst query = {\n    cluster_uuid: msg.req.params.cluster_uuid,\n    mac: mac\n};\n\nconst update = {\n    $set: {\n            peers: msg.device.peers\n        }\n};\n\nmsg.payload = [query, update];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 520,
+        "y": 1560,
+        "wires": [
+            [
+                "62d7f3d71e91d649"
+            ]
+        ]
+    },
+    {
+        "id": "b07791e1a0cf3998",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Invalid input'};\nmsg.statusCode = 400;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1400,
+        "wires": [
+            [
+                "37128a192e805527"
+            ]
+        ]
+    },
+    {
+        "id": "266282a66c85574b",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "validate input",
+        "func": "msg.valid = true;\n\nif (!msg.payload.hasOwnProperty('peers')) {\n    msg.valid = false;\n}\n\nmsg.device = msg.payload;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 510,
+        "y": 1400,
+        "wires": [
+            [
+                "3a220f46ebaec8b4"
+            ]
+        ]
+    },
+    {
+        "id": "3a220f46ebaec8b4",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "input invalid",
+        "property": "valid",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "false"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1010,
+        "y": 1400,
+        "wires": [
+            [
+                "b07791e1a0cf3998"
+            ],
+            [
+                "5207c33cfadfaec9"
+            ]
+        ]
+    },
+    {
+        "id": "51b94135b902b353",
+        "type": "switch",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "cluster not found",
+        "property": "payload",
+        "propertyType": "msg",
+        "rules": [
+            {
+                "t": "empty"
+            },
+            {
+                "t": "else"
+            }
+        ],
+        "checkall": "true",
+        "repair": false,
+        "outputs": 2,
+        "x": 1020,
+        "y": 1480,
+        "wires": [
+            [
+                "7ba14089be07867e"
+            ],
+            [
+                "91f73e2bca602bc0"
+            ]
+        ]
+    },
+    {
+        "id": "5207c33cfadfaec9",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 1480,
+        "wires": [
+            [
+                "41d451dc6db2db34"
+            ]
+        ]
+    },
+    {
+        "id": "7ba14089be07867e",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "msg.payload = { 'message': 'Cluster not found'};\nmsg.statusCode = 404;\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1280,
+        "y": 1480,
+        "wires": [
+            [
+                "37128a192e805527"
+            ]
+        ]
+    },
+    {
+        "id": "41d451dc6db2db34",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 1480,
+        "wires": [
+            [
+                "51b94135b902b353"
+            ]
+        ]
+    },
+    {
+        "id": "05b4bbce54b79cc8",
+        "type": "http in",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "[patch] clusters/:uuid",
+        "url": "clusters/:cluster_uuid",
+        "method": "patch",
+        "upload": false,
+        "swaggerDoc": "",
+        "x": 170,
+        "y": 420,
+        "wires": [
+            [
+                "992105113dc594a4"
+            ]
+        ]
+    },
+    {
+        "id": "992105113dc594a4",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "set query",
+        "func": "const query = {\n    uuid: msg.req.params.cluster_uuid\n};\n\nmsg.payload = [query, {}];\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 500,
+        "y": 420,
+        "wires": [
+            [
+                "430813fd8c51758c"
+            ]
+        ]
+    },
+    {
+        "id": "a003be7bc111c3c7",
+        "type": "http response",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "",
+        "statusCode": "",
+        "headers": {},
+        "x": 1230,
+        "y": 420,
+        "wires": []
+    },
+    {
+        "id": "ef64a43b1a31da7f",
+        "type": "function",
+        "z": "cd1a3aa5b0f95c03",
+        "name": "format response",
+        "func": "if (!msg.payload.hasOwnProperty('uuid')) {\n    msg.statusCode = 404;\n    msg.payload = {'message': 'Cluster not found'};\n} else {\n    const cluster = {\n        uuid: msg.payload.uuid,\n        name: msg.payload.name\n    };\n    msg.payload = cluster;\n    msg.statusCode = 200;\n}\nreturn msg;",
+        "outputs": 1,
+        "noerr": 0,
+        "initialize": "",
+        "finalize": "",
+        "libs": [],
+        "x": 1020,
+        "y": 420,
+        "wires": [
+            [
+                "a003be7bc111c3c7"
+            ]
+        ]
+    },
+    {
+        "id": "430813fd8c51758c",
+        "type": "mongodb3 in",
+        "z": "cd1a3aa5b0f95c03",
+        "service": "_ext_",
+        "configNode": "2096b91b638576ce",
+        "name": "find cluster",
+        "collection": "clusters",
+        "operation": "findOne",
+        "x": 770,
+        "y": 420,
+        "wires": [
+            [
+                "ef64a43b1a31da7f"
+            ]
+        ]
+    },
+    {
+        "id": "2096b91b638576ce",
+        "type": "mongodb3",
+        "uri": "mongodb://localhost:27017/rcm-api",
+        "name": "rcm-api",
+        "options": "",
+        "parallelism": "-1"
+    }
+]
\ No newline at end of file