@cloudstreamsoftware/claude-tools 1.0.0 → 1.2.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/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/bin/cloudstream-setup.js +16 -6
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# Creator Widget Integration
|
|
2
|
+
|
|
3
|
+
## Critical Constraints
|
|
4
|
+
|
|
5
|
+
> **WARNING:** Widgets do NOT work on published pages. If you need external user interaction, use the Publish API instead (see publish-api-patterns.md).
|
|
6
|
+
|
|
7
|
+
> **LIMIT:** Maximum 50 widgets per Creator application.
|
|
8
|
+
|
|
9
|
+
## Widget Initialization
|
|
10
|
+
|
|
11
|
+
Every widget MUST call `ZOHO.CREATOR.init()` before any other API calls:
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// Widget entry point - ALWAYS starts here
|
|
15
|
+
ZOHO.CREATOR.init().then(function() {
|
|
16
|
+
console.log("Widget initialized successfully");
|
|
17
|
+
loadWidgetData();
|
|
18
|
+
}).catch(function(error) {
|
|
19
|
+
console.error("Widget init failed:", error);
|
|
20
|
+
document.getElementById("app").innerHTML =
|
|
21
|
+
"<div class='error'>Widget failed to load. Please refresh.</div>";
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## JS API v1 vs v2 Differences
|
|
26
|
+
|
|
27
|
+
| Feature | v1 (Legacy) | v2 (Current) |
|
|
28
|
+
|---------|-------------|--------------|
|
|
29
|
+
| Initialization | `ZDK.Page.getForm()` | `ZOHO.CREATOR.init()` |
|
|
30
|
+
| Get record | `ZDK.Page.getRecord()` | `ZOHO.CREATOR.DATA.getRecord()` |
|
|
31
|
+
| Create record | `ZDK.Apps.CRM.createRecord()` | `ZOHO.CREATOR.DATA.createRecord()` |
|
|
32
|
+
| Event handling | Callback-based | Promise-based |
|
|
33
|
+
| Widget context | Limited | Full form/record context |
|
|
34
|
+
| SDK location | Self-hosted | `https://js.zohostatic.com/creator/widgets/version/widgetsdk-min.js` |
|
|
35
|
+
|
|
36
|
+
> **WARNING:** v1 API is deprecated. All new widgets MUST use v2. Migrate existing v1 widgets when modifying them.
|
|
37
|
+
|
|
38
|
+
## Widget-to-Form Communication
|
|
39
|
+
|
|
40
|
+
### Reading Current Record Data
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
ZOHO.CREATOR.init().then(function() {
|
|
44
|
+
// Get the current record context
|
|
45
|
+
ZOHO.CREATOR.UTIL.getInitParams().then(function(params) {
|
|
46
|
+
var recordId = params.record_id;
|
|
47
|
+
var formName = params.form_link_name;
|
|
48
|
+
var appName = params.app_link_name;
|
|
49
|
+
|
|
50
|
+
if (recordId) {
|
|
51
|
+
// Editing existing record - fetch data
|
|
52
|
+
ZOHO.CREATOR.DATA.getRecordById({
|
|
53
|
+
appName: appName,
|
|
54
|
+
formName: formName,
|
|
55
|
+
id: recordId
|
|
56
|
+
}).then(function(response) {
|
|
57
|
+
var record = response.data;
|
|
58
|
+
populateWidget(record);
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
// New record context
|
|
62
|
+
initNewRecordWidget();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Writing Data Back to Form
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
// Update a field in the parent form
|
|
72
|
+
function updateFormField(fieldName, value) {
|
|
73
|
+
ZOHO.CREATOR.UTIL.setFieldValue(fieldName, value)
|
|
74
|
+
.then(function(response) {
|
|
75
|
+
console.log("Field updated:", fieldName, "=", value);
|
|
76
|
+
})
|
|
77
|
+
.catch(function(error) {
|
|
78
|
+
console.error("Failed to update field:", error);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Set multiple fields at once
|
|
83
|
+
function updateMultipleFields(fieldMap) {
|
|
84
|
+
var promises = [];
|
|
85
|
+
for (var field in fieldMap) {
|
|
86
|
+
promises.push(
|
|
87
|
+
ZOHO.CREATOR.UTIL.setFieldValue(field, fieldMap[field])
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
Promise.all(promises).then(function() {
|
|
91
|
+
console.log("All fields updated");
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Navigating Between Records
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// Open another record in a new tab
|
|
100
|
+
function openRelatedRecord(appName, formName, recordId) {
|
|
101
|
+
ZOHO.CREATOR.UTIL.navigateTo({
|
|
102
|
+
appName: appName,
|
|
103
|
+
formName: formName,
|
|
104
|
+
recordId: recordId,
|
|
105
|
+
target: "_blank"
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Passing Parameters to Widgets
|
|
111
|
+
|
|
112
|
+
### Via URL Parameters (Widget Configuration)
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// In widget settings, set URL params: ?mode=edit&type=invoice
|
|
116
|
+
ZOHO.CREATOR.init().then(function() {
|
|
117
|
+
var urlParams = new URLSearchParams(window.location.search);
|
|
118
|
+
var mode = urlParams.get("mode") || "view";
|
|
119
|
+
var type = urlParams.get("type") || "default";
|
|
120
|
+
|
|
121
|
+
initWidget(mode, type);
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Via Form Field Values
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
// Read a hidden field that stores config JSON
|
|
129
|
+
ZOHO.CREATOR.init().then(function() {
|
|
130
|
+
ZOHO.CREATOR.UTIL.getFieldValue("Widget_Config")
|
|
131
|
+
.then(function(response) {
|
|
132
|
+
var config = JSON.parse(response.value || "{}");
|
|
133
|
+
applyConfiguration(config);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Widget Sizing and Responsive Design
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<!DOCTYPE html>
|
|
142
|
+
<html>
|
|
143
|
+
<head>
|
|
144
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
145
|
+
<style>
|
|
146
|
+
/* Widget container - respect Creator's iframe constraints */
|
|
147
|
+
body {
|
|
148
|
+
margin: 0;
|
|
149
|
+
padding: 8px;
|
|
150
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
151
|
+
font-size: 13px;
|
|
152
|
+
overflow-x: hidden;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.widget-container {
|
|
156
|
+
width: 100%;
|
|
157
|
+
max-width: 100%;
|
|
158
|
+
box-sizing: border-box;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Resize widget height dynamically */
|
|
162
|
+
.auto-height {
|
|
163
|
+
min-height: 100px;
|
|
164
|
+
max-height: 600px;
|
|
165
|
+
overflow-y: auto;
|
|
166
|
+
}
|
|
167
|
+
</style>
|
|
168
|
+
</head>
|
|
169
|
+
<body>
|
|
170
|
+
<div class="widget-container auto-height" id="app">
|
|
171
|
+
<!-- Widget content -->
|
|
172
|
+
</div>
|
|
173
|
+
<script src="https://js.zohostatic.com/creator/widgets/1.0/widgetsdk-min.js"></script>
|
|
174
|
+
<script src="app.js"></script>
|
|
175
|
+
</body>
|
|
176
|
+
</html>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Resizing Widget Iframe Dynamically
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
// Notify Creator to resize the widget iframe
|
|
183
|
+
function resizeWidget(height) {
|
|
184
|
+
ZOHO.CREATOR.UTIL.resize({
|
|
185
|
+
height: height + "px"
|
|
186
|
+
}).then(function() {
|
|
187
|
+
console.log("Widget resized to", height);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Auto-resize based on content
|
|
192
|
+
function autoResize() {
|
|
193
|
+
var contentHeight = document.getElementById("app").scrollHeight;
|
|
194
|
+
resizeWidget(Math.min(contentHeight + 20, 800)); // Cap at 800px
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## CORS Handling for API Calls from Widgets
|
|
199
|
+
|
|
200
|
+
> **WARNING:** Widgets run in an iframe. Direct API calls to external services will be blocked by CORS. Use one of these patterns:
|
|
201
|
+
|
|
202
|
+
### Pattern 1: Catalyst Proxy (Recommended)
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
// Widget calls Catalyst function which calls external API
|
|
206
|
+
async function fetchExternalData(endpoint, params) {
|
|
207
|
+
try {
|
|
208
|
+
// Call your Catalyst function (same Zoho domain = no CORS issue)
|
|
209
|
+
var response = await ZOHO.CREATOR.DATA.invokeFunction({
|
|
210
|
+
appName: "my-app",
|
|
211
|
+
functionName: "proxy_external_api",
|
|
212
|
+
data: {
|
|
213
|
+
endpoint: endpoint,
|
|
214
|
+
params: JSON.stringify(params)
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
return JSON.parse(response.data);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error("Proxy call failed:", error);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Pattern 2: Zoho Creator Custom Function Proxy
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
// Call a Deluge custom function that makes the external call
|
|
229
|
+
async function callViaDeluge(apiUrl, method, body) {
|
|
230
|
+
var response = await ZOHO.CREATOR.DATA.invokeFunction({
|
|
231
|
+
appName: "my-app",
|
|
232
|
+
functionName: "external_api_proxy",
|
|
233
|
+
data: {
|
|
234
|
+
url: apiUrl,
|
|
235
|
+
method: method,
|
|
236
|
+
body: JSON.stringify(body)
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
return response;
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Supporting Deluge Function
|
|
244
|
+
|
|
245
|
+
```deluge
|
|
246
|
+
// Custom function: external_api_proxy
|
|
247
|
+
// Arguments: url (TEXT), method (TEXT), body (TEXT)
|
|
248
|
+
|
|
249
|
+
response = invokeUrl [
|
|
250
|
+
url: url
|
|
251
|
+
type: if(method == "POST", POST, if(method == "PUT", PUT, GET))
|
|
252
|
+
headers: {"Content-Type": "application/json"}
|
|
253
|
+
body: body
|
|
254
|
+
connection: "external-api-connection"
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
return response.toString();
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Debugging Widget Load Failures
|
|
261
|
+
|
|
262
|
+
| Symptom | Cause | Solution |
|
|
263
|
+
|---------|-------|----------|
|
|
264
|
+
| Blank iframe | SDK not loaded | Verify SDK URL is accessible, check network tab |
|
|
265
|
+
| "init() failed" | Wrong SDK version | Match SDK version to your Creator plan |
|
|
266
|
+
| Fields not updating | Wrong field link name | Use link names (underscored), not display names |
|
|
267
|
+
| Widget shows in edit but not list | Widget placement config | Reconfigure widget placement in form settings |
|
|
268
|
+
| CORS errors in console | Direct external API call | Route through Catalyst proxy (see above) |
|
|
269
|
+
| Widget loads slowly | Large bundle size | Code-split, lazy-load non-critical components |
|
|
270
|
+
| Data not refreshing | Cached API responses | Add timestamp parameter to API calls |
|
|
271
|
+
|
|
272
|
+
### Debug Mode Pattern
|
|
273
|
+
|
|
274
|
+
```javascript
|
|
275
|
+
var DEBUG = window.location.search.includes("debug=true");
|
|
276
|
+
|
|
277
|
+
function debugLog(label, data) {
|
|
278
|
+
if (DEBUG) {
|
|
279
|
+
console.log("[Widget Debug]", label, JSON.stringify(data, null, 2));
|
|
280
|
+
// Also render to page for mobile debugging
|
|
281
|
+
var debugDiv = document.getElementById("debug-output");
|
|
282
|
+
if (debugDiv) {
|
|
283
|
+
debugDiv.innerHTML += "<pre>" + label + ": " +
|
|
284
|
+
JSON.stringify(data, null, 2) + "</pre>";
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
ZOHO.CREATOR.init().then(function() {
|
|
290
|
+
debugLog("Init", { status: "success", timestamp: new Date().toISOString() });
|
|
291
|
+
|
|
292
|
+
ZOHO.CREATOR.UTIL.getInitParams().then(function(params) {
|
|
293
|
+
debugLog("Params", params);
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Widget Development Workflow
|
|
299
|
+
|
|
300
|
+
1. **Local Development:** Use `http://localhost:3000` with mock Zoho SDK
|
|
301
|
+
2. **Upload to Creator:** Settings > Widgets > Upload ZIP (index.html at root)
|
|
302
|
+
3. **Test in Form:** Add widget field, open form in edit mode
|
|
303
|
+
4. **Debug:** Use `?debug=true` parameter for verbose logging
|
|
304
|
+
5. **Production:** Remove debug flags, minify JS, test on all target browsers
|
|
305
|
+
|
|
306
|
+
> **REMINDER:** Widgets only work for logged-in Zoho users viewing forms within Creator. For external-facing functionality, use Publish API patterns.
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Creator Workflow Automation
|
|
2
|
+
|
|
3
|
+
## Workflow Execution Order
|
|
4
|
+
|
|
5
|
+
When a record is created or edited, Creator executes automation in this order:
|
|
6
|
+
1. Field validation rules
|
|
7
|
+
2. On-create/edit workflow (Deluge scripts)
|
|
8
|
+
3. Field update rules (form rules)
|
|
9
|
+
4. Blueprint transitions (if applicable)
|
|
10
|
+
5. Approval processes (if triggered)
|
|
11
|
+
6. Scheduled workflows (independent, time-based)
|
|
12
|
+
|
|
13
|
+
> **WARNING:** If a workflow modifies a field that triggers another workflow, infinite loops are possible. Use `input.Trigger_Type` to guard against re-entry.
|
|
14
|
+
|
|
15
|
+
## On-Create / On-Edit Triggers
|
|
16
|
+
|
|
17
|
+
```deluge
|
|
18
|
+
// Workflow: On Create of "Invoice" form
|
|
19
|
+
// Trigger: Record creation
|
|
20
|
+
|
|
21
|
+
// Guard against re-entry from approval/blueprint updates
|
|
22
|
+
if (input.Trigger_Type == "form_submission")
|
|
23
|
+
{
|
|
24
|
+
// Set audit fields
|
|
25
|
+
input.Created_By_Name = zoho.loginuserid;
|
|
26
|
+
input.Created_Date = zoho.currentdate;
|
|
27
|
+
|
|
28
|
+
// Auto-generate invoice number
|
|
29
|
+
lastRecord = zoho.creator.getRecords("billing-app", "All_Invoices", "", 1, 1, "Invoice_Number", "desc");
|
|
30
|
+
if (lastRecord.size() > 0)
|
|
31
|
+
{
|
|
32
|
+
lastNum = lastRecord.get(0).get("Invoice_Number").toLong();
|
|
33
|
+
input.Invoice_Number = lastNum + 1;
|
|
34
|
+
}
|
|
35
|
+
else
|
|
36
|
+
{
|
|
37
|
+
input.Invoice_Number = 10001;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Cross-app notification
|
|
41
|
+
sendmail [
|
|
42
|
+
from: zoho.adminuserid
|
|
43
|
+
to: input.Account_Manager.Email
|
|
44
|
+
subject: "New Invoice Created: INV-" + input.Invoice_Number
|
|
45
|
+
message: "Invoice for " + input.Customer_Name + " - $" + input.Total_Amount
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```deluge
|
|
51
|
+
// Workflow: On Edit of "Project" form
|
|
52
|
+
// Only fire when Status changes
|
|
53
|
+
|
|
54
|
+
if (input.Status != input.Status_previous)
|
|
55
|
+
{
|
|
56
|
+
// Log status change to audit subform
|
|
57
|
+
auditRow = Project_History();
|
|
58
|
+
auditRow.Old_Status = input.Status_previous;
|
|
59
|
+
auditRow.New_Status = input.Status;
|
|
60
|
+
auditRow.Changed_By = zoho.loginuserid;
|
|
61
|
+
auditRow.Changed_Date = zoho.currenttime;
|
|
62
|
+
|
|
63
|
+
// Insert into subform
|
|
64
|
+
input.Project_History.insert(auditRow);
|
|
65
|
+
|
|
66
|
+
// Notify team on completion
|
|
67
|
+
if (input.Status == "Completed")
|
|
68
|
+
{
|
|
69
|
+
teamMembers = zoho.creator.getRecords("pm-app", "Team_Members", "Project == " + input.ID);
|
|
70
|
+
for each member in teamMembers
|
|
71
|
+
{
|
|
72
|
+
sendmail [
|
|
73
|
+
from: zoho.adminuserid
|
|
74
|
+
to: member.get("Email")
|
|
75
|
+
subject: "Project Completed: " + input.Project_Name
|
|
76
|
+
message: "The project has been marked complete."
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Scheduled Workflows
|
|
84
|
+
|
|
85
|
+
```deluge
|
|
86
|
+
// Scheduled: Daily at 6 AM UTC
|
|
87
|
+
// Purpose: Auto-close stale opportunities older than 90 days
|
|
88
|
+
|
|
89
|
+
staleDate = zoho.currentdate.subDay(90);
|
|
90
|
+
criteria = "Stage == \"Negotiation\" && Last_Activity_Date < \"" + staleDate.toString("dd-MMM-yyyy") + "\"";
|
|
91
|
+
staleDeals = zoho.creator.getRecords("sales-app", "All_Deals", criteria, 1, 200);
|
|
92
|
+
|
|
93
|
+
closedCount = 0;
|
|
94
|
+
for each deal in staleDeals
|
|
95
|
+
{
|
|
96
|
+
updateMap = Map();
|
|
97
|
+
updateMap.put("Stage", "Closed Lost");
|
|
98
|
+
updateMap.put("Close_Reason", "Auto-closed: No activity 90+ days");
|
|
99
|
+
zoho.creator.updateRecord("sales-app", "Deals", deal.get("ID").toLong(), updateMap);
|
|
100
|
+
closedCount = closedCount + 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Report results
|
|
104
|
+
if (closedCount > 0)
|
|
105
|
+
{
|
|
106
|
+
sendmail [
|
|
107
|
+
from: zoho.adminuserid
|
|
108
|
+
to: "sales-manager@company.com"
|
|
109
|
+
subject: "Auto-Close Report: " + closedCount + " deals closed"
|
|
110
|
+
message: closedCount + " stale deals auto-closed on " + zoho.currentdate
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Blueprint Configuration
|
|
116
|
+
|
|
117
|
+
Blueprints enforce process stages (e.g., Lead Qualification, Project Delivery):
|
|
118
|
+
|
|
119
|
+
| Component | Purpose | Example |
|
|
120
|
+
|-----------|---------|---------|
|
|
121
|
+
| States | Allowed statuses | Draft, In Review, Approved, Rejected |
|
|
122
|
+
| Transitions | Allowed movements | Draft→In Review, In Review→Approved |
|
|
123
|
+
| Before Transition | Validation script | Check required fields filled |
|
|
124
|
+
| During Transition | Collect input | Rejection reason, approval notes |
|
|
125
|
+
| After Transition | Post-action script | Notify stakeholders, update related records |
|
|
126
|
+
|
|
127
|
+
```deluge
|
|
128
|
+
// Blueprint: Before Transition "Submit for Review"
|
|
129
|
+
// Validate completeness before allowing transition
|
|
130
|
+
|
|
131
|
+
errors = List();
|
|
132
|
+
|
|
133
|
+
if (input.Description.length() < 50)
|
|
134
|
+
{
|
|
135
|
+
errors.add("Description must be at least 50 characters");
|
|
136
|
+
}
|
|
137
|
+
if (input.Attachments.size() == 0)
|
|
138
|
+
{
|
|
139
|
+
errors.add("At least one attachment is required");
|
|
140
|
+
}
|
|
141
|
+
if (input.Estimated_Hours == 0)
|
|
142
|
+
{
|
|
143
|
+
errors.add("Estimated hours must be provided");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (errors.size() > 0)
|
|
147
|
+
{
|
|
148
|
+
cancel submit;
|
|
149
|
+
alert errors.toString(",");
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Approval Processes
|
|
154
|
+
|
|
155
|
+
```deluge
|
|
156
|
+
// Approval: Invoice over $10,000 requires manager approval
|
|
157
|
+
// Criteria: Total_Amount > 10000
|
|
158
|
+
|
|
159
|
+
// On Approve action:
|
|
160
|
+
input.Approval_Status = "Approved";
|
|
161
|
+
input.Approved_By = zoho.loginuserid;
|
|
162
|
+
input.Approved_Date = zoho.currenttime;
|
|
163
|
+
|
|
164
|
+
// Trigger downstream: create Books invoice
|
|
165
|
+
bookData = Map();
|
|
166
|
+
bookData.put("customer_name", input.Customer_Name);
|
|
167
|
+
bookData.put("line_items", input.Line_Items);
|
|
168
|
+
response = zoho.books.createRecord("invoices", "YOUR_ORG_ID", bookData, "zoho-books-connection");
|
|
169
|
+
|
|
170
|
+
// On Reject action:
|
|
171
|
+
input.Approval_Status = "Rejected";
|
|
172
|
+
input.Rejection_Reason = input.Approver_Comments;
|
|
173
|
+
sendmail [
|
|
174
|
+
from: zoho.adminuserid
|
|
175
|
+
to: input.Submitted_By.Email
|
|
176
|
+
subject: "Invoice Rejected: " + input.Invoice_Number
|
|
177
|
+
message: "Reason: " + input.Approver_Comments
|
|
178
|
+
];
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Field Update Rules
|
|
182
|
+
|
|
183
|
+
Field update rules execute WITHOUT triggering on-edit workflows (avoids loops):
|
|
184
|
+
|
|
185
|
+
- Use for: Auto-calculations, status derivations, default values
|
|
186
|
+
- Do NOT use for: Cross-app updates, email notifications, complex logic
|
|
187
|
+
|
|
188
|
+
## Custom Functions in Workflows
|
|
189
|
+
|
|
190
|
+
> **WARNING:** Custom functions share the 5000-statement limit with the calling workflow. If your workflow uses 3000 statements, the custom function only has 2000 remaining.
|
|
191
|
+
|
|
192
|
+
```deluge
|
|
193
|
+
// Custom function: calculateProjectHealth(projectId)
|
|
194
|
+
// Called from workflow after status update
|
|
195
|
+
|
|
196
|
+
projectId = input.projectId;
|
|
197
|
+
tasks = zoho.creator.getRecords("pm-app", "All_Tasks", "Project == " + projectId, 1, 200);
|
|
198
|
+
|
|
199
|
+
totalTasks = tasks.size();
|
|
200
|
+
completedTasks = 0;
|
|
201
|
+
overdueTasks = 0;
|
|
202
|
+
|
|
203
|
+
for each task in tasks
|
|
204
|
+
{
|
|
205
|
+
if (task.get("Status") == "Completed")
|
|
206
|
+
{
|
|
207
|
+
completedTasks = completedTasks + 1;
|
|
208
|
+
}
|
|
209
|
+
if (task.get("Due_Date") < zoho.currentdate && task.get("Status") != "Completed")
|
|
210
|
+
{
|
|
211
|
+
overdueTasks = overdueTasks + 1;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
healthScore = (completedTasks * 100) / totalTasks;
|
|
216
|
+
if (overdueTasks > 3)
|
|
217
|
+
{
|
|
218
|
+
healthScore = healthScore - 20;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
updateMap = Map();
|
|
222
|
+
updateMap.put("Health_Score", healthScore);
|
|
223
|
+
updateMap.put("Health_Status", if(healthScore >= 80, "Green", if(healthScore >= 50, "Yellow", "Red")));
|
|
224
|
+
zoho.creator.updateRecord("pm-app", "Projects", projectId, updateMap);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Debugging Workflow Failures
|
|
228
|
+
|
|
229
|
+
| Symptom | Likely Cause | Fix |
|
|
230
|
+
|---------|--------------|-----|
|
|
231
|
+
| Workflow doesn't fire | Wrong trigger type selected | Check form settings > workflows |
|
|
232
|
+
| Fires multiple times | Edit workflow + field update loop | Add `input.Trigger_Type` guard |
|
|
233
|
+
| Partial execution | 5000 statement limit hit | Split into custom function + scheduled |
|
|
234
|
+
| Null pointer error | Field not available in context | Check field availability per trigger type |
|
|
235
|
+
| Email not sent | Org email limits exceeded | Check Admin > Email usage |
|
|
236
|
+
| Cross-app call fails | Connection expired/wrong scope | Re-authorize connection in settings |
|
|
237
|
+
|
|
238
|
+
### Logging Pattern for Debugging
|
|
239
|
+
|
|
240
|
+
```deluge
|
|
241
|
+
// Add to any workflow for troubleshooting
|
|
242
|
+
logMap = Map();
|
|
243
|
+
logMap.put("Workflow_Name", "Invoice_OnCreate");
|
|
244
|
+
logMap.put("Record_ID", input.ID);
|
|
245
|
+
logMap.put("Trigger_Type", input.Trigger_Type);
|
|
246
|
+
logMap.put("Timestamp", zoho.currenttime);
|
|
247
|
+
logMap.put("User", zoho.loginuserid);
|
|
248
|
+
logMap.put("Details", "Invoice " + input.Invoice_Number + " created");
|
|
249
|
+
|
|
250
|
+
zoho.creator.createRecord("admin-app", "Workflow_Logs", logMap);
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
> **NOTE:** Creator audit logs are only retained for 1 year. For compliance clients (HIPAA/SOC2), implement custom audit archival to a separate form or external store.
|