axis-crm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +122 -0
- package/cli/index.js +106 -0
- package/package.json +36 -0
- package/template/CLAUDE.md +38 -0
- package/template/CRM Dashboard.md +53 -0
- package/template/automations/README.md +62 -0
- package/template/automations/client-research.json +383 -0
- package/template/automations/fireflies-to-crm.json +306 -0
- package/template/clients/acme-consulting/README.md +43 -0
- package/template/clients/acme-consulting/communication/2026-03-01-cena-dohodnuta.md +24 -0
- package/template/clients/acme-consulting/contacts/jana-novakova.md +17 -0
- package/template/clients/acme-consulting/contacts/tomas-dvorak.md +16 -0
- package/template/clients/acme-consulting/files/faktury/.gitkeep +0 -0
- package/template/clients/acme-consulting/files/nabidky/.gitkeep +0 -0
- package/template/clients/acme-consulting/files/smlouvy/.gitkeep +0 -0
- package/template/clients/acme-consulting/meetings/2026-02-10-kickoff.md +25 -0
- package/template/clients/acme-consulting/meetings/2026-03-15-progress-review.md +25 -0
- package/template/clients/acme-consulting/projects/web-redesign/README.md +53 -0
- package/template/clients/acme-consulting/projects/web-redesign/deliverables/.gitkeep +0 -0
- package/template/clients/acme-consulting/projects/web-redesign/notes/.gitkeep +0 -0
- package/template/clients/acme-consulting/projects/web-redesign/zadani.md +33 -0
- package/template/dashboards/client-overview.md +25 -0
- package/template/dashboards/hot-leads.md +23 -0
- package/template/dashboards/pipeline.md +52 -0
- package/template/leads/bytovy-architekt-kovar.md +22 -0
- package/template/leads/green-energy-as.md +22 -0
- package/template/leads/nova-digital-sro.md +22 -0
- package/template/leads/restaurace-u-zlateho-lva.md +23 -0
- package/template/leads/techpro-solutions.md +23 -0
- package/template/rules/fields.md +45 -0
- package/template/rules/lifecycle.md +51 -0
- package/template/rules/scoring.md +43 -0
- package/template/rules/structure.md +82 -0
- package/template/scripts/convert-to-client.sh +133 -0
- package/template/scripts/new-lead.sh +68 -0
- package/template/scripts/new-project.sh +69 -0
- package/template/scripts/validate.sh +149 -0
- package/template/templates/client/README.md +31 -0
- package/template/templates/client/communication/.gitkeep +0 -0
- package/template/templates/client/contacts/.gitkeep +0 -0
- package/template/templates/client/files/.gitkeep +0 -0
- package/template/templates/client/files/faktury/.gitkeep +0 -0
- package/template/templates/client/files/nabidky/.gitkeep +0 -0
- package/template/templates/client/files/smlouvy/.gitkeep +0 -0
- package/template/templates/client/meetings/.gitkeep +0 -0
- package/template/templates/client/projects/.gitkeep +0 -0
- package/template/templates/communication.md +17 -0
- package/template/templates/contact.md +14 -0
- package/template/templates/lead.md +20 -0
- package/template/templates/meeting.md +17 -0
- package/template/templates/project/README.md +34 -0
- package/template/templates/project/deliverables/.gitkeep +0 -0
- package/template/templates/project/notes/.gitkeep +0 -0
- package/template/templates/project/zadani.md +19 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Axis CRM — Meeting to CRM",
|
|
3
|
+
"nodes": [
|
|
4
|
+
{
|
|
5
|
+
"id": "w1-trigger",
|
|
6
|
+
"name": "Fireflies Webhook",
|
|
7
|
+
"type": "n8n-nodes-base.webhook",
|
|
8
|
+
"typeVersion": 2,
|
|
9
|
+
"position": [250, 300],
|
|
10
|
+
"parameters": {
|
|
11
|
+
"httpMethod": "POST",
|
|
12
|
+
"path": "axis-crm-meeting",
|
|
13
|
+
"options": {}
|
|
14
|
+
},
|
|
15
|
+
"webhookId": "axis-crm-meeting"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "w1-get-transcript",
|
|
19
|
+
"name": "Get Transcript",
|
|
20
|
+
"type": "@firefliesai/n8n-nodes-fireflies.fireflies",
|
|
21
|
+
"typeVersion": 1,
|
|
22
|
+
"position": [450, 300],
|
|
23
|
+
"parameters": {
|
|
24
|
+
"transcriptId": "={{ $json.body.meetingId }}"
|
|
25
|
+
},
|
|
26
|
+
"credentials": {
|
|
27
|
+
"firefliesApi": {
|
|
28
|
+
"id": "YOUR_FIREFLIES_CREDENTIAL_ID",
|
|
29
|
+
"name": "Fireflies API"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "w1-extract",
|
|
35
|
+
"name": "Extract Meeting Data",
|
|
36
|
+
"type": "n8n-nodes-base.code",
|
|
37
|
+
"typeVersion": 2,
|
|
38
|
+
"position": [650, 300],
|
|
39
|
+
"parameters": {
|
|
40
|
+
"jsCode": "const raw = $input.first().json;\nconst ff = raw.data || raw;\nconst title = ff.title || 'Unknown Meeting';\nconst rawDate = ff.dateString || ff.date || '';\nlet date;\nif (typeof rawDate === 'number') {\n date = new Date(rawDate).toISOString().split('T')[0];\n} else if (rawDate) {\n date = new Date(rawDate).toISOString().split('T')[0];\n} else {\n date = new Date().toISOString().split('T')[0];\n}\nconst duration = ff.duration || 0;\nconst transcript = ff.sentences?.map(s => s.speaker_name + ': ' + s.text).join('\\n') || '';\nconst summaryObj = ff.summary || {};\nconst summaryText = typeof summaryObj === 'string' ? summaryObj : (summaryObj.overview || summaryObj.shorthand_bullet || '');\nconst actionItemsRaw = typeof summaryObj === 'object' ? summaryObj.action_items : '';\nconst actionItems = actionItemsRaw ? actionItemsRaw.split('\\n').filter(l => l.trim()) : [];\nconst participants = [];\nconst speakers = ff.speakers || [];\nspeakers.forEach(s => {\n const name = s.name || s.speaker_name || 'Unknown';\n if (!participants.includes(name)) participants.push(name);\n});\nif (participants.length === 0 && ff.sentences) {\n ff.sentences.forEach(s => {\n if (s.speaker_name && !participants.includes(s.speaker_name)) participants.push(s.speaker_name);\n });\n}\nif (participants.length === 0 && ff.meeting_attendees) {\n ff.meeting_attendees.forEach(a => {\n const name = a.displayName || a.name || a.email || 'Unknown';\n if (!participants.includes(name)) participants.push(name);\n });\n}\nreturn [{\n json: {\n title, date, duration,\n transcript: transcript.substring(0, 10000),\n summary: summaryText,\n actionItems,\n participants\n }\n}];"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "w1-prep-ai",
|
|
45
|
+
"name": "Prepare AI Request",
|
|
46
|
+
"type": "n8n-nodes-base.code",
|
|
47
|
+
"typeVersion": 2,
|
|
48
|
+
"position": [850, 300],
|
|
49
|
+
"parameters": {
|
|
50
|
+
"jsCode": "const data = $input.first().json;\n\nconst prompt = `Analyzuj tento meeting a urcni ke kteremu klientovi patri.\n\nMeeting: ${data.title}\nUcastnici: ${data.participants.join(', ')}\nSummary: ${data.summary}\nTranscript (prvnich 2000 znaku):\n${data.transcript.substring(0, 2000)}\n\nOdpovez POUZE validnim JSON (bez markdown code blocku):\n{\n \"client_slug\": \"nazev-firmy-lowercase-pomlcky-bez-sro\",\n \"client_name\": \"Oficialni nazev firmy\",\n \"is_new\": true,\n \"attendees\": [\"jmeno1\", \"jmeno2\"],\n \"summary\": \"2-3 vety co se resilo\",\n \"action_items\": [\"ukol1\", \"ukol2\"],\n \"topics\": [\"tema1\", \"tema2\"]\n}`;\n\nreturn [{\n json: {\n ...data,\n aiRequestBody: JSON.stringify({\n model: 'claude-sonnet-4-20250514',\n max_tokens: 1024,\n messages: [{ role: 'user', content: prompt }]\n })\n }\n}];"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "w1-ai",
|
|
55
|
+
"name": "AI Identify Client",
|
|
56
|
+
"type": "n8n-nodes-base.httpRequest",
|
|
57
|
+
"typeVersion": 4.2,
|
|
58
|
+
"position": [1050, 300],
|
|
59
|
+
"parameters": {
|
|
60
|
+
"method": "POST",
|
|
61
|
+
"url": "https://api.anthropic.com/v1/messages",
|
|
62
|
+
"sendBody": true,
|
|
63
|
+
"specifyBody": "json",
|
|
64
|
+
"jsonBody": "={{ $json.aiRequestBody }}",
|
|
65
|
+
"sendHeaders": true,
|
|
66
|
+
"headerParameters": {
|
|
67
|
+
"parameters": [
|
|
68
|
+
{ "name": "anthropic-version", "value": "2023-06-01" },
|
|
69
|
+
{ "name": "Content-Type", "value": "application/json" }
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"options": { "timeout": 30000 },
|
|
73
|
+
"authentication": "predefinedCredentialType",
|
|
74
|
+
"nodeCredentialType": "anthropicApi"
|
|
75
|
+
},
|
|
76
|
+
"credentials": {
|
|
77
|
+
"anthropicApi": { "id": "YOUR_ANTHROPIC_CREDENTIAL_ID", "name": "Anthropic API" }
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "w1-build",
|
|
82
|
+
"name": "Build Meeting Markdown",
|
|
83
|
+
"type": "n8n-nodes-base.code",
|
|
84
|
+
"typeVersion": 2,
|
|
85
|
+
"position": [1250, 300],
|
|
86
|
+
"parameters": {
|
|
87
|
+
"jsCode": "const meeting = $('Extract Meeting Data').first().json;\nconst aiResponse = $input.first().json;\nconst aiText = aiResponse.content?.[0]?.text || aiResponse.text || JSON.stringify(aiResponse);\n\nlet analysis;\ntry {\n const jsonMatch = aiText.match(/\\{[\\s\\S]*\\}/);\n analysis = JSON.parse(jsonMatch[0]);\n} catch(e) {\n const slug = meeting.title.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').substring(0, 40);\n analysis = {\n client_slug: slug, client_name: meeting.title, is_new: true,\n attendees: meeting.participants, summary: meeting.summary || '',\n action_items: meeting.actionItems || [], topics: []\n };\n}\n\nconst slug = analysis.client_slug;\nconst date = meeting.date;\nconst filename = date + '-' + slug + '.md';\n\nconst actionItemsMd = analysis.action_items.length > 0\n ? analysis.action_items.map(a => '- [ ] ' + a).join('\\n')\n : '- [ ] ';\nconst topicsMd = analysis.topics.length > 0\n ? analysis.topics.map(t => '- ' + t).join('\\n')\n : '';\nconst attendeeYaml = analysis.attendees.map(a => \"'\" + a.replace(/'/g, \"''\") + \"'\").join(', ');\n\nconst meetingMd = [\n '---',\n \"title: '\" + meeting.title.replace(/'/g, \"''\") + \"'\",\n \"date: '\" + date + \"'\",\n 'tags: [meeting]',\n 'type: meeting',\n 'attendees: [' + attendeeYaml + ']',\n \"duration: '\" + meeting.duration + \" min'\",\n 'next_steps: []',\n '---',\n '',\n '## Summary',\n '',\n analysis.summary,\n '',\n '## Topics',\n '',\n topicsMd,\n '',\n '## Action Items',\n '',\n actionItemsMd,\n '',\n '## Transcript',\n '',\n '<details>',\n '<summary>Full transcript</summary>',\n '',\n meeting.transcript,\n '',\n '</details>'\n].join('\\n');\n\nlet clientReadme = '';\nif (analysis.is_new) {\n clientReadme = [\n '---',\n \"title: '\" + analysis.client_name.replace(/'/g, \"''\") + \"'\",\n \"created: '\" + date + \"'\",\n 'tags: [client]',\n 'type: client',\n \"status: 'active'\",\n \"source: 'meeting'\",\n 'score: 0',\n '---',\n '',\n '## Overview',\n '',\n 'Auto-created from meeting: ' + meeting.title,\n '',\n '## Contacts',\n '',\n analysis.attendees.map(a => '- ' + a).join('\\n')\n ].join('\\n');\n}\n\nreturn [{\n json: {\n client_slug: slug,\n client_name: analysis.client_name,\n is_new: analysis.is_new,\n filename,\n meetingMdContent: meetingMd,\n clientReadmeContent: clientReadme,\n meetingPath: 'clients/' + slug + '/meetings/' + filename,\n clientReadmePath: 'clients/' + slug + '/README.md',\n ntfyBody: 'Meeting ' + filename + ' saved for ' + analysis.client_name\n }\n}];"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "w1-if-new",
|
|
92
|
+
"name": "New Client?",
|
|
93
|
+
"type": "n8n-nodes-base.if",
|
|
94
|
+
"typeVersion": 2.2,
|
|
95
|
+
"position": [1450, 300],
|
|
96
|
+
"parameters": {
|
|
97
|
+
"conditions": {
|
|
98
|
+
"options": { "version": 2 },
|
|
99
|
+
"combinator": "and",
|
|
100
|
+
"conditions": [
|
|
101
|
+
{
|
|
102
|
+
"leftValue": "={{ $json.is_new }}",
|
|
103
|
+
"rightValue": true,
|
|
104
|
+
"operator": { "type": "boolean", "operation": "equals" }
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "w1-check-client-sha",
|
|
112
|
+
"name": "Check Client SHA",
|
|
113
|
+
"type": "n8n-nodes-base.httpRequest",
|
|
114
|
+
"typeVersion": 4.2,
|
|
115
|
+
"position": [1600, 200],
|
|
116
|
+
"parameters": {
|
|
117
|
+
"method": "GET",
|
|
118
|
+
"url": "=https://api.github.com/repos/your-username/axis-crm/contents/{{ $json.clientReadmePath }}?ref=crm",
|
|
119
|
+
"sendHeaders": true,
|
|
120
|
+
"headerParameters": {
|
|
121
|
+
"parameters": [
|
|
122
|
+
{ "name": "Accept", "value": "application/vnd.github.v3+json" }
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"options": { "timeout": 10000 },
|
|
126
|
+
"authentication": "predefinedCredentialType",
|
|
127
|
+
"nodeCredentialType": "githubApi"
|
|
128
|
+
},
|
|
129
|
+
"credentials": {
|
|
130
|
+
"githubApi": { "id": "YOUR_GITHUB_CREDENTIAL_ID", "name": "GitHub API" }
|
|
131
|
+
},
|
|
132
|
+
"onError": "continueRegularOutput"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "w1-prep-client-body",
|
|
136
|
+
"name": "Prep Client Body",
|
|
137
|
+
"type": "n8n-nodes-base.code",
|
|
138
|
+
"typeVersion": 2,
|
|
139
|
+
"position": [1750, 200],
|
|
140
|
+
"parameters": {
|
|
141
|
+
"jsCode": "const d = $('Build Meeting Markdown').first().json;\nconst checkResult = $input.first().json;\nconst sha = checkResult.sha || null;\n\nconst body = {\n message: sha ? 'fix(crm): update client ' + d.client_slug : 'feat(crm): auto-create client ' + d.client_slug,\n branch: 'crm',\n content: Buffer.from(d.clientReadmeContent).toString('base64')\n};\nif (sha) body.sha = sha;\n\nreturn [{ json: { githubBody: JSON.stringify(body), path: d.clientReadmePath } }];"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": "w1-upsert-client",
|
|
146
|
+
"name": "Upsert Client README",
|
|
147
|
+
"type": "n8n-nodes-base.httpRequest",
|
|
148
|
+
"typeVersion": 4.2,
|
|
149
|
+
"position": [1900, 200],
|
|
150
|
+
"parameters": {
|
|
151
|
+
"method": "PUT",
|
|
152
|
+
"url": "=https://api.github.com/repos/your-username/axis-crm/contents/{{ $json.path }}",
|
|
153
|
+
"sendBody": true,
|
|
154
|
+
"specifyBody": "json",
|
|
155
|
+
"jsonBody": "={{ $json.githubBody }}",
|
|
156
|
+
"sendHeaders": true,
|
|
157
|
+
"headerParameters": {
|
|
158
|
+
"parameters": [
|
|
159
|
+
{ "name": "Accept", "value": "application/vnd.github.v3+json" }
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
"options": { "timeout": 15000 },
|
|
163
|
+
"authentication": "predefinedCredentialType",
|
|
164
|
+
"nodeCredentialType": "githubApi"
|
|
165
|
+
},
|
|
166
|
+
"credentials": {
|
|
167
|
+
"githubApi": { "id": "YOUR_GITHUB_CREDENTIAL_ID", "name": "GitHub API" }
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"id": "w1-check-meeting-sha",
|
|
172
|
+
"name": "Check Meeting SHA",
|
|
173
|
+
"type": "n8n-nodes-base.httpRequest",
|
|
174
|
+
"typeVersion": 4.2,
|
|
175
|
+
"position": [2050, 300],
|
|
176
|
+
"parameters": {
|
|
177
|
+
"method": "GET",
|
|
178
|
+
"url": "=https://api.github.com/repos/your-username/axis-crm/contents/{{ $('Build Meeting Markdown').first().json.meetingPath }}?ref=crm",
|
|
179
|
+
"sendHeaders": true,
|
|
180
|
+
"headerParameters": {
|
|
181
|
+
"parameters": [
|
|
182
|
+
{ "name": "Accept", "value": "application/vnd.github.v3+json" }
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
"options": { "timeout": 10000 },
|
|
186
|
+
"authentication": "predefinedCredentialType",
|
|
187
|
+
"nodeCredentialType": "githubApi"
|
|
188
|
+
},
|
|
189
|
+
"credentials": {
|
|
190
|
+
"githubApi": { "id": "YOUR_GITHUB_CREDENTIAL_ID", "name": "GitHub API" }
|
|
191
|
+
},
|
|
192
|
+
"onError": "continueRegularOutput"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"id": "w1-prep-meeting-body",
|
|
196
|
+
"name": "Prep Meeting Body",
|
|
197
|
+
"type": "n8n-nodes-base.code",
|
|
198
|
+
"typeVersion": 2,
|
|
199
|
+
"position": [2200, 300],
|
|
200
|
+
"parameters": {
|
|
201
|
+
"jsCode": "const d = $('Build Meeting Markdown').first().json;\nconst checkResult = $input.first().json;\nconst sha = checkResult.sha || null;\n\nconst body = {\n message: sha ? 'fix(crm): update meeting ' + d.filename : 'feat(crm): auto-add meeting ' + d.filename,\n branch: 'crm',\n content: Buffer.from(d.meetingMdContent).toString('base64')\n};\nif (sha) body.sha = sha;\n\nreturn [{ json: { githubBody: JSON.stringify(body), path: d.meetingPath } }];"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "w1-upsert-meeting",
|
|
206
|
+
"name": "Upsert Meeting File",
|
|
207
|
+
"type": "n8n-nodes-base.httpRequest",
|
|
208
|
+
"typeVersion": 4.2,
|
|
209
|
+
"position": [2350, 300],
|
|
210
|
+
"parameters": {
|
|
211
|
+
"method": "PUT",
|
|
212
|
+
"url": "=https://api.github.com/repos/your-username/axis-crm/contents/{{ $json.path }}",
|
|
213
|
+
"sendBody": true,
|
|
214
|
+
"specifyBody": "json",
|
|
215
|
+
"jsonBody": "={{ $json.githubBody }}",
|
|
216
|
+
"sendHeaders": true,
|
|
217
|
+
"headerParameters": {
|
|
218
|
+
"parameters": [
|
|
219
|
+
{ "name": "Accept", "value": "application/vnd.github.v3+json" }
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
"options": { "timeout": 15000 },
|
|
223
|
+
"authentication": "predefinedCredentialType",
|
|
224
|
+
"nodeCredentialType": "githubApi"
|
|
225
|
+
},
|
|
226
|
+
"credentials": {
|
|
227
|
+
"githubApi": { "id": "YOUR_GITHUB_CREDENTIAL_ID", "name": "GitHub API" }
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"id": "w1-notify",
|
|
232
|
+
"name": "Notify",
|
|
233
|
+
"type": "n8n-nodes-base.httpRequest",
|
|
234
|
+
"typeVersion": 4.2,
|
|
235
|
+
"position": [2500, 300],
|
|
236
|
+
"parameters": {
|
|
237
|
+
"method": "POST",
|
|
238
|
+
"url": "https://ntfy.sh/your-topic",
|
|
239
|
+
"sendBody": true,
|
|
240
|
+
"specifyBody": "string",
|
|
241
|
+
"body": "={{ $('Build Meeting Markdown').first().json.ntfyBody }}",
|
|
242
|
+
"sendHeaders": true,
|
|
243
|
+
"headerParameters": {
|
|
244
|
+
"parameters": [
|
|
245
|
+
{ "name": "Title", "value": "Axis CRM: Meeting saved" },
|
|
246
|
+
{ "name": "Priority", "value": "3" },
|
|
247
|
+
{ "name": "Tags", "value": "briefcase" }
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
"options": {}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
],
|
|
254
|
+
"connections": {
|
|
255
|
+
"Fireflies Webhook": {
|
|
256
|
+
"main": [[{ "node": "Get Transcript", "type": "main", "index": 0 }]]
|
|
257
|
+
},
|
|
258
|
+
"Get Transcript": {
|
|
259
|
+
"main": [[{ "node": "Extract Meeting Data", "type": "main", "index": 0 }]]
|
|
260
|
+
},
|
|
261
|
+
"Extract Meeting Data": {
|
|
262
|
+
"main": [[{ "node": "Prepare AI Request", "type": "main", "index": 0 }]]
|
|
263
|
+
},
|
|
264
|
+
"Prepare AI Request": {
|
|
265
|
+
"main": [[{ "node": "AI Identify Client", "type": "main", "index": 0 }]]
|
|
266
|
+
},
|
|
267
|
+
"AI Identify Client": {
|
|
268
|
+
"main": [[{ "node": "Build Meeting Markdown", "type": "main", "index": 0 }]]
|
|
269
|
+
},
|
|
270
|
+
"Build Meeting Markdown": {
|
|
271
|
+
"main": [[{ "node": "New Client?", "type": "main", "index": 0 }]]
|
|
272
|
+
},
|
|
273
|
+
"New Client?": {
|
|
274
|
+
"main": [
|
|
275
|
+
[{ "node": "Check Client SHA", "type": "main", "index": 0 }],
|
|
276
|
+
[{ "node": "Check Meeting SHA", "type": "main", "index": 0 }]
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
"Check Client SHA": {
|
|
280
|
+
"main": [[{ "node": "Prep Client Body", "type": "main", "index": 0 }]]
|
|
281
|
+
},
|
|
282
|
+
"Prep Client Body": {
|
|
283
|
+
"main": [[{ "node": "Upsert Client README", "type": "main", "index": 0 }]]
|
|
284
|
+
},
|
|
285
|
+
"Upsert Client README": {
|
|
286
|
+
"main": [[{ "node": "Check Meeting SHA", "type": "main", "index": 0 }]]
|
|
287
|
+
},
|
|
288
|
+
"Check Meeting SHA": {
|
|
289
|
+
"main": [[{ "node": "Prep Meeting Body", "type": "main", "index": 0 }]]
|
|
290
|
+
},
|
|
291
|
+
"Prep Meeting Body": {
|
|
292
|
+
"main": [[{ "node": "Upsert Meeting File", "type": "main", "index": 0 }]]
|
|
293
|
+
},
|
|
294
|
+
"Upsert Meeting File": {
|
|
295
|
+
"main": [[{ "node": "Notify", "type": "main", "index": 0 }]]
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
"settings": {
|
|
299
|
+
"executionOrder": "v1",
|
|
300
|
+
"saveExecutionProgress": true,
|
|
301
|
+
"saveManualExecutions": true,
|
|
302
|
+
"timezone": "Europe/Prague",
|
|
303
|
+
"callerPolicy": "workflowsFromSameOwner",
|
|
304
|
+
"availableInMCP": false
|
|
305
|
+
}
|
|
306
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Acme Consulting s.r.o.'
|
|
3
|
+
created: '2026-01-15'
|
|
4
|
+
tags: [client]
|
|
5
|
+
type: client
|
|
6
|
+
status: 'active'
|
|
7
|
+
priority: 'high'
|
|
8
|
+
city: 'Praha'
|
|
9
|
+
size: '10-50'
|
|
10
|
+
industry: 'consulting'
|
|
11
|
+
source: 'referral'
|
|
12
|
+
email: 'info@acme-consulting.cz'
|
|
13
|
+
phone: '+420 222 333 444'
|
|
14
|
+
ico: '12345678'
|
|
15
|
+
web: 'https://acme-consulting.cz'
|
|
16
|
+
score: 75
|
|
17
|
+
hourly_rate: 120
|
|
18
|
+
manday_rate: 960
|
|
19
|
+
currency: 'USD'
|
|
20
|
+
converted_from_lead: 'leads/acme-consulting-sro.md (see git history)'
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
Consulting firm focused on digital transformation and process optimization for mid-sized companies. Key contact: Jana Novakova (CEO). Partnership since January 2026.
|
|
26
|
+
|
|
27
|
+
## Contacts
|
|
28
|
+
|
|
29
|
+
- [[contacts/jana-novakova|Jana Novakova]] — CEO, primary contact
|
|
30
|
+
- [[contacts/tomas-dvorak|Tomas Dvorak]] — CTO, technical contact
|
|
31
|
+
|
|
32
|
+
## Active Projects
|
|
33
|
+
|
|
34
|
+
- [[projects/web-redesign/README|Web Redesign]] — full redesign of company website (deadline: May 2026)
|
|
35
|
+
|
|
36
|
+
## Recent Meetings
|
|
37
|
+
|
|
38
|
+
- [[meetings/2026-03-15-progress-review|Progress Review]] — 2026-03-15
|
|
39
|
+
- [[meetings/2026-02-10-kickoff|Kickoff]] — 2026-02-10
|
|
40
|
+
|
|
41
|
+
## Key Decisions
|
|
42
|
+
|
|
43
|
+
- 2026-03-01: Price agreed at 85,000 CZK, payment in 3 milestones
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Price agreed — Web Redesign'
|
|
3
|
+
date: '2026-03-01'
|
|
4
|
+
tags: [communication]
|
|
5
|
+
type: communication
|
|
6
|
+
channel: 'email'
|
|
7
|
+
participants: ['Jana Novakova', 'Patrik']
|
|
8
|
+
decision: 'Price 85,000 CZK, payment in 3 milestones'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
After sending the price quote (25.02.), the client responded with a counter-offer. We agreed on 85,000 CZK.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
- Total price: 85,000 CZK excluding VAT
|
|
18
|
+
- Payment in 3 milestones: 30% after design approval, 40% after development, 30% after launch
|
|
19
|
+
- Invoicing to Acme Consulting s.r.o., ICO 12345678
|
|
20
|
+
|
|
21
|
+
## Action Items
|
|
22
|
+
|
|
23
|
+
- [ ] Prepare contract
|
|
24
|
+
- [x] Send confirmation email
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Jana Novakova'
|
|
3
|
+
created: '2026-01-15'
|
|
4
|
+
tags: [contact]
|
|
5
|
+
type: contact
|
|
6
|
+
role: 'CEO'
|
|
7
|
+
email: 'jana@acme-consulting.cz'
|
|
8
|
+
phone: '+420 777 888 999'
|
|
9
|
+
linkedin: 'https://linkedin.com/in/jana-novakova-demo'
|
|
10
|
+
last_contact: '2026-03-15'
|
|
11
|
+
notes: 'Primary contact. Makes budget decisions.'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Notes
|
|
15
|
+
|
|
16
|
+
Prefers email communication. Available in the morning hours.
|
|
17
|
+
Interested in AI automation of internal processes.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Tomas Dvorak'
|
|
3
|
+
created: '2026-01-20'
|
|
4
|
+
tags: [contact]
|
|
5
|
+
type: contact
|
|
6
|
+
role: 'CTO'
|
|
7
|
+
email: 'tomas@acme-consulting.cz'
|
|
8
|
+
phone: '+420 666 555 444'
|
|
9
|
+
linkedin: 'https://linkedin.com/in/tomas-dvorak-demo'
|
|
10
|
+
last_contact: '2026-03-15'
|
|
11
|
+
notes: 'Technical contact. Makes tech stack decisions.'
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Notes
|
|
15
|
+
|
|
16
|
+
Experienced with React, Node.js, PostgreSQL. Prefers Slack communication.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Kickoff — Web Redesign'
|
|
3
|
+
date: '2026-02-10'
|
|
4
|
+
tags: [meeting]
|
|
5
|
+
type: meeting
|
|
6
|
+
attendees: ['Jana Novakova', 'Tomas Dvorak', 'Patrik']
|
|
7
|
+
duration: '45 min'
|
|
8
|
+
next_steps: ['Prepare wireframe draft', 'Send price quote']
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Agenda
|
|
12
|
+
|
|
13
|
+
1. Project introduction
|
|
14
|
+
2. Requirements discussion
|
|
15
|
+
3. Timeline agreement
|
|
16
|
+
|
|
17
|
+
## Notes
|
|
18
|
+
|
|
19
|
+
Client wants a modern, minimalist design. Main priority is loading speed and SEO. Current website is on WordPress, they want to migrate to Next.js. Budget up to 100,000 CZK, ideally around 80,000.
|
|
20
|
+
|
|
21
|
+
## Action Items
|
|
22
|
+
|
|
23
|
+
- [ ] Prepare homepage wireframe (by 2026-02-17)
|
|
24
|
+
- [ ] Send price quote (by 2026-02-14)
|
|
25
|
+
- [ ] Share Google Analytics access
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Progress Review — Web Redesign'
|
|
3
|
+
date: '2026-03-15'
|
|
4
|
+
tags: [meeting]
|
|
5
|
+
type: meeting
|
|
6
|
+
attendees: ['Jana Novakova', 'Patrik']
|
|
7
|
+
duration: '30 min'
|
|
8
|
+
next_steps: ['Finalize homepage design', 'Prepare subpages']
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Agenda
|
|
12
|
+
|
|
13
|
+
1. Review of ongoing design
|
|
14
|
+
2. Wireframe feedback
|
|
15
|
+
3. Next steps
|
|
16
|
+
|
|
17
|
+
## Notes
|
|
18
|
+
|
|
19
|
+
Client is happy with the overall direction. Wants more space for case studies on the homepage. Logo needs a minor tweak — darker variant. Mobile version is a priority.
|
|
20
|
+
|
|
21
|
+
## Action Items
|
|
22
|
+
|
|
23
|
+
- [ ] Update homepage layout — add case studies section
|
|
24
|
+
- [ ] Prepare darker logo variant
|
|
25
|
+
- [ ] Mobile-first redesign of subpages
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Web Redesign'
|
|
3
|
+
created: '2026-02-10'
|
|
4
|
+
tags: [project]
|
|
5
|
+
type: project
|
|
6
|
+
status: 'active'
|
|
7
|
+
start: '2026-02-15'
|
|
8
|
+
deadline: '2026-05-01'
|
|
9
|
+
value: '85000 CZK'
|
|
10
|
+
description: 'Full redesign of company website including migration from WordPress to Next.js'
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
Full redesign of acme-consulting.cz. Migration from WordPress to Next.js with focus on speed, SEO, and modern design.
|
|
16
|
+
|
|
17
|
+
## Scope
|
|
18
|
+
|
|
19
|
+
**IN scope:**
|
|
20
|
+
- Homepage redesign
|
|
21
|
+
- 5 subpages (About, Services, References, Blog, Contact)
|
|
22
|
+
- SEO optimization
|
|
23
|
+
- Responsive design
|
|
24
|
+
- CMS (Sanity/Contentful)
|
|
25
|
+
|
|
26
|
+
**OUT of scope:**
|
|
27
|
+
- E-shop
|
|
28
|
+
- Multi-language version
|
|
29
|
+
- Custom application
|
|
30
|
+
|
|
31
|
+
## Progress
|
|
32
|
+
|
|
33
|
+
- 2026-02-15: Wireframes approved
|
|
34
|
+
- 2026-03-01: Price agreed (85,000 CZK)
|
|
35
|
+
- 2026-03-15: Progress review — homepage design in progress
|
|
36
|
+
|
|
37
|
+
## Timeline
|
|
38
|
+
|
|
39
|
+
| Milestone | Date | Status |
|
|
40
|
+
| ---------------- | ---------- | ----------- |
|
|
41
|
+
| Kick-off | 2026-02-10 | done |
|
|
42
|
+
| Wireframes | 2026-02-20 | done |
|
|
43
|
+
| Design v1 | 2026-03-15 | in-progress |
|
|
44
|
+
| Development | 2026-04-01 | |
|
|
45
|
+
| Final delivery | 2026-05-01 | |
|
|
46
|
+
|
|
47
|
+
## Deliverables
|
|
48
|
+
|
|
49
|
+
Outputs are in the `deliverables/` folder.
|
|
50
|
+
|
|
51
|
+
## Notes
|
|
52
|
+
|
|
53
|
+
Ongoing notes are in the `notes/` folder.
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Zadani — Web Redesign'
|
|
3
|
+
created: '2026-02-10'
|
|
4
|
+
type: brief
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Brief
|
|
8
|
+
|
|
9
|
+
## From whom
|
|
10
|
+
|
|
11
|
+
Jana Novakova (CEO, Acme Consulting s.r.o.)
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
Full redesign of the company website. The current WordPress site is slow, not responsive, and visually outdated. She wants a modern, fast website that represents the company properly.
|
|
16
|
+
|
|
17
|
+
## Why
|
|
18
|
+
|
|
19
|
+
The current website doesn't generate leads. Bounce rate over 70%, average time on page under 30s. The company is growing and the website doesn't match the quality of their services.
|
|
20
|
+
|
|
21
|
+
## Constraints
|
|
22
|
+
|
|
23
|
+
- Budget: max 100,000 CZK (target 80-85k)
|
|
24
|
+
- Deadline: May 2026
|
|
25
|
+
- Must: responsive, fast (Core Web Vitals), SEO friendly
|
|
26
|
+
- Preferred stack: Next.js + headless CMS
|
|
27
|
+
|
|
28
|
+
## Success criteria
|
|
29
|
+
|
|
30
|
+
- [ ] All Core Web Vitals green
|
|
31
|
+
- [ ] Bounce rate under 50%
|
|
32
|
+
- [ ] At least 3 lead form submissions per month
|
|
33
|
+
- [ ] Client approves final design
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Client Overview
|
|
3
|
+
type: dashboard
|
|
4
|
+
tags: [dashboard, crm]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Clients
|
|
8
|
+
|
|
9
|
+
## Active
|
|
10
|
+
|
|
11
|
+
```dataview
|
|
12
|
+
TABLE status, priority, industry
|
|
13
|
+
FROM "clients"
|
|
14
|
+
WHERE type = "client" AND (status = "active" OR status = "active-partnership" OR status = "in-progress")
|
|
15
|
+
SORT priority DESC
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## All Clients
|
|
19
|
+
|
|
20
|
+
```dataview
|
|
21
|
+
TABLE status, priority, city, industry
|
|
22
|
+
FROM "clients"
|
|
23
|
+
WHERE type = "client"
|
|
24
|
+
SORT status ASC
|
|
25
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hot Leads
|
|
3
|
+
type: dashboard
|
|
4
|
+
tags: [dashboard, crm]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Hot Leads (score > 60)
|
|
8
|
+
|
|
9
|
+
```dataview
|
|
10
|
+
TABLE status, score, email, industry, city, campaign
|
|
11
|
+
FROM "leads"
|
|
12
|
+
WHERE type = "lead" AND score > 60
|
|
13
|
+
SORT score DESC
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Highest priority (score > 80)
|
|
17
|
+
|
|
18
|
+
```dataview
|
|
19
|
+
TABLE status, score, email, first_contact
|
|
20
|
+
FROM "leads"
|
|
21
|
+
WHERE type = "lead" AND score > 80
|
|
22
|
+
SORT score DESC
|
|
23
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Lead Pipeline
|
|
3
|
+
type: dashboard
|
|
4
|
+
tags: [dashboard, crm]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Lead Pipeline
|
|
8
|
+
|
|
9
|
+
## New (awaiting enrichment)
|
|
10
|
+
|
|
11
|
+
```dataview
|
|
12
|
+
TABLE source, city, industry
|
|
13
|
+
FROM "leads"
|
|
14
|
+
WHERE type = "lead" AND status = "new"
|
|
15
|
+
SORT created DESC
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Enriched (awaiting qualification)
|
|
19
|
+
|
|
20
|
+
```dataview
|
|
21
|
+
TABLE score, industry, city, email
|
|
22
|
+
FROM "leads"
|
|
23
|
+
WHERE type = "lead" AND status = "enriched"
|
|
24
|
+
SORT score DESC
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Qualified (ready for outreach)
|
|
28
|
+
|
|
29
|
+
```dataview
|
|
30
|
+
TABLE score, email, industry, city
|
|
31
|
+
FROM "leads"
|
|
32
|
+
WHERE type = "lead" AND status = "qualified"
|
|
33
|
+
SORT score DESC
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Contacted (awaiting response)
|
|
37
|
+
|
|
38
|
+
```dataview
|
|
39
|
+
TABLE campaign, first_contact, email
|
|
40
|
+
FROM "leads"
|
|
41
|
+
WHERE type = "lead" AND status = "contacted"
|
|
42
|
+
SORT first_contact DESC
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Opportunities (meeting scheduled)
|
|
46
|
+
|
|
47
|
+
```dataview
|
|
48
|
+
TABLE priority, score, email
|
|
49
|
+
FROM "leads"
|
|
50
|
+
WHERE type = "lead" AND status = "opportunity"
|
|
51
|
+
SORT score DESC
|
|
52
|
+
```
|