feat(n8n): financial-brief.json workflow for CEO OS automation

This commit is contained in:
admin-valentin 2026-08-26 15:49:20 +00:00
parent 299ffaeb95
commit 9629b4e794

View file

@ -0,0 +1,264 @@
{
"name": "CEO OS — Financial Weekly Brief",
"nodes": [
{
"id": "n4-trigger",
"name": "Every Friday 17:00",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
0,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 17 * * 5"
}
]
}
}
},
{
"id": "n4-vars",
"name": "Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
220,
300
],
"parameters": {
"mode": "manual",
"assignments": {
"assignments": [
{
"id": "d1",
"name": "api",
"value": "={{$env['CEO_OS_API_URL'] ?? 'https://boardmind.dev/api'}}",
"type": "string"
},
{
"id": "d2",
"name": "tenantId",
"value": "={{$env['CEO_OS_TENANT_ID']}}",
"type": "string"
},
{
"id": "d3",
"name": "serviceKey",
"value": "={{$env['CEO_OS_SERVICE_KEY']}}",
"type": "string"
}
]
}
}
},
{
"id": "n4-contracts",
"name": "Get Contracts",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
440,
200
],
"parameters": {
"url": "={{$json.api}}/v1/contracts?tenantId={{$json.tenantId}}",
"method": "GET",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Service-Key",
"value": "={{$json.serviceKey}}"
}
]
}
}
},
{
"id": "n4-obs",
"name": "Get Expense Observations",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
440,
400
],
"parameters": {
"url": "={{$('Config').item.json.api}}/v1/observations?tenantId={{$('Config').item.json.tenantId}}&subjectType=expense",
"method": "GET",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Service-Key",
"value": "={{$('Config').item.json.serviceKey}}"
}
]
}
}
},
{
"id": "n4-build",
"name": "Build Financial Context",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"jsCode": "const cfg = $('Config').item.json;\nconst contracts = $('Get Contracts').all().map(i => i.json);\nconst expenses = $('Get Expense Observations').all().map(i => i.json);\n\nconst now = Date.now();\nconst monthAgo = now - 30 * 86400000;\n\nconst activeContracts = contracts.filter(c => c.status === 'signed' || c.status === 'active');\nconst totalRevenue = activeContracts.reduce((s, c) => s + (parseFloat(c.value) || 0), 0);\n\nconst monthlyExpenses = expenses.filter(e => new Date(e.observedAt || e.createdAt).getTime() > monthAgo);\nconst totalExpenses = monthlyExpenses.reduce((s, e) => s + (parseFloat(e.value) || 0), 0);\n\nconst prompt = [\n `Generează un brief financiar săptămânal. Vineri, ${new Date().toLocaleDateString('ro-RO')}.`,\n '',\n `## Date financiare:`,\n `- Contracte active: ${activeContracts.length} → Total valoare: ${totalRevenue.toLocaleString('ro-RO')} EUR`,\n `- Cheltuieli luna curentă: ${totalExpenses.toLocaleString('ro-RO')} EUR (${monthlyExpenses.length} tranzacții)`,\n `- Sold net estimat: ${(totalRevenue - totalExpenses).toLocaleString('ro-RO')} EUR`,\n '',\n 'Structurează în: 💰 Situație actuală, 📈 Tendință, ⚠️ Atenție la, ✅ Recomandate. Max 200 cuvinte.',\n].join('\\n');\n\nreturn [{ json: {\n prompt, totalRevenue, totalExpenses,\n api: cfg.api, tenantId: cfg.tenantId, serviceKey: cfg.serviceKey,\n}}];"
}
},
{
"id": "n4-ai",
"name": "Generate Financial Brief",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
900,
300
],
"parameters": {
"url": "={{$json.api}}/v1/ai/ask",
"method": "POST",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Service-Key",
"value": "={{$json.serviceKey}}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"messages\": [{\"role\": \"user\", \"content\": {{JSON.stringify($json.prompt)}}}], \"context\": \"{\\\"financialBrief\\\": true}\"}"
}
},
{
"id": "n4-save",
"name": "Save Financial Brief",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1120,
300
],
"parameters": {
"url": "={{$('Build Financial Context').item.json.api}}/v1/observations",
"method": "POST",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Service-Key",
"value": "={{$('Build Financial Context').item.json.serviceKey}}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"tenantId\": \"{{$('Build Financial Context').item.json.tenantId}}\", \"metric\": \"financial-brief\", \"value\": {{JSON.stringify($json.reply)}}, \"unit\": \"{{$('Build Financial Context').item.json.totalRevenue}} EUR\", \"subjectType\": \"finance\", \"confidence\": 0.95}"
}
}
],
"connections": {
"Every Friday 17:00": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"Config": {
"main": [
[
{
"node": "Get Contracts",
"type": "main",
"index": 0
},
{
"node": "Get Expense Observations",
"type": "main",
"index": 0
}
]
]
},
"Get Contracts": {
"main": [
[
{
"node": "Build Financial Context",
"type": "main",
"index": 0
}
]
]
},
"Get Expense Observations": {
"main": [
[
{
"node": "Build Financial Context",
"type": "main",
"index": 0
}
]
]
},
"Build Financial Context": {
"main": [
[
{
"node": "Generate Financial Brief",
"type": "main",
"index": 0
}
]
]
},
"Generate Financial Brief": {
"main": [
[
{
"node": "Save Financial Brief",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"tags": [
{
"name": "ceo-os"
},
{
"name": "finance"
}
]
}