@hailer/mcp 0.0.1

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 (163) hide show
  1. package/.claude/commands/tool-builder.md +37 -0
  2. package/.claude/commands/ws-pull.md +44 -0
  3. package/.claude/settings.json +8 -0
  4. package/.claude/settings.local.json +49 -0
  5. package/.claude/skills/activity-api/SKILL.md +96 -0
  6. package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
  7. package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
  8. package/.claude/skills/agent-building/SKILL.md +243 -0
  9. package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
  10. package/.claude/skills/agent-building/references/code-examples.md +587 -0
  11. package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
  12. package/.claude/skills/app-api/SKILL.md +219 -0
  13. package/.claude/skills/app-api/references/app-endpoints.md +759 -0
  14. package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
  15. package/.claude/skills/create-app-skill/SKILL.md +1101 -0
  16. package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
  17. package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
  18. package/.claude/skills/hailer-api/SKILL.md +283 -0
  19. package/.claude/skills/hailer-api/references/activities.md +620 -0
  20. package/.claude/skills/hailer-api/references/authentication.md +216 -0
  21. package/.claude/skills/hailer-api/references/datasets.md +437 -0
  22. package/.claude/skills/hailer-api/references/files.md +301 -0
  23. package/.claude/skills/hailer-api/references/insights.md +469 -0
  24. package/.claude/skills/hailer-api/references/workflows.md +720 -0
  25. package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
  26. package/.claude/skills/insight-api/SKILL.md +185 -0
  27. package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
  28. package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
  29. package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
  30. package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
  31. package/.claude/skills/local-first-skill/SKILL.md +570 -0
  32. package/.claude/skills/mcp-tools/SKILL.md +419 -0
  33. package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
  34. package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
  35. package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
  36. package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
  37. package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
  38. package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
  39. package/.claude/skills/remove-app-skill/SKILL.md +985 -0
  40. package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
  41. package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
  42. package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
  43. package/.claude/skills/skill-testing/README.md +137 -0
  44. package/.claude/skills/skill-testing/SKILL.md +348 -0
  45. package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
  46. package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
  47. package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
  48. package/.claude/skills/tool-builder/SKILL.md +328 -0
  49. package/.claude/skills/update-app-skill/SKILL.md +970 -0
  50. package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
  51. package/.env.example +81 -0
  52. package/.mcp.json +13 -0
  53. package/README.md +297 -0
  54. package/dist/app.d.ts +4 -0
  55. package/dist/app.js +74 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.js +5 -0
  58. package/dist/client/adaptive-documentation-bot.d.ts +108 -0
  59. package/dist/client/adaptive-documentation-bot.js +475 -0
  60. package/dist/client/adaptive-documentation-types.d.ts +66 -0
  61. package/dist/client/adaptive-documentation-types.js +9 -0
  62. package/dist/client/agent-activity-bot.d.ts +51 -0
  63. package/dist/client/agent-activity-bot.js +166 -0
  64. package/dist/client/agent-tracker.d.ts +499 -0
  65. package/dist/client/agent-tracker.js +659 -0
  66. package/dist/client/description-updater.d.ts +56 -0
  67. package/dist/client/description-updater.js +259 -0
  68. package/dist/client/log-parser.d.ts +72 -0
  69. package/dist/client/log-parser.js +387 -0
  70. package/dist/client/mcp-client.d.ts +50 -0
  71. package/dist/client/mcp-client.js +532 -0
  72. package/dist/client/message-processor.d.ts +35 -0
  73. package/dist/client/message-processor.js +352 -0
  74. package/dist/client/multi-bot-manager.d.ts +24 -0
  75. package/dist/client/multi-bot-manager.js +74 -0
  76. package/dist/client/providers/anthropic-provider.d.ts +19 -0
  77. package/dist/client/providers/anthropic-provider.js +631 -0
  78. package/dist/client/providers/llm-provider.d.ts +47 -0
  79. package/dist/client/providers/llm-provider.js +367 -0
  80. package/dist/client/providers/openai-provider.d.ts +23 -0
  81. package/dist/client/providers/openai-provider.js +621 -0
  82. package/dist/client/simple-llm-caller.d.ts +19 -0
  83. package/dist/client/simple-llm-caller.js +100 -0
  84. package/dist/client/skill-generator.d.ts +81 -0
  85. package/dist/client/skill-generator.js +386 -0
  86. package/dist/client/test-adaptive-bot.d.ts +9 -0
  87. package/dist/client/test-adaptive-bot.js +82 -0
  88. package/dist/client/token-pricing.d.ts +38 -0
  89. package/dist/client/token-pricing.js +127 -0
  90. package/dist/client/token-tracker.d.ts +232 -0
  91. package/dist/client/token-tracker.js +457 -0
  92. package/dist/client/token-usage-bot.d.ts +53 -0
  93. package/dist/client/token-usage-bot.js +153 -0
  94. package/dist/client/tool-executor.d.ts +69 -0
  95. package/dist/client/tool-executor.js +159 -0
  96. package/dist/client/tool-schema-loader.d.ts +60 -0
  97. package/dist/client/tool-schema-loader.js +178 -0
  98. package/dist/client/types.d.ts +69 -0
  99. package/dist/client/types.js +7 -0
  100. package/dist/config.d.ts +162 -0
  101. package/dist/config.js +296 -0
  102. package/dist/core.d.ts +26 -0
  103. package/dist/core.js +147 -0
  104. package/dist/lib/context-manager.d.ts +111 -0
  105. package/dist/lib/context-manager.js +431 -0
  106. package/dist/lib/logger.d.ts +74 -0
  107. package/dist/lib/logger.js +277 -0
  108. package/dist/lib/materialize.d.ts +3 -0
  109. package/dist/lib/materialize.js +101 -0
  110. package/dist/lib/normalizedName.d.ts +7 -0
  111. package/dist/lib/normalizedName.js +48 -0
  112. package/dist/lib/prompt-length-manager.d.ts +81 -0
  113. package/dist/lib/prompt-length-manager.js +457 -0
  114. package/dist/lib/terminal-prompt.d.ts +9 -0
  115. package/dist/lib/terminal-prompt.js +108 -0
  116. package/dist/mcp/UserContextCache.d.ts +56 -0
  117. package/dist/mcp/UserContextCache.js +163 -0
  118. package/dist/mcp/auth.d.ts +2 -0
  119. package/dist/mcp/auth.js +29 -0
  120. package/dist/mcp/hailer-clients.d.ts +42 -0
  121. package/dist/mcp/hailer-clients.js +246 -0
  122. package/dist/mcp/signal-handler.d.ts +45 -0
  123. package/dist/mcp/signal-handler.js +317 -0
  124. package/dist/mcp/tool-registry.d.ts +100 -0
  125. package/dist/mcp/tool-registry.js +306 -0
  126. package/dist/mcp/tools/activity.d.ts +15 -0
  127. package/dist/mcp/tools/activity.js +955 -0
  128. package/dist/mcp/tools/app.d.ts +20 -0
  129. package/dist/mcp/tools/app.js +1488 -0
  130. package/dist/mcp/tools/discussion.d.ts +19 -0
  131. package/dist/mcp/tools/discussion.js +950 -0
  132. package/dist/mcp/tools/file.d.ts +15 -0
  133. package/dist/mcp/tools/file.js +119 -0
  134. package/dist/mcp/tools/insight.d.ts +17 -0
  135. package/dist/mcp/tools/insight.js +806 -0
  136. package/dist/mcp/tools/skill.d.ts +10 -0
  137. package/dist/mcp/tools/skill.js +279 -0
  138. package/dist/mcp/tools/user.d.ts +10 -0
  139. package/dist/mcp/tools/user.js +108 -0
  140. package/dist/mcp/tools/workflow-template.d.ts +19 -0
  141. package/dist/mcp/tools/workflow-template.js +822 -0
  142. package/dist/mcp/tools/workflow.d.ts +18 -0
  143. package/dist/mcp/tools/workflow.js +1362 -0
  144. package/dist/mcp/utils/api-errors.d.ts +45 -0
  145. package/dist/mcp/utils/api-errors.js +160 -0
  146. package/dist/mcp/utils/data-transformers.d.ts +102 -0
  147. package/dist/mcp/utils/data-transformers.js +194 -0
  148. package/dist/mcp/utils/file-upload.d.ts +33 -0
  149. package/dist/mcp/utils/file-upload.js +148 -0
  150. package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
  151. package/dist/mcp/utils/hailer-api-client.js +323 -0
  152. package/dist/mcp/utils/index.d.ts +13 -0
  153. package/dist/mcp/utils/index.js +39 -0
  154. package/dist/mcp/utils/logger.d.ts +42 -0
  155. package/dist/mcp/utils/logger.js +103 -0
  156. package/dist/mcp/utils/types.d.ts +286 -0
  157. package/dist/mcp/utils/types.js +7 -0
  158. package/dist/mcp/workspace-cache.d.ts +42 -0
  159. package/dist/mcp/workspace-cache.js +97 -0
  160. package/dist/mcp-server.d.ts +42 -0
  161. package/dist/mcp-server.js +280 -0
  162. package/package.json +56 -0
  163. package/tsconfig.json +23 -0
@@ -0,0 +1,1290 @@
1
+ ---
2
+ name: Preview Hailer Insights
3
+ description: Complete guide for testing SQL queries before saving insights - use when debugging queries or designing reports
4
+ ---
5
+
6
+ # Preview Hailer Insights - Complete Guide
7
+
8
+ Complete reference for testing SQL queries on Hailer workflow data using the `preview_insight` MCP tool.
9
+
10
+ ## Table of Contents
11
+ 1. [Quick Reference](#quick-reference)
12
+ 2. [Overview](#overview)
13
+ 3. [Core Concepts](#core-concepts)
14
+ 4. [Basic Usage](#basic-usage)
15
+ 5. [Development Workflow](#development-workflow)
16
+ 6. [Testing Strategies](#testing-strategies)
17
+ 7. [Debugging Queries](#debugging-queries)
18
+ 8. [Common Scenarios](#common-scenarios)
19
+ 9. [Performance Considerations](#performance-considerations)
20
+ 10. [Best Practices](#best-practices)
21
+ 11. [Troubleshooting](#troubleshooting)
22
+
23
+ ## Quick Reference
24
+
25
+ **Test Simple Query:**
26
+
27
+ ```javascript
28
+ preview_insight({
29
+ sources: [{
30
+ name: 'tasks',
31
+ workflowId: 'tasks-workflow-id',
32
+ fields: [
33
+ { name: 'title', meta: 'name' },
34
+ { name: 'dueDate', fieldId: 'due-date-field-id' }
35
+ ]
36
+ }],
37
+ query: 'SELECT title, dueDate FROM tasks WHERE dueDate > "2024-01-01"'
38
+ })
39
+ ```
40
+
41
+ **Test JOIN Query:**
42
+
43
+ ```javascript
44
+ preview_insight({
45
+ sources: [
46
+ {
47
+ name: 'tasks',
48
+ workflowId: 'tasks-workflow-id',
49
+ fields: [
50
+ { name: 'taskName', meta: 'name' },
51
+ { name: 'projectLink', fieldId: 'project-link-field-id' }
52
+ ]
53
+ },
54
+ {
55
+ name: 'projects',
56
+ workflowId: 'projects-workflow-id',
57
+ fields: [
58
+ { name: 'id', meta: '_id' },
59
+ { name: 'projectName', meta: 'name' }
60
+ ]
61
+ }
62
+ ],
63
+ query: `
64
+ SELECT tasks.taskName, projects.projectName
65
+ FROM tasks
66
+ LEFT JOIN projects ON tasks.projectLink = projects.id
67
+ `
68
+ })
69
+ ```
70
+
71
+ **Preview Existing Insight Changes:**
72
+
73
+ ```javascript
74
+ preview_insight({
75
+ insightId: 'existing-insight-id', // Preview changes to existing insight
76
+ sources: [...], // New sources
77
+ query: 'SELECT ...' // New query
78
+ })
79
+ ```
80
+
81
+ **Key Features:**
82
+ - Tests SQL queries without creating insights
83
+ - Shows sample results (~20 activities)
84
+ - Fast iteration for query development
85
+ - Catches syntax errors immediately
86
+ - Safe testing - doesn't save anything
87
+
88
+ ## Overview
89
+
90
+ **What is Preview?**
91
+
92
+ Preview lets you test SQL queries on a small sample of your workflow data before creating or updating an insight. It's the essential tool for insight development and debugging.
93
+
94
+ **Think of it as:**
95
+ - SQL query validation
96
+ - Dry run before committing
97
+ - Interactive query builder
98
+ - Debug console for insights
99
+
100
+ **Key Differences from create_insight:**
101
+
102
+ | Feature | preview_insight | create_insight |
103
+ |---------|----------------|----------------|
104
+ | Saves insight | โŒ No | โœ… Yes |
105
+ | Data returned | ~20 activities | Not directly |
106
+ | Use case | Testing/debugging | Production use |
107
+ | Speed | Very fast | Slower (saves) |
108
+ | Iterations | Unlimited | Should minimize |
109
+
110
+ **When to Use:**
111
+ - Before creating new insights
112
+ - When debugging SQL errors
113
+ - Testing field mappings
114
+ - Verifying JOIN conditions
115
+ - Checking WHERE clause logic
116
+ - Validating aggregations
117
+ - Iterating on query design
118
+
119
+ **When NOT to Use:**
120
+ - Getting full dataset (use get_insight_data)
121
+ - Running production reports (create insight first)
122
+ - When query already works (just create it)
123
+
124
+ ## Core Concepts
125
+
126
+ ### Preview vs Create Workflow
127
+
128
+ **Recommended Flow:**
129
+
130
+ ```
131
+ 1. Design query structure
132
+ โ†“
133
+ 2. Preview with minimal data
134
+ โ†“
135
+ 3. Fix errors, iterate
136
+ โ†“
137
+ 4. Preview until successful
138
+ โ†“
139
+ 5. Create insight
140
+ โ†“
141
+ 6. Get full data with get_insight_data
142
+ ```
143
+
144
+ **Anti-Pattern (Don't Do This):**
145
+
146
+ ```
147
+ 1. Create insight immediately
148
+ โ†“
149
+ 2. Get error
150
+ โ†“
151
+ 3. Debug by trial and error
152
+ โ†“
153
+ 4. Remove and recreate multiple times
154
+ ```
155
+
156
+ ### Sample Data Limitation
157
+
158
+ **Important:** Preview returns only ~20 activities per source.
159
+
160
+ **What this means:**
161
+ - Quick feedback on query structure
162
+ - May not show all edge cases
163
+ - Aggregations may not be representative
164
+ - JOINs might miss some relationships
165
+
166
+ **Good for:**
167
+ - SQL syntax validation
168
+ - Field mapping verification
169
+ - JOIN logic testing
170
+ - Column name checking
171
+
172
+ **Not good for:**
173
+ - Accurate COUNT results
174
+ - Complete data analysis
175
+ - Finding rare edge cases
176
+ - Production reporting
177
+
178
+ ### Security Note
179
+
180
+ **Regular Users:**
181
+ - Can only preview with sources from existing insights they have access to
182
+ - Cannot test arbitrary workflow combinations
183
+ - Security restriction to prevent unauthorized data access
184
+
185
+ **Workspace Admins:**
186
+ - Can preview with any workflow sources
187
+ - Full testing capabilities
188
+ - No source restrictions
189
+
190
+ ## Basic Usage
191
+
192
+ ### Example 1: Test Simple Query
193
+
194
+ ```javascript
195
+ // Step 1: Define sources and query
196
+ preview_insight({
197
+ sources: [{
198
+ name: 'tasks',
199
+ workflowId: '68446dc05b30685f67c6fcd4',
200
+ fields: [
201
+ { name: 'title', meta: 'name' },
202
+ { name: 'priority', fieldId: 'priority-field-id' }
203
+ ]
204
+ }],
205
+ query: 'SELECT title, priority FROM tasks'
206
+ })
207
+
208
+ // Response:
209
+ // โœ… Insight Preview Successful
210
+ //
211
+ // Query Results (showing up to 20 activities):
212
+ // | title | priority |
213
+ // |-------|----------|
214
+ // | Task 1 | High |
215
+ // | Task 2 | Medium |
216
+ // ...
217
+ ```
218
+
219
+ ### Example 2: Test with Filter
220
+
221
+ ```javascript
222
+ preview_insight({
223
+ sources: [{
224
+ name: 'tasks',
225
+ workflowId: 'tasks-workflow-id',
226
+ fields: [
227
+ { name: 'title', meta: 'name' },
228
+ { name: 'priority', fieldId: 'priority-field-id' },
229
+ { name: 'status', meta: 'phase' }
230
+ ]
231
+ }],
232
+ query: `
233
+ SELECT title, priority, status
234
+ FROM tasks
235
+ WHERE priority = 'High' AND status != 'Done'
236
+ `
237
+ })
238
+ ```
239
+
240
+ ### Example 3: Test JOIN
241
+
242
+ ```javascript
243
+ preview_insight({
244
+ sources: [
245
+ {
246
+ name: 'tasks',
247
+ workflowId: 'tasks-workflow-id',
248
+ fields: [
249
+ { name: 'taskName', meta: 'name' },
250
+ { name: 'projectId', fieldId: 'project-field-id' }
251
+ ]
252
+ },
253
+ {
254
+ name: 'projects',
255
+ workflowId: 'projects-workflow-id',
256
+ fields: [
257
+ { name: 'id', meta: '_id' },
258
+ { name: 'projectName', meta: 'name' }
259
+ ]
260
+ }
261
+ ],
262
+ query: `
263
+ SELECT
264
+ tasks.taskName,
265
+ projects.projectName
266
+ FROM tasks
267
+ LEFT JOIN projects ON tasks.projectId = projects.id
268
+ `
269
+ })
270
+ ```
271
+
272
+ ### Example 4: Test Aggregation
273
+
274
+ ```javascript
275
+ preview_insight({
276
+ sources: [{
277
+ name: 'tasks',
278
+ workflowId: 'tasks-workflow-id',
279
+ fields: [
280
+ { name: 'priority', fieldId: 'priority-field-id' }
281
+ ]
282
+ }],
283
+ query: `
284
+ SELECT priority, COUNT(*) AS count
285
+ FROM tasks
286
+ GROUP BY priority
287
+ ORDER BY count DESC
288
+ `
289
+ })
290
+
291
+ // Note: COUNT will only reflect ~20 sampled activities
292
+ ```
293
+
294
+ ## Development Workflow
295
+
296
+ ### Workflow 1: Build Query Iteratively
297
+
298
+ **Start simple, add complexity gradually:**
299
+
300
+ ```javascript
301
+ // Step 1: Start with SELECT *
302
+ preview_insight({
303
+ sources: [{
304
+ name: 'tasks',
305
+ workflowId: 'tasks-workflow-id',
306
+ fields: [
307
+ { name: 'title', meta: 'name' }
308
+ ]
309
+ }],
310
+ query: 'SELECT * FROM tasks'
311
+ })
312
+ // โœ… Works? Continue.
313
+
314
+ // Step 2: Add specific columns
315
+ preview_insight({
316
+ sources: [{
317
+ name: 'tasks',
318
+ workflowId: 'tasks-workflow-id',
319
+ fields: [
320
+ { name: 'title', meta: 'name' },
321
+ { name: 'priority', fieldId: 'priority-field-id' }
322
+ ]
323
+ }],
324
+ query: 'SELECT title, priority FROM tasks'
325
+ })
326
+ // โœ… Works? Continue.
327
+
328
+ // Step 3: Add WHERE clause
329
+ preview_insight({
330
+ sources: [{
331
+ name: 'tasks',
332
+ workflowId: 'tasks-workflow-id',
333
+ fields: [
334
+ { name: 'title', meta: 'name' },
335
+ { name: 'priority', fieldId: 'priority-field-id' }
336
+ ]
337
+ }],
338
+ query: 'SELECT title, priority FROM tasks WHERE priority = "High"'
339
+ })
340
+ // โœ… Works? Continue.
341
+
342
+ // Step 4: Add ORDER BY
343
+ preview_insight({
344
+ sources: [{
345
+ name: 'tasks',
346
+ workflowId: 'tasks-workflow-id',
347
+ fields: [
348
+ { name: 'title', meta: 'name' },
349
+ { name: 'priority', fieldId: 'priority-field-id' },
350
+ { name: 'created', meta: 'created' }
351
+ ]
352
+ }],
353
+ query: `
354
+ SELECT title, priority, created
355
+ FROM tasks
356
+ WHERE priority = 'High'
357
+ ORDER BY created DESC
358
+ `
359
+ })
360
+ // โœ… Works? Create insight!
361
+ ```
362
+
363
+ ### Workflow 2: Test JOIN Relationships
364
+
365
+ ```javascript
366
+ // Step 1: Verify both sources independently
367
+ preview_insight({
368
+ sources: [{
369
+ name: 'tasks',
370
+ workflowId: 'tasks-workflow-id',
371
+ fields: [
372
+ { name: 'id', meta: '_id' },
373
+ { name: 'title', meta: 'name' }
374
+ ]
375
+ }],
376
+ query: 'SELECT * FROM tasks LIMIT 5'
377
+ })
378
+
379
+ preview_insight({
380
+ sources: [{
381
+ name: 'projects',
382
+ workflowId: 'projects-workflow-id',
383
+ fields: [
384
+ { name: 'id', meta: '_id' },
385
+ { name: 'name', meta: 'name' }
386
+ ]
387
+ }],
388
+ query: 'SELECT * FROM projects LIMIT 5'
389
+ })
390
+
391
+ // Step 2: Test JOIN without filters
392
+ preview_insight({
393
+ sources: [
394
+ {
395
+ name: 'tasks',
396
+ workflowId: 'tasks-workflow-id',
397
+ fields: [
398
+ { name: 'title', meta: 'name' },
399
+ { name: 'projectId', fieldId: 'project-field-id' }
400
+ ]
401
+ },
402
+ {
403
+ name: 'projects',
404
+ workflowId: 'projects-workflow-id',
405
+ fields: [
406
+ { name: 'id', meta: '_id' },
407
+ { name: 'projectName', meta: 'name' }
408
+ ]
409
+ }
410
+ ],
411
+ query: `
412
+ SELECT tasks.title, projects.projectName
413
+ FROM tasks
414
+ LEFT JOIN projects ON tasks.projectId = projects.id
415
+ `
416
+ })
417
+
418
+ // Step 3: Add filters and sorting
419
+ preview_insight({
420
+ sources: [...],
421
+ query: `
422
+ SELECT tasks.title, projects.projectName
423
+ FROM tasks
424
+ LEFT JOIN projects ON tasks.projectId = projects.id
425
+ WHERE projects.projectName IS NOT NULL
426
+ ORDER BY projects.projectName, tasks.title
427
+ `
428
+ })
429
+ ```
430
+
431
+ ### Workflow 3: Fix Field Mapping Errors
432
+
433
+ ```javascript
434
+ // Step 1: Preview with suspected incorrect field
435
+ preview_insight({
436
+ sources: [{
437
+ name: 'tasks',
438
+ workflowId: 'tasks-workflow-id',
439
+ fields: [
440
+ { name: 'priority', fieldId: 'wrong-field-id' } // Wrong ID
441
+ ]
442
+ }],
443
+ query: 'SELECT priority FROM tasks'
444
+ })
445
+ // โŒ Returns null or unexpected values
446
+
447
+ // Step 2: Get correct field ID
448
+ const schema = get_workflow_schema({
449
+ workflowId: 'tasks-workflow-id'
450
+ })
451
+ const priorityField = schema.fields.find(f => f.key === 'priority')
452
+ console.log('Correct field ID:', priorityField._id)
453
+
454
+ // Step 3: Retry with correct field ID
455
+ preview_insight({
456
+ sources: [{
457
+ name: 'tasks',
458
+ workflowId: 'tasks-workflow-id',
459
+ fields: [
460
+ { name: 'priority', fieldId: priorityField._id } // Correct ID
461
+ ]
462
+ }],
463
+ query: 'SELECT priority FROM tasks'
464
+ })
465
+ // โœ… Works!
466
+ ```
467
+
468
+ ## Testing Strategies
469
+
470
+ ### Strategy 1: Column-by-Column Verification
471
+
472
+ **Test each field individually:**
473
+
474
+ ```javascript
475
+ // Test field 1
476
+ preview_insight({
477
+ sources: [{
478
+ name: 'tasks',
479
+ workflowId: 'tasks-workflow-id',
480
+ fields: [{ name: 'title', meta: 'name' }]
481
+ }],
482
+ query: 'SELECT title FROM tasks LIMIT 5'
483
+ })
484
+
485
+ // Test field 2
486
+ preview_insight({
487
+ sources: [{
488
+ name: 'tasks',
489
+ workflowId: 'tasks-workflow-id',
490
+ fields: [{ name: 'priority', fieldId: 'priority-field-id' }]
491
+ }],
492
+ query: 'SELECT priority FROM tasks LIMIT 5'
493
+ })
494
+
495
+ // Combine once both work
496
+ preview_insight({
497
+ sources: [{
498
+ name: 'tasks',
499
+ workflowId: 'tasks-workflow-id',
500
+ fields: [
501
+ { name: 'title', meta: 'name' },
502
+ { name: 'priority', fieldId: 'priority-field-id' }
503
+ ]
504
+ }],
505
+ query: 'SELECT title, priority FROM tasks LIMIT 5'
506
+ })
507
+ ```
508
+
509
+ ### Strategy 2: WHERE Clause Testing
510
+
511
+ **Test filters incrementally:**
512
+
513
+ ```javascript
514
+ // No filter
515
+ preview_insight({
516
+ sources: [...],
517
+ query: 'SELECT title, priority FROM tasks'
518
+ })
519
+ // Note: How many rows returned?
520
+
521
+ // Add first filter
522
+ preview_insight({
523
+ sources: [...],
524
+ query: 'SELECT title, priority FROM tasks WHERE priority = "High"'
525
+ })
526
+ // Note: Did rows decrease appropriately?
527
+
528
+ // Add second filter
529
+ preview_insight({
530
+ sources: [...],
531
+ query: `
532
+ SELECT title, priority, status
533
+ FROM tasks
534
+ WHERE priority = 'High' AND status != 'Done'
535
+ `
536
+ })
537
+ // Note: Further decrease makes sense?
538
+ ```
539
+
540
+ ### Strategy 3: JOIN Direction Testing
541
+
542
+ **Test different JOIN types:**
543
+
544
+ ```javascript
545
+ // Test INNER JOIN (only matching)
546
+ preview_insight({
547
+ sources: [...],
548
+ query: `
549
+ SELECT tasks.title, projects.projectName
550
+ FROM tasks
551
+ INNER JOIN projects ON tasks.projectId = projects.id
552
+ `
553
+ })
554
+ // Note: Row count
555
+
556
+ // Test LEFT JOIN (all tasks)
557
+ preview_insight({
558
+ sources: [...],
559
+ query: `
560
+ SELECT tasks.title, projects.projectName
561
+ FROM tasks
562
+ LEFT JOIN projects ON tasks.projectId = projects.id
563
+ `
564
+ })
565
+ // Note: Should have more rows (tasks without projects included)
566
+
567
+ // Test RIGHT JOIN (all projects)
568
+ preview_insight({
569
+ sources: [...],
570
+ query: `
571
+ SELECT tasks.title, projects.projectName
572
+ FROM tasks
573
+ RIGHT JOIN projects ON tasks.projectId = projects.id
574
+ `
575
+ })
576
+ // Note: Different row count (projects without tasks included)
577
+ ```
578
+
579
+ ### Strategy 4: Aggregation Validation
580
+
581
+ **Check aggregation logic:**
582
+
583
+ ```javascript
584
+ // Simple count
585
+ preview_insight({
586
+ sources: [{
587
+ name: 'tasks',
588
+ workflowId: 'tasks-workflow-id',
589
+ fields: [{ name: 'id', meta: '_id' }]
590
+ }],
591
+ query: 'SELECT COUNT(*) AS total FROM tasks'
592
+ })
593
+ // Note: Total (but remember, only ~20 activities sampled)
594
+
595
+ // Count by group
596
+ preview_insight({
597
+ sources: [{
598
+ name: 'tasks',
599
+ workflowId: 'tasks-workflow-id',
600
+ fields: [{ name: 'priority', fieldId: 'priority-field-id' }]
601
+ }],
602
+ query: `
603
+ SELECT priority, COUNT(*) AS count
604
+ FROM tasks
605
+ GROUP BY priority
606
+ `
607
+ })
608
+ // Note: Distributions (sample only)
609
+
610
+ // Verify with detail query
611
+ preview_insight({
612
+ sources: [{
613
+ name: 'tasks',
614
+ workflowId: 'tasks-workflow-id',
615
+ fields: [{ name: 'priority', fieldId: 'priority-field-id' }]
616
+ }],
617
+ query: 'SELECT priority FROM tasks'
618
+ })
619
+ // Note: Manually count to verify GROUP BY logic
620
+ ```
621
+
622
+ ## Debugging Queries
623
+
624
+ ### Debug Pattern 1: SQL Syntax Errors
625
+
626
+ **Error:** SQL syntax error
627
+
628
+ **Debug steps:**
629
+
630
+ ```javascript
631
+ // 1. Simplify to minimal query
632
+ preview_insight({
633
+ sources: [{
634
+ name: 'tasks',
635
+ workflowId: 'tasks-workflow-id',
636
+ fields: [{ name: 'title', meta: 'name' }]
637
+ }],
638
+ query: 'SELECT title FROM tasks'
639
+ })
640
+ // โœ… Works? Syntax is valid.
641
+
642
+ // 2. Add back pieces one at a time
643
+ preview_insight({
644
+ sources: [...],
645
+ query: 'SELECT title FROM tasks WHERE priority = "High"'
646
+ })
647
+ // โŒ Error? Issue is in WHERE clause.
648
+
649
+ // 3. Fix WHERE clause (quotes)
650
+ preview_insight({
651
+ sources: [...],
652
+ query: "SELECT title FROM tasks WHERE priority = 'High'"
653
+ })
654
+ // โœ… Works? Continue adding.
655
+ ```
656
+
657
+ ### Debug Pattern 2: Column Not Found
658
+
659
+ **Error:** Column name doesn't exist
660
+
661
+ **Debug steps:**
662
+
663
+ ```javascript
664
+ // 1. List all available columns
665
+ preview_insight({
666
+ sources: [{
667
+ name: 'tasks',
668
+ workflowId: 'tasks-workflow-id',
669
+ fields: [
670
+ { name: 'field1', meta: 'name' },
671
+ { name: 'field2', fieldId: 'field-id' }
672
+ ]
673
+ }],
674
+ query: 'SELECT * FROM tasks LIMIT 1'
675
+ })
676
+ // Note: What columns appear in result?
677
+
678
+ // 2. Use correct column name
679
+ preview_insight({
680
+ sources: [...],
681
+ query: 'SELECT field1, field2 FROM tasks'
682
+ })
683
+ // Must match name in field mapping
684
+ ```
685
+
686
+ ### Debug Pattern 3: JOIN Returns No Rows
687
+
688
+ **Problem:** JOIN returns empty result
689
+
690
+ **Debug steps:**
691
+
692
+ ```javascript
693
+ // 1. Check both tables have data
694
+ preview_insight({
695
+ sources: [{
696
+ name: 'tasks',
697
+ workflowId: 'tasks-workflow-id',
698
+ fields: [{ name: 'id', meta: '_id' }]
699
+ }],
700
+ query: 'SELECT COUNT(*) FROM tasks'
701
+ })
702
+
703
+ preview_insight({
704
+ sources: [{
705
+ name: 'projects',
706
+ workflowId: 'projects-workflow-id',
707
+ fields: [{ name: 'id', meta: '_id' }]
708
+ }],
709
+ query: 'SELECT COUNT(*) FROM projects'
710
+ })
711
+
712
+ // 2. Check JOIN keys have values
713
+ preview_insight({
714
+ sources: [{
715
+ name: 'tasks',
716
+ workflowId: 'tasks-workflow-id',
717
+ fields: [
718
+ { name: 'projectId', fieldId: 'project-field-id' }
719
+ ]
720
+ }],
721
+ query: 'SELECT projectId FROM tasks WHERE projectId IS NOT NULL'
722
+ })
723
+
724
+ // 3. Use LEFT JOIN to see all tasks
725
+ preview_insight({
726
+ sources: [
727
+ {
728
+ name: 'tasks',
729
+ workflowId: 'tasks-workflow-id',
730
+ fields: [
731
+ { name: 'title', meta: 'name' },
732
+ { name: 'projectId', fieldId: 'project-field-id' }
733
+ ]
734
+ },
735
+ {
736
+ name: 'projects',
737
+ workflowId: 'projects-workflow-id',
738
+ fields: [
739
+ { name: 'id', meta: '_id' },
740
+ { name: 'projectName', meta: 'name' }
741
+ ]
742
+ }
743
+ ],
744
+ query: `
745
+ SELECT tasks.title, tasks.projectId, projects.projectName
746
+ FROM tasks
747
+ LEFT JOIN projects ON tasks.projectId = projects.id
748
+ `
749
+ })
750
+ // Shows which tasks don't match projects
751
+ ```
752
+
753
+ ### Debug Pattern 4: Unexpected NULL Values
754
+
755
+ **Problem:** Fields show NULL when they shouldn't
756
+
757
+ **Debug steps:**
758
+
759
+ ```javascript
760
+ // 1. Check field mapping
761
+ const schema = get_workflow_schema({
762
+ workflowId: 'workflow-id'
763
+ })
764
+ console.log('Available fields:', schema.fields.map(f => ({
765
+ id: f._id,
766
+ key: f.key,
767
+ label: f.label
768
+ })))
769
+
770
+ // 2. Verify field ID is correct
771
+ const field = schema.fields.find(f => f.key === 'priority')
772
+ console.log('Priority field ID:', field._id)
773
+
774
+ // 3. Test with correct field ID
775
+ preview_insight({
776
+ sources: [{
777
+ name: 'tasks',
778
+ workflowId: 'workflow-id',
779
+ fields: [
780
+ { name: 'priority', fieldId: field._id } // Correct ID
781
+ ]
782
+ }],
783
+ query: 'SELECT priority FROM tasks'
784
+ })
785
+
786
+ // 4. Check if field values actually exist
787
+ list_activities({
788
+ workflowId: 'workflow-id',
789
+ limit: 5,
790
+ returnFlat: true
791
+ })
792
+ // Verify activities have priority values
793
+ ```
794
+
795
+ ## Common Scenarios
796
+
797
+ ### Scenario 1: Design New Report
798
+
799
+ ```javascript
800
+ // Goal: Create "High Priority Overdue Tasks" report
801
+
802
+ // Step 1: Get field IDs
803
+ const schema = get_workflow_schema({
804
+ workflowId: 'tasks-workflow-id'
805
+ })
806
+
807
+ // Step 2: Preview basic query
808
+ preview_insight({
809
+ sources: [{
810
+ name: 'tasks',
811
+ workflowId: 'tasks-workflow-id',
812
+ fields: [
813
+ { name: 'title', meta: 'name' },
814
+ { name: 'priority', fieldId: 'priority-field-id' },
815
+ { name: 'dueDate', fieldId: 'due-date-field-id' }
816
+ ]
817
+ }],
818
+ query: `
819
+ SELECT title, priority, dueDate
820
+ FROM tasks
821
+ WHERE priority = 'High'
822
+ AND dueDate < date('now')
823
+ ORDER BY dueDate ASC
824
+ `
825
+ })
826
+ // โœ… Works? Create insight.
827
+
828
+ // Step 3: Create the insight
829
+ create_insight({
830
+ name: 'High Priority Overdue Tasks',
831
+ sources: [...], // Same as preview
832
+ query: '...' // Same as preview
833
+ })
834
+ ```
835
+
836
+ ### Scenario 2: Modify Existing Insight
837
+
838
+ ```javascript
839
+ // Goal: Update insight to include status field
840
+
841
+ // Step 1: Preview with new field
842
+ preview_insight({
843
+ insightId: 'existing-insight-id', // Optional: reference existing
844
+ sources: [{
845
+ name: 'tasks',
846
+ workflowId: 'tasks-workflow-id',
847
+ fields: [
848
+ { name: 'title', meta: 'name' },
849
+ { name: 'priority', fieldId: 'priority-field-id' },
850
+ { name: 'status', meta: 'phase' } // New field
851
+ ]
852
+ }],
853
+ query: `
854
+ SELECT title, priority, status
855
+ FROM tasks
856
+ WHERE priority = 'High'
857
+ `
858
+ })
859
+ // โœ… Works? Update insight.
860
+
861
+ // Step 2: Update insight (use update_insight if available)
862
+ // Or remove and recreate with new query
863
+ ```
864
+
865
+ ### Scenario 3: Debug Broken Insight
866
+
867
+ ```javascript
868
+ // Goal: Fix insight that's returning errors
869
+
870
+ // Step 1: Get insight definition
871
+ const insights = list_insights()
872
+ const broken = insights.find(i => i.name === 'Broken Report')
873
+
874
+ // Step 2: Preview with same query
875
+ preview_insight({
876
+ sources: broken.sources,
877
+ query: broken.query
878
+ })
879
+ // โŒ Error? Now you can debug interactively.
880
+
881
+ // Step 3: Simplify query to find issue
882
+ preview_insight({
883
+ sources: broken.sources,
884
+ query: 'SELECT * FROM tasks LIMIT 5'
885
+ })
886
+ // โœ… Works? Issue is in complex query logic.
887
+
888
+ // Step 4: Add back complexity piece by piece
889
+ // ... debug until you find the problem
890
+ ```
891
+
892
+ ### Scenario 4: Test Performance
893
+
894
+ ```javascript
895
+ // Goal: Ensure query performs well on sample data
896
+
897
+ // Test 1: Simple query (should be fast)
898
+ preview_insight({
899
+ sources: [{
900
+ name: 'tasks',
901
+ workflowId: 'tasks-workflow-id',
902
+ fields: [{ name: 'title', meta: 'name' }]
903
+ }],
904
+ query: 'SELECT title FROM tasks'
905
+ })
906
+ // Note: Response time
907
+
908
+ // Test 2: Complex query (might be slower)
909
+ preview_insight({
910
+ sources: [
911
+ { name: 'tasks', ... },
912
+ { name: 'projects', ... },
913
+ { name: 'teams', ... }
914
+ ],
915
+ query: `
916
+ SELECT ...
917
+ FROM tasks t
918
+ JOIN projects p ON t.projectId = p.id
919
+ JOIN teams tm ON p.teamId = tm.id
920
+ WHERE ...
921
+ GROUP BY ...
922
+ ORDER BY ...
923
+ `
924
+ })
925
+ // Note: Response time (if slow on sample, will be very slow on full data)
926
+ ```
927
+
928
+ ## Performance Considerations
929
+
930
+ ### Preview Performance
931
+
932
+ **Preview is fast because:**
933
+ - Limited to ~20 activities per source
934
+ - No data persistence
935
+ - Simple validation
936
+ - Quick response
937
+
938
+ **Even preview can be slow if:**
939
+ - Many sources (complex JOINs)
940
+ - Complex aggregations
941
+ - Large result set (many columns)
942
+ - Server overloaded
943
+
944
+ ### Optimizing Queries
945
+
946
+ **Fast queries:**
947
+ ```sql
948
+ SELECT title, priority FROM tasks LIMIT 10
949
+ SELECT COUNT(*) FROM tasks
950
+ SELECT * FROM tasks WHERE status = 'Open'
951
+ ```
952
+
953
+ **Slower queries:**
954
+ ```sql
955
+ -- Many JOINs
956
+ SELECT * FROM t1 JOIN t2 JOIN t3 JOIN t4 JOIN t5
957
+
958
+ -- Complex aggregations
959
+ SELECT a, b, c, COUNT(*), SUM(x), AVG(y), MIN(z), MAX(w)
960
+ FROM tasks
961
+ GROUP BY a, b, c
962
+ HAVING COUNT(*) > 10
963
+
964
+ -- String operations
965
+ SELECT title || ' - ' || description || ' - ' || notes FROM tasks
966
+ ```
967
+
968
+ ## Best Practices
969
+
970
+ ### 1. Always Preview Before Creating
971
+
972
+ **Bad:**
973
+ ```javascript
974
+ // Create without testing
975
+ create_insight({
976
+ name: 'Report',
977
+ sources: [...],
978
+ query: 'SELECT ...' // Hope it works!
979
+ })
980
+ // โŒ Fails, have to debug and recreate
981
+ ```
982
+
983
+ **Good:**
984
+ ```javascript
985
+ // Preview first
986
+ preview_insight({
987
+ sources: [...],
988
+ query: 'SELECT ...'
989
+ })
990
+ // โœ… Works!
991
+
992
+ // Then create
993
+ create_insight({
994
+ name: 'Report',
995
+ sources: [...],
996
+ query: 'SELECT ...'
997
+ })
998
+ ```
999
+
1000
+ ### 2. Start Simple, Build Complexity
1001
+
1002
+ ```javascript
1003
+ // Step 1: Basic SELECT
1004
+ preview_insight({ query: 'SELECT * FROM tasks' })
1005
+
1006
+ // Step 2: Specific columns
1007
+ preview_insight({ query: 'SELECT title, priority FROM tasks' })
1008
+
1009
+ // Step 3: Add filter
1010
+ preview_insight({ query: 'SELECT title, priority FROM tasks WHERE priority = "High"' })
1011
+
1012
+ // Step 4: Add sorting
1013
+ preview_insight({ query: 'SELECT title, priority FROM tasks WHERE priority = "High" ORDER BY title' })
1014
+ ```
1015
+
1016
+ ### 3. Use LIMIT During Testing
1017
+
1018
+ ```javascript
1019
+ // Good: Limited results for fast testing
1020
+ preview_insight({
1021
+ sources: [...],
1022
+ query: 'SELECT * FROM tasks LIMIT 5'
1023
+ })
1024
+
1025
+ // Then remove LIMIT when creating
1026
+ create_insight({
1027
+ sources: [...],
1028
+ query: 'SELECT * FROM tasks' // Full results
1029
+ })
1030
+ ```
1031
+
1032
+ ### 4. Verify Field Mappings
1033
+
1034
+ ```javascript
1035
+ // Before preview, get field IDs
1036
+ const schema = get_workflow_schema({ workflowId: 'workflow-id' })
1037
+ schema.fields.forEach(f => {
1038
+ if (f.key) {
1039
+ console.log(`${f.key}: ${f._id}`)
1040
+ }
1041
+ })
1042
+
1043
+ // Use correct IDs in preview
1044
+ preview_insight({
1045
+ sources: [{
1046
+ fields: [
1047
+ { name: 'priority', fieldId: 'verified-field-id' }
1048
+ ]
1049
+ }],
1050
+ query: '...'
1051
+ })
1052
+ ```
1053
+
1054
+ ### 5. Test JOINs Independently
1055
+
1056
+ ```javascript
1057
+ // Test each source independently first
1058
+ preview_insight({
1059
+ sources: [{ name: 'tasks', ... }],
1060
+ query: 'SELECT * FROM tasks LIMIT 5'
1061
+ })
1062
+
1063
+ preview_insight({
1064
+ sources: [{ name: 'projects', ... }],
1065
+ query: 'SELECT * FROM projects LIMIT 5'
1066
+ })
1067
+
1068
+ // Then test JOIN
1069
+ preview_insight({
1070
+ sources: [
1071
+ { name: 'tasks', ... },
1072
+ { name: 'projects', ... }
1073
+ ],
1074
+ query: 'SELECT ... FROM tasks JOIN projects ...'
1075
+ })
1076
+ ```
1077
+
1078
+ ### 6. Document Your Iterations
1079
+
1080
+ ```javascript
1081
+ // Keep track of what works
1082
+ console.log('Test 1: Basic query - โœ…')
1083
+ preview_insight({ query: 'SELECT * FROM tasks' })
1084
+
1085
+ console.log('Test 2: With filter - โœ…')
1086
+ preview_insight({ query: 'SELECT * FROM tasks WHERE priority = "High"' })
1087
+
1088
+ console.log('Test 3: With JOIN - โŒ Error: column not found')
1089
+ preview_insight({ query: 'SELECT ... JOIN ...' })
1090
+
1091
+ console.log('Test 4: Fixed JOIN - โœ…')
1092
+ preview_insight({ query: 'SELECT ... LEFT JOIN ...' })
1093
+ ```
1094
+
1095
+ ### 7. Remember Sample Limitation
1096
+
1097
+ ```javascript
1098
+ // Preview only shows ~20 activities
1099
+ preview_insight({
1100
+ sources: [...],
1101
+ query: 'SELECT COUNT(*) FROM tasks'
1102
+ })
1103
+ // Returns: 20 (not actual total!)
1104
+
1105
+ // To see actual count, create insight and use get_insight_data
1106
+ create_insight({ ... })
1107
+ get_insight_data({ insightId: '...' })
1108
+ // Returns: 1523 (actual total)
1109
+ ```
1110
+
1111
+ ## Troubleshooting
1112
+
1113
+ ### Preview Returns No Data
1114
+
1115
+ **Causes:**
1116
+ 1. No activities in workflow
1117
+ 2. WHERE clause too restrictive
1118
+ 3. INNER JOIN eliminates all rows
1119
+
1120
+ **Solutions:**
1121
+
1122
+ ```javascript
1123
+ // 1. Check activity count
1124
+ list_activities({
1125
+ workflowId: 'workflow-id',
1126
+ limit: 1
1127
+ })
1128
+
1129
+ // 2. Remove WHERE clause
1130
+ preview_insight({
1131
+ sources: [...],
1132
+ query: 'SELECT * FROM tasks' // No filter
1133
+ })
1134
+
1135
+ // 3. Use LEFT JOIN
1136
+ preview_insight({
1137
+ sources: [...],
1138
+ query: 'SELECT ... FROM tasks LEFT JOIN projects ...'
1139
+ })
1140
+ ```
1141
+
1142
+ ### Error: "Column not found"
1143
+
1144
+ **Cause:** Field name in query doesn't match source definition.
1145
+
1146
+ **Solution:**
1147
+
1148
+ ```javascript
1149
+ // Field names must match exactly
1150
+ sources: [{
1151
+ fields: [
1152
+ { name: 'taskTitle', meta: 'name' } // Name is 'taskTitle'
1153
+ ]
1154
+ }],
1155
+ query: 'SELECT taskTitle FROM tasks' // Must use 'taskTitle'
1156
+ ```
1157
+
1158
+ ### Error: "Table not found"
1159
+
1160
+ **Cause:** Table name in query doesn't match source name.
1161
+
1162
+ **Solution:**
1163
+
1164
+ ```javascript
1165
+ // Source names must match
1166
+ sources: [{
1167
+ name: 'tasks', // Name is 'tasks'
1168
+ ...
1169
+ }],
1170
+ query: 'SELECT * FROM tasks' // Must use 'tasks'
1171
+ ```
1172
+
1173
+ ### Error: "Permission denied"
1174
+
1175
+ **Cause:** Regular users can't test arbitrary workflow combinations.
1176
+
1177
+ **Solutions:**
1178
+ 1. Use sources from existing insights you have access to
1179
+ 2. Request workspace admin to test
1180
+ 3. Admins can test any sources
1181
+
1182
+ ### Preview Successful But create_insight Fails
1183
+
1184
+ **Cause:** Preview uses sample data; full data may have issues.
1185
+
1186
+ **Solutions:**
1187
+ 1. Check for NULL values in full dataset
1188
+ 2. Verify all activities have required fields
1189
+ 3. Test with get_insight_data after creation
1190
+
1191
+ ## Integration with Other Tools
1192
+
1193
+ ### With create_insight
1194
+
1195
+ Standard workflow:
1196
+
1197
+ ```javascript
1198
+ // 1. Preview
1199
+ preview_insight({
1200
+ sources: [...],
1201
+ query: '...'
1202
+ })
1203
+
1204
+ // 2. Create (use exact same sources and query)
1205
+ create_insight({
1206
+ name: 'My Report',
1207
+ sources: [...], // Same
1208
+ query: '...' // Same
1209
+ })
1210
+ ```
1211
+
1212
+ ### With get_workflow_schema
1213
+
1214
+ Get field IDs for preview:
1215
+
1216
+ ```javascript
1217
+ // 1. Get schema
1218
+ const schema = get_workflow_schema({
1219
+ workflowId: 'workflow-id'
1220
+ })
1221
+
1222
+ // 2. Build field mappings
1223
+ const fields = schema.fields
1224
+ .filter(f => f.key)
1225
+ .map(f => ({
1226
+ name: f.key,
1227
+ fieldId: f._id
1228
+ }))
1229
+
1230
+ // 3. Preview with fields
1231
+ preview_insight({
1232
+ sources: [{
1233
+ workflowId: 'workflow-id',
1234
+ fields: fields
1235
+ }],
1236
+ query: '...'
1237
+ })
1238
+ ```
1239
+
1240
+ ### With list_activities
1241
+
1242
+ Compare results:
1243
+
1244
+ ```javascript
1245
+ // Preview result
1246
+ preview_insight({
1247
+ sources: [...],
1248
+ query: 'SELECT * FROM tasks WHERE priority = "High"'
1249
+ })
1250
+ // Shows ~20 rows
1251
+
1252
+ // Compare with list_activities
1253
+ list_activities({
1254
+ workflowId: 'workflow-id',
1255
+ filters: [{ field: 'priority-field-id', operator: 'eq', value: 'High' }]
1256
+ })
1257
+ // Shows actual count
1258
+ ```
1259
+
1260
+ ## Summary
1261
+
1262
+ **Key Takeaways:**
1263
+ 1. ๐Ÿงช **Test before create** - Always preview queries first
1264
+ 2. ๐Ÿ“Š **Sample data** - Preview shows ~20 activities only
1265
+ 3. โšก **Fast iteration** - Quick feedback loop for development
1266
+ 4. ๐Ÿ” **Debugging tool** - Catch errors before committing
1267
+ 5. ๐Ÿ”’ **Security aware** - Regular users have restrictions
1268
+ 6. ๐Ÿ—๏ธ **Iterative building** - Start simple, add complexity
1269
+ 7. โœ… **Validation** - Verify syntax, fields, JOINs
1270
+
1271
+ **Quick Decision Tree:**
1272
+
1273
+ ```
1274
+ Building an insight?
1275
+ โ”‚
1276
+ โ”œโ”€ Query untested? โ†’ Preview first
1277
+ โ”œโ”€ Getting SQL errors? โ†’ Preview to debug
1278
+ โ”œโ”€ Unsure about JOINs? โ†’ Preview each piece
1279
+ โ”œโ”€ Need full data? โ†’ Create insight, use get_insight_data
1280
+ โ””โ”€ Query works in preview? โ†’ Create insight
1281
+ ```
1282
+
1283
+ ## Additional Resources
1284
+
1285
+ - See `create-insight-skill` for creating insights
1286
+ - See `get-insight-data-skill` for executing insights
1287
+ - See `remove-insight-skill` for deleting insights
1288
+ - See `insight-api` skill for comprehensive Insight API documentation
1289
+ - Use `get_workflow_schema` to find field IDs
1290
+ - Use `list_workflows` to find workflow IDs