@awesomate/hosting-mcp 0.12.0 → 0.13.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.
Files changed (58) hide show
  1. package/dist/index.js +204 -8
  2. package/package.json +2 -2
  3. package/skill/awesomate-app-builder/SKILL.md +5 -1
  4. package/skill/awesomate-credentials/SKILL.md +1 -1
  5. package/skill/awesomate-hosting/SKILL.md +50 -159
  6. package/skill/awesomate-hosting/references/connect-troubleshooting.md +77 -0
  7. package/skill/awesomate-hosting/references/multi-account.md +33 -0
  8. package/skill/awesomate-hosting/references/rest-fallback.md +30 -0
  9. package/skill/awesomate-hosting/scripts/bootstrap.mjs +27 -7
  10. package/skill/awesomate-n8n/SKILL.md +153 -147
  11. package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +31 -0
  12. package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +1 -0
  13. package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +30 -0
  14. package/skill/awesomate-n8n/evals/build-form-email/prompt.md +1 -0
  15. package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +32 -0
  16. package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +2 -0
  17. package/skill/awesomate-n8n/evals/diagnose-failure/graders/grader.md +27 -0
  18. package/skill/awesomate-n8n/evals/diagnose-failure/prompt.md +2 -0
  19. package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +27 -0
  20. package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +2 -0
  21. package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +35 -0
  22. package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +2 -0
  23. package/skill/awesomate-n8n/evals/possibilities-grounded/graders/grader.md +28 -0
  24. package/skill/awesomate-n8n/evals/possibilities-grounded/prompt.md +1 -0
  25. package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +27 -0
  26. package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +2 -0
  27. package/skill/awesomate-n8n/evals/vars-not-env/graders/grader.md +26 -0
  28. package/skill/awesomate-n8n/evals/vars-not-env/prompt.md +2 -0
  29. package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +26 -0
  30. package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +3 -0
  31. package/skill/awesomate-n8n/references/ai-agents.md +135 -0
  32. package/skill/awesomate-n8n/references/datatables.md +105 -0
  33. package/skill/awesomate-n8n/references/{node-recipes.md → platform-notes.md} +56 -7
  34. package/skill/awesomate-n8n/references/possibilities.md +83 -0
  35. package/skill/awesomate-n8n/references/testing-policy.md +115 -0
  36. package/skill/awesomate-n8n/references/troubleshooting.md +69 -0
  37. package/skill/awesomate-n8n/references/upgrade-loop.md +98 -0
  38. package/skill/awesomate-n8n/references/vendor/MANIFEST.json +26 -0
  39. package/skill/awesomate-n8n/references/vendor/code-node/BUILTIN_FUNCTIONS.md +779 -0
  40. package/skill/awesomate-n8n/references/vendor/code-node/COMMON_PATTERNS.md +1123 -0
  41. package/skill/awesomate-n8n/references/vendor/code-node/DATA_ACCESS.md +797 -0
  42. package/skill/awesomate-n8n/references/vendor/code-node/ERROR_PATTERNS.md +776 -0
  43. package/skill/awesomate-n8n/references/vendor/code-node/SKILL.md +703 -0
  44. package/skill/awesomate-n8n/references/vendor/expressions/COMMON_MISTAKES.md +406 -0
  45. package/skill/awesomate-n8n/references/vendor/expressions/EXAMPLES.md +496 -0
  46. package/skill/awesomate-n8n/references/vendor/expressions/SKILL.md +525 -0
  47. package/skill/awesomate-n8n/references/vendor/node-configuration/DEPENDENCIES.md +743 -0
  48. package/skill/awesomate-n8n/references/vendor/node-configuration/OPERATION_PATTERNS.md +926 -0
  49. package/skill/awesomate-n8n/references/vendor/node-configuration/SKILL.md +583 -0
  50. package/skill/awesomate-n8n/references/vendor/validation/ERROR_CATALOG.md +781 -0
  51. package/skill/awesomate-n8n/references/vendor/validation/FALSE_POSITIVES.md +695 -0
  52. package/skill/awesomate-n8n/references/vendor/validation/SKILL.md +414 -0
  53. package/skill/awesomate-n8n/references/vendor/workflow-patterns/SKILL.md +413 -0
  54. package/skill/awesomate-n8n/references/vendor/workflow-patterns/ai_agent_workflow.md +797 -0
  55. package/skill/awesomate-n8n/references/vendor/workflow-patterns/database_operations.md +798 -0
  56. package/skill/awesomate-n8n/references/vendor/workflow-patterns/http_api_integration.md +747 -0
  57. package/skill/awesomate-n8n/references/vendor/workflow-patterns/scheduled_tasks.md +786 -0
  58. package/skill/awesomate-n8n/references/vendor/workflow-patterns/webhook_processing.md +558 -0
@@ -0,0 +1,926 @@
1
+ <!--
2
+ VENDORED from n8n-builder@d293559 (n8n-node-configuration/OPERATION_PATTERNS.md) — DO NOT EDIT HERE.
3
+ Edit the source in ~/Projects/n8n-builder, then re-run:
4
+ node mcp/scripts/sync-n8n-references.mjs --write
5
+
6
+ Awesomate platform overrides — where this file conflicts with
7
+ ../platform-notes.md, platform-notes wins:
8
+ - $env is BLOCKED fleet-wide → use {{ $vars.key || 'fallback' }}
9
+ - Task runners are ON → no $helpers in Code nodes; use HTTP Request nodes
10
+ - Webhook payloads live at $json.body
11
+ - saveExecutionProgress must stay false
12
+ -->
13
+
14
+ # Operation Patterns Guide
15
+
16
+ Common node configuration patterns organized by node type and operation.
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ **Purpose**: Quick reference for common node configurations
23
+
24
+ **Coverage**: Top 20 most-used nodes from 525 available
25
+
26
+ **Pattern format**:
27
+ - Minimal valid configuration
28
+ - Common options
29
+ - Real-world examples
30
+ - Gotchas and tips
31
+
32
+ ---
33
+
34
+ ## HTTP & API Nodes
35
+
36
+ ### HTTP Request (nodes-base.httpRequest)
37
+
38
+ Most versatile node for HTTP operations
39
+
40
+ #### GET Request
41
+
42
+ **Minimal**:
43
+ ```javascript
44
+ {
45
+ "method": "GET",
46
+ "url": "https://api.example.com/users",
47
+ "authentication": "none"
48
+ }
49
+ ```
50
+
51
+ **With query parameters**:
52
+ ```javascript
53
+ {
54
+ "method": "GET",
55
+ "url": "https://api.example.com/users",
56
+ "authentication": "none",
57
+ "sendQuery": true,
58
+ "queryParameters": {
59
+ "parameters": [
60
+ {
61
+ "name": "limit",
62
+ "value": "100"
63
+ },
64
+ {
65
+ "name": "offset",
66
+ "value": "={{$json.offset}}"
67
+ }
68
+ ]
69
+ }
70
+ }
71
+ ```
72
+
73
+ **With authentication**:
74
+ ```javascript
75
+ {
76
+ "method": "GET",
77
+ "url": "https://api.example.com/users",
78
+ "authentication": "predefinedCredentialType",
79
+ "nodeCredentialType": "httpHeaderAuth"
80
+ }
81
+ ```
82
+
83
+ #### POST with JSON
84
+
85
+ **Minimal**:
86
+ ```javascript
87
+ {
88
+ "method": "POST",
89
+ "url": "https://api.example.com/users",
90
+ "authentication": "none",
91
+ "sendBody": true,
92
+ "body": {
93
+ "contentType": "json",
94
+ "content": {
95
+ "name": "John Doe",
96
+ "email": "john@example.com"
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ **With expressions**:
103
+ ```javascript
104
+ {
105
+ "method": "POST",
106
+ "url": "https://api.example.com/users",
107
+ "authentication": "none",
108
+ "sendBody": true,
109
+ "body": {
110
+ "contentType": "json",
111
+ "content": {
112
+ "name": "={{$json.name}}",
113
+ "email": "={{$json.email}}",
114
+ "metadata": {
115
+ "source": "n8n",
116
+ "timestamp": "={{$now.toISO()}}"
117
+ }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ **Gotcha**: Remember `sendBody: true` for POST/PUT/PATCH!
124
+
125
+ #### PUT/PATCH Request
126
+
127
+ **Pattern**: Same as POST, but method changes
128
+ ```javascript
129
+ {
130
+ "method": "PUT", // or "PATCH"
131
+ "url": "https://api.example.com/users/123",
132
+ "authentication": "none",
133
+ "sendBody": true,
134
+ "body": {
135
+ "contentType": "json",
136
+ "content": {
137
+ "name": "Updated Name"
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ #### DELETE Request
144
+
145
+ **Minimal** (no body):
146
+ ```javascript
147
+ {
148
+ "method": "DELETE",
149
+ "url": "https://api.example.com/users/123",
150
+ "authentication": "none"
151
+ }
152
+ ```
153
+
154
+ **With body** (some APIs allow):
155
+ ```javascript
156
+ {
157
+ "method": "DELETE",
158
+ "url": "https://api.example.com/users",
159
+ "authentication": "none",
160
+ "sendBody": true,
161
+ "body": {
162
+ "contentType": "json",
163
+ "content": {
164
+ "ids": ["123", "456"]
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ ### Webhook (nodes-base.webhook)
173
+
174
+ Most common trigger - 813 searches!
175
+
176
+ #### Basic Webhook
177
+
178
+ **Minimal**:
179
+ ```javascript
180
+ {
181
+ "path": "my-webhook",
182
+ "httpMethod": "POST",
183
+ "responseMode": "onReceived"
184
+ }
185
+ ```
186
+
187
+ **Gotcha**: Webhook data is under `$json.body`, not `$json`!
188
+
189
+ ```javascript
190
+ // ❌ Wrong
191
+ {
192
+ "text": "={{$json.email}}"
193
+ }
194
+
195
+ // ✅ Correct
196
+ {
197
+ "text": "={{$json.body.email}}"
198
+ }
199
+ ```
200
+
201
+ #### Webhook with Authentication
202
+
203
+ **Header auth**:
204
+ ```javascript
205
+ {
206
+ "path": "secure-webhook",
207
+ "httpMethod": "POST",
208
+ "responseMode": "onReceived",
209
+ "authentication": "headerAuth",
210
+ "options": {
211
+ "responseCode": 200,
212
+ "responseData": "{\n \"success\": true\n}"
213
+ }
214
+ }
215
+ ```
216
+
217
+ #### Webhook Returning Data
218
+
219
+ **Custom response**:
220
+ ```javascript
221
+ {
222
+ "path": "my-webhook",
223
+ "httpMethod": "POST",
224
+ "responseMode": "lastNode", // Return data from last node
225
+ "options": {
226
+ "responseCode": 201,
227
+ "responseHeaders": {
228
+ "entries": [
229
+ {
230
+ "name": "Content-Type",
231
+ "value": "application/json"
232
+ }
233
+ ]
234
+ }
235
+ }
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Communication Nodes
242
+
243
+ ### Slack (nodes-base.slack)
244
+
245
+ Popular choice for AI agent workflows
246
+
247
+ #### Post Message
248
+
249
+ **Minimal**:
250
+ ```javascript
251
+ {
252
+ "resource": "message",
253
+ "operation": "post",
254
+ "channel": "#general",
255
+ "text": "Hello from n8n!"
256
+ }
257
+ ```
258
+
259
+ **With dynamic content**:
260
+ ```javascript
261
+ {
262
+ "resource": "message",
263
+ "operation": "post",
264
+ "channel": "={{$json.channel}}",
265
+ "text": "New user: {{$json.name}} ({{$json.email}})"
266
+ }
267
+ ```
268
+
269
+ **With attachments**:
270
+ ```javascript
271
+ {
272
+ "resource": "message",
273
+ "operation": "post",
274
+ "channel": "#alerts",
275
+ "text": "Error Alert",
276
+ "attachments": [
277
+ {
278
+ "color": "#ff0000",
279
+ "fields": [
280
+ {
281
+ "title": "Error Type",
282
+ "value": "={{$json.errorType}}"
283
+ },
284
+ {
285
+ "title": "Timestamp",
286
+ "value": "={{$now.toLocaleString()}}"
287
+ }
288
+ ]
289
+ }
290
+ ]
291
+ }
292
+ ```
293
+
294
+ **Gotcha**: Channel must start with `#` for public channels or be a channel ID!
295
+
296
+ #### Update Message
297
+
298
+ **Minimal**:
299
+ ```javascript
300
+ {
301
+ "resource": "message",
302
+ "operation": "update",
303
+ "messageId": "1234567890.123456", // From previous message post
304
+ "text": "Updated message content"
305
+ }
306
+ ```
307
+
308
+ **Note**: `messageId` required, `channel` optional (can be inferred)
309
+
310
+ #### Create Channel
311
+
312
+ **Minimal**:
313
+ ```javascript
314
+ {
315
+ "resource": "channel",
316
+ "operation": "create",
317
+ "name": "new-project-channel", // Lowercase, no spaces
318
+ "isPrivate": false
319
+ }
320
+ ```
321
+
322
+ **Gotcha**: Channel name must be lowercase, no spaces, 1-80 chars!
323
+
324
+ ---
325
+
326
+ ### Gmail (nodes-base.gmail)
327
+
328
+ Popular for email automation
329
+
330
+ #### Send Email
331
+
332
+ **Minimal**:
333
+ ```javascript
334
+ {
335
+ "resource": "message",
336
+ "operation": "send",
337
+ "to": "user@example.com",
338
+ "subject": "Hello from n8n",
339
+ "message": "This is the email body"
340
+ }
341
+ ```
342
+
343
+ **With dynamic content**:
344
+ ```javascript
345
+ {
346
+ "resource": "message",
347
+ "operation": "send",
348
+ "to": "={{$json.email}}",
349
+ "subject": "Order Confirmation #{{$json.orderId}}",
350
+ "message": "Dear {{$json.name}},\n\nYour order has been confirmed.\n\nThank you!",
351
+ "options": {
352
+ "ccList": "admin@example.com",
353
+ "replyTo": "support@example.com"
354
+ }
355
+ }
356
+ ```
357
+
358
+ #### Get Email
359
+
360
+ **Minimal**:
361
+ ```javascript
362
+ {
363
+ "resource": "message",
364
+ "operation": "getAll",
365
+ "returnAll": false,
366
+ "limit": 10
367
+ }
368
+ ```
369
+
370
+ **With filters**:
371
+ ```javascript
372
+ {
373
+ "resource": "message",
374
+ "operation": "getAll",
375
+ "returnAll": false,
376
+ "limit": 50,
377
+ "filters": {
378
+ "q": "is:unread from:important@example.com",
379
+ "labelIds": ["INBOX"]
380
+ }
381
+ }
382
+ ```
383
+
384
+ ---
385
+
386
+ ## Database Nodes
387
+
388
+ ### Postgres (nodes-base.postgres)
389
+
390
+ Database operations - 456 templates
391
+
392
+ #### Execute Query
393
+
394
+ **Minimal** (SELECT):
395
+ ```javascript
396
+ {
397
+ "operation": "executeQuery",
398
+ "query": "SELECT * FROM users WHERE active = true LIMIT 100"
399
+ }
400
+ ```
401
+
402
+ **With parameters** (SQL injection prevention):
403
+ ```javascript
404
+ {
405
+ "operation": "executeQuery",
406
+ "query": "SELECT * FROM users WHERE email = $1 AND active = $2",
407
+ "additionalFields": {
408
+ "mode": "list",
409
+ "queryParameters": "user@example.com,true"
410
+ }
411
+ }
412
+ ```
413
+
414
+ **Gotcha**: ALWAYS use parameterized queries for user input!
415
+
416
+ ```javascript
417
+ // ❌ BAD - SQL injection risk!
418
+ {
419
+ "query": "SELECT * FROM users WHERE email = '{{$json.email}}'"
420
+ }
421
+
422
+ // ✅ GOOD - Parameterized
423
+ {
424
+ "query": "SELECT * FROM users WHERE email = $1",
425
+ "additionalFields": {
426
+ "mode": "list",
427
+ "queryParameters": "={{$json.email}}"
428
+ }
429
+ }
430
+ ```
431
+
432
+ #### Insert
433
+
434
+ **Minimal**:
435
+ ```javascript
436
+ {
437
+ "operation": "insert",
438
+ "table": "users",
439
+ "columns": "name,email,created_at",
440
+ "additionalFields": {
441
+ "mode": "list",
442
+ "queryParameters": "John Doe,john@example.com,NOW()"
443
+ }
444
+ }
445
+ ```
446
+
447
+ **With expressions**:
448
+ ```javascript
449
+ {
450
+ "operation": "insert",
451
+ "table": "users",
452
+ "columns": "name,email,metadata",
453
+ "additionalFields": {
454
+ "mode": "list",
455
+ "queryParameters": "={{$json.name}},={{$json.email}},{{JSON.stringify($json)}}"
456
+ }
457
+ }
458
+ ```
459
+
460
+ #### Update
461
+
462
+ **Minimal**:
463
+ ```javascript
464
+ {
465
+ "operation": "update",
466
+ "table": "users",
467
+ "updateKey": "id",
468
+ "columns": "name,email",
469
+ "additionalFields": {
470
+ "mode": "list",
471
+ "queryParameters": "={{$json.id}},Updated Name,newemail@example.com"
472
+ }
473
+ }
474
+ ```
475
+
476
+ ---
477
+
478
+ ## Data Transformation Nodes
479
+
480
+ ### Set (nodes-base.set)
481
+
482
+ Most used transformation - 68% of workflows!
483
+
484
+ #### Set Fixed Values
485
+
486
+ **Minimal**:
487
+ ```javascript
488
+ {
489
+ "mode": "manual",
490
+ "duplicateItem": false,
491
+ "assignments": {
492
+ "assignments": [
493
+ {
494
+ "name": "status",
495
+ "value": "active",
496
+ "type": "string"
497
+ },
498
+ {
499
+ "name": "count",
500
+ "value": 100,
501
+ "type": "number"
502
+ }
503
+ ]
504
+ }
505
+ }
506
+ ```
507
+
508
+ #### Set from Input Data
509
+
510
+ **Mapping data**:
511
+ ```javascript
512
+ {
513
+ "mode": "manual",
514
+ "duplicateItem": false,
515
+ "assignments": {
516
+ "assignments": [
517
+ {
518
+ "name": "fullName",
519
+ "value": "={{$json.firstName}} {{$json.lastName}}",
520
+ "type": "string"
521
+ },
522
+ {
523
+ "name": "email",
524
+ "value": "={{$json.email.toLowerCase()}}",
525
+ "type": "string"
526
+ },
527
+ {
528
+ "name": "timestamp",
529
+ "value": "={{$now.toISO()}}",
530
+ "type": "string"
531
+ }
532
+ ]
533
+ }
534
+ }
535
+ ```
536
+
537
+ **Gotcha**: Use correct `type` for each field!
538
+
539
+ ```javascript
540
+ // ❌ Wrong type
541
+ {
542
+ "name": "age",
543
+ "value": "25", // String
544
+ "type": "string" // Will be string "25"
545
+ }
546
+
547
+ // ✅ Correct type
548
+ {
549
+ "name": "age",
550
+ "value": 25, // Number
551
+ "type": "number" // Will be number 25
552
+ }
553
+ ```
554
+
555
+ ---
556
+
557
+ ### Code (nodes-base.code)
558
+
559
+ JavaScript execution - 42% of workflows
560
+
561
+ #### Simple Transformation
562
+
563
+ **Minimal**:
564
+ ```javascript
565
+ {
566
+ "mode": "runOnceForAllItems",
567
+ "jsCode": "return $input.all().map(item => ({\n json: {\n name: item.json.name.toUpperCase(),\n email: item.json.email\n }\n}));"
568
+ }
569
+ ```
570
+
571
+ **Per-item processing**:
572
+ ```javascript
573
+ {
574
+ "mode": "runOnceForEachItem",
575
+ "jsCode": "// Process each item\nconst data = $input.item.json;\n\nreturn {\n json: {\n fullName: `${data.firstName} ${data.lastName}`,\n email: data.email.toLowerCase(),\n timestamp: new Date().toISOString()\n }\n};"
576
+ }
577
+ ```
578
+
579
+ **Gotcha**: In Code nodes, use `$input.item.json` or `$input.all()`, NOT `{{...}}`!
580
+
581
+ ```javascript
582
+ // ❌ Wrong - expressions don't work in Code nodes
583
+ {
584
+ "jsCode": "const name = '={{$json.name}}';"
585
+ }
586
+
587
+ // ✅ Correct - direct access
588
+ {
589
+ "jsCode": "const name = $input.item.json.name;"
590
+ }
591
+ ```
592
+
593
+ ---
594
+
595
+ ## Conditional Nodes
596
+
597
+ ### IF (nodes-base.if)
598
+
599
+ Conditional logic - 38% of workflows
600
+
601
+ #### String Comparison
602
+
603
+ **Equals** (binary):
604
+ ```javascript
605
+ {
606
+ "conditions": {
607
+ "string": [
608
+ {
609
+ "value1": "={{$json.status}}",
610
+ "operation": "equals",
611
+ "value2": "active"
612
+ }
613
+ ]
614
+ }
615
+ }
616
+ ```
617
+
618
+ **Contains** (binary):
619
+ ```javascript
620
+ {
621
+ "conditions": {
622
+ "string": [
623
+ {
624
+ "value1": "={{$json.email}}",
625
+ "operation": "contains",
626
+ "value2": "@example.com"
627
+ }
628
+ ]
629
+ }
630
+ }
631
+ ```
632
+
633
+ **isEmpty** (unary):
634
+ ```javascript
635
+ {
636
+ "conditions": {
637
+ "string": [
638
+ {
639
+ "value1": "={{$json.email}}",
640
+ "operation": "isEmpty"
641
+ // No value2 - unary operator
642
+ // singleValue: true added by auto-sanitization
643
+ }
644
+ ]
645
+ }
646
+ }
647
+ ```
648
+
649
+ **Gotcha**: Unary operators (isEmpty, isNotEmpty) don't need value2!
650
+
651
+ #### Number Comparison
652
+
653
+ **Greater than**:
654
+ ```javascript
655
+ {
656
+ "conditions": {
657
+ "number": [
658
+ {
659
+ "value1": "={{$json.age}}",
660
+ "operation": "larger",
661
+ "value2": 18
662
+ }
663
+ ]
664
+ }
665
+ }
666
+ ```
667
+
668
+ #### Boolean Comparison
669
+
670
+ **Is true**:
671
+ ```javascript
672
+ {
673
+ "conditions": {
674
+ "boolean": [
675
+ {
676
+ "value1": "={{$json.isActive}}",
677
+ "operation": "true"
678
+ // Unary - no value2
679
+ }
680
+ ]
681
+ }
682
+ }
683
+ ```
684
+
685
+ #### Multiple Conditions (AND)
686
+
687
+ **All must match**:
688
+ ```javascript
689
+ {
690
+ "conditions": {
691
+ "string": [
692
+ {
693
+ "value1": "={{$json.status}}",
694
+ "operation": "equals",
695
+ "value2": "active"
696
+ }
697
+ ],
698
+ "number": [
699
+ {
700
+ "value1": "={{$json.age}}",
701
+ "operation": "larger",
702
+ "value2": 18
703
+ }
704
+ ]
705
+ },
706
+ "combineOperation": "all" // AND logic
707
+ }
708
+ ```
709
+
710
+ #### Multiple Conditions (OR)
711
+
712
+ **Any can match**:
713
+ ```javascript
714
+ {
715
+ "conditions": {
716
+ "string": [
717
+ {
718
+ "value1": "={{$json.status}}",
719
+ "operation": "equals",
720
+ "value2": "active"
721
+ },
722
+ {
723
+ "value1": "={{$json.status}}",
724
+ "operation": "equals",
725
+ "value2": "pending"
726
+ }
727
+ ]
728
+ },
729
+ "combineOperation": "any" // OR logic
730
+ }
731
+ ```
732
+
733
+ ---
734
+
735
+ ### Switch (nodes-base.switch)
736
+
737
+ Multi-way routing - 18% of workflows
738
+
739
+ #### Basic Switch
740
+
741
+ **Minimal**:
742
+ ```javascript
743
+ {
744
+ "mode": "rules",
745
+ "rules": {
746
+ "rules": [
747
+ {
748
+ "conditions": {
749
+ "string": [
750
+ {
751
+ "value1": "={{$json.status}}",
752
+ "operation": "equals",
753
+ "value2": "active"
754
+ }
755
+ ]
756
+ }
757
+ },
758
+ {
759
+ "conditions": {
760
+ "string": [
761
+ {
762
+ "value1": "={{$json.status}}",
763
+ "operation": "equals",
764
+ "value2": "pending"
765
+ }
766
+ ]
767
+ }
768
+ }
769
+ ]
770
+ },
771
+ "fallbackOutput": "extra" // Catch-all for non-matching
772
+ }
773
+ ```
774
+
775
+ **Gotcha**: Number of rules must match number of outputs!
776
+
777
+ ---
778
+
779
+ ## AI Nodes
780
+
781
+ ### OpenAI (nodes-langchain.openAi)
782
+
783
+ AI operations - 234 templates
784
+
785
+ #### Chat Completion
786
+
787
+ **Minimal**:
788
+ ```javascript
789
+ {
790
+ "resource": "chat",
791
+ "operation": "complete",
792
+ "messages": {
793
+ "values": [
794
+ {
795
+ "role": "user",
796
+ "content": "={{$json.prompt}}"
797
+ }
798
+ ]
799
+ }
800
+ }
801
+ ```
802
+
803
+ **With system prompt**:
804
+ ```javascript
805
+ {
806
+ "resource": "chat",
807
+ "operation": "complete",
808
+ "messages": {
809
+ "values": [
810
+ {
811
+ "role": "system",
812
+ "content": "You are a helpful assistant specialized in customer support."
813
+ },
814
+ {
815
+ "role": "user",
816
+ "content": "={{$json.userMessage}}"
817
+ }
818
+ ]
819
+ },
820
+ "options": {
821
+ "temperature": 0.7,
822
+ "maxTokens": 500
823
+ }
824
+ }
825
+ ```
826
+
827
+ ---
828
+
829
+ ## Schedule Nodes
830
+
831
+ ### Schedule Trigger (nodes-base.scheduleTrigger)
832
+
833
+ Time-based workflows - 28% have schedule triggers
834
+
835
+ #### Daily at Specific Time
836
+
837
+ **Minimal**:
838
+ ```javascript
839
+ {
840
+ "rule": {
841
+ "interval": [
842
+ {
843
+ "field": "hours",
844
+ "hoursInterval": 24
845
+ }
846
+ ],
847
+ "hour": 9,
848
+ "minute": 0,
849
+ "timezone": "America/New_York"
850
+ }
851
+ }
852
+ ```
853
+
854
+ **Gotcha**: Always set timezone explicitly!
855
+
856
+ ```javascript
857
+ // ❌ Bad - uses server timezone
858
+ {
859
+ "rule": {
860
+ "interval": [...]
861
+ }
862
+ }
863
+
864
+ // ✅ Good - explicit timezone
865
+ {
866
+ "rule": {
867
+ "interval": [...],
868
+ "timezone": "America/New_York"
869
+ }
870
+ }
871
+ ```
872
+
873
+ #### Every N Minutes
874
+
875
+ **Minimal**:
876
+ ```javascript
877
+ {
878
+ "rule": {
879
+ "interval": [
880
+ {
881
+ "field": "minutes",
882
+ "minutesInterval": 15
883
+ }
884
+ ]
885
+ }
886
+ }
887
+ ```
888
+
889
+ #### Cron Expression
890
+
891
+ **Advanced scheduling**:
892
+ ```javascript
893
+ {
894
+ "mode": "cron",
895
+ "cronExpression": "0 */2 * * *", // Every 2 hours
896
+ "timezone": "America/New_York"
897
+ }
898
+ ```
899
+
900
+ ---
901
+
902
+ ## Summary
903
+
904
+ **Key Patterns by Category**:
905
+
906
+ | Category | Most Common | Key Gotcha |
907
+ |---|---|---|
908
+ | HTTP/API | GET, POST JSON | Remember sendBody: true |
909
+ | Webhooks | POST receiver | Data under $json.body |
910
+ | Communication | Slack post | Channel format (#name) |
911
+ | Database | SELECT with params | Use parameterized queries |
912
+ | Transform | Set assignments | Correct type per field |
913
+ | Conditional | IF string equals | Unary vs binary operators |
914
+ | AI | OpenAI chat | System + user messages |
915
+ | Schedule | Daily at time | Set timezone explicitly |
916
+
917
+ **Configuration Approach**:
918
+ 1. Use patterns as starting point
919
+ 2. Adapt to your use case
920
+ 3. Verify in the n8n editor (open the node — warnings flag missing/invalid required fields)
921
+ 4. Iterate based on warnings
922
+ 5. Execute with test data before relying on it
923
+
924
+ **Related Files**:
925
+ - **[SKILL.md](SKILL.md)** - Configuration workflow and philosophy
926
+ - **[DEPENDENCIES.md](DEPENDENCIES.md)** - Property dependency rules