{ "id": "schoolMorningBrf", "name": "Compass / NHS — 6:00am morning brief", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "0 6 * * *" } ] } }, "id": "c1a0a0a0-0000-4000-8000-000000000001", "name": "6:00am every day", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [200, 360] }, { "parameters": {}, "id": "c1a0a0a0-0000-4000-8000-000000000002", "name": "Run now (manual)", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [200, 180], "notes": "Optional: run the brief by hand from the n8n UI, or with `docker exec n8n n8n execute --id=schoolMorningBrf`. The schedule fires on its own; this trigger only does something when you press it." }, { "parameters": { "authentication": "privateKey", "resource": "command", "operation": "execute", "command": "cd /home/sam/paseo/projects/compass_teams_nhs && ./scripts/morning-brief.sh", "cwd": "/" }, "id": "c1a0a0a0-0000-4000-8000-000000000003", "name": "Run the morning brief on the host", "type": "n8n-nodes-base.ssh", "typeVersion": 1, "position": [480, 360], "notes": "The scan needs node + patchright on .13, so it runs outside this container. The credential is the restricted trigger key: the server's forced command runs exactly scripts/morning-brief.sh, whatever command is sent.", "credentials": { "sshPrivateKey": { "id": "schoolScanKey", "name": "school-scan restricted key" } } }, { "parameters": { "mode": "runOnceForAllItems", "language": "javaScript", "jsCode": "for (const item of $input.all()) {\n if (item.json.code !== 0) {\n throw new Error('morning-brief.sh failed with exit ' + item.json.code + ': ' + (item.json.stderr || ''));\n }\n}\nreturn $input.all();" }, "id": "c1a0a0a0-0000-4000-8000-000000000004", "name": "Red execution when the brief fails", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [720, 360], "notes": "The SSH node reports the remote exit code but does not fail on it. This node turns a non-zero exit (a failed scan or a failed send) into a red execution, so the schedule can never look green when the brief failed (FR-12)." } ], "connections": { "6:00am every day": { "main": [ [ { "node": "Run the morning brief on the host", "type": "main", "index": 0 } ] ] }, "Run now (manual)": { "main": [ [ { "node": "Run the morning brief on the host", "type": "main", "index": 0 } ] ] }, "Run the morning brief on the host": { "main": [ [ { "node": "Red execution when the brief fails", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "timezone": "Australia/Melbourne", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner" }, "staticData": null, "meta": { "templateCredsSetupCompleted": true, "instanceId": "compass-teams-nhs" }, "pinData": {}, "tags": [ { "name": "school" } ], "active": false }