@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,446 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zoho-patterns
|
|
3
|
+
description: Zoho platform development patterns covering Creator, Catalyst, Deluge, integrations, and analytics. Core skill for all Zoho development work.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
status: active
|
|
6
|
+
introduced: 1.0.0
|
|
7
|
+
lastUpdated: 2026-01-25
|
|
8
|
+
activation: Any Zoho development task, Creator forms, Catalyst functions, Deluge scripts, Zoho integrations
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Zoho Development Patterns
|
|
12
|
+
|
|
13
|
+
Comprehensive patterns for Zoho Creator, Catalyst, Deluge, and cross-app integrations. This skill is activated for all Zoho platform development tasks.
|
|
14
|
+
|
|
15
|
+
## Platform Constraints (CRITICAL)
|
|
16
|
+
|
|
17
|
+
These hard limits are enforced by the platform and cannot be circumvented:
|
|
18
|
+
|
|
19
|
+
| Constraint | Limit | Workaround |
|
|
20
|
+
|------------|-------|------------|
|
|
21
|
+
| Deluge statement limit | 5,000 per execution | Chunk into multiple functions |
|
|
22
|
+
| `invokeUrl` timeout | 40 seconds | Use Catalyst for long-running |
|
|
23
|
+
| Catalyst Basic I/O | 30 seconds | Move heavy work to Cron/Event |
|
|
24
|
+
| Catalyst Cron/Event | 15 minutes | Paginate, checkpoint progress |
|
|
25
|
+
| Subform row limit | 200 rows | Use separate form for more |
|
|
26
|
+
| OAuth token expiry | 1 hour | Implement refresh, use Connections |
|
|
27
|
+
| Creator audit retention | 1 year | Export to Analytics for archival |
|
|
28
|
+
| File upload size | 50 MB | Use external storage + URL reference |
|
|
29
|
+
| CRM→Books native sync | 2-hour cycle | Trigger sync via API if urgent |
|
|
30
|
+
|
|
31
|
+
### Catalyst-Specific Requirements
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
CRITICAL: context.close() is MANDATORY in ALL Catalyst functions.
|
|
35
|
+
Without it, the function hangs until timeout. ALWAYS use finally block:
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// Your logic
|
|
39
|
+
} finally {
|
|
40
|
+
context.close(); // MANDATORY
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Skill Files Reference
|
|
47
|
+
|
|
48
|
+
| Directory | Focus Area | Key Files |
|
|
49
|
+
|-----------|------------|-----------|
|
|
50
|
+
| `creator/` | Forms, workflows, widgets | form-design.md, workflow-automation.md, widget-integration.md |
|
|
51
|
+
| `catalyst/` | Functions, deployment | function-patterns.md, cron-batch-processing.md, appsail-deployment.md |
|
|
52
|
+
| `deluge/` | Scripting, APIs | syntax-reference.md, error-handling.md, batch-processing.md |
|
|
53
|
+
| `integration/` | Cross-app, OAuth | oauth-token-management.md, cors-proxy-architecture.md |
|
|
54
|
+
| `analytics/` | Dashboards, pipelines | dashboard-patterns.md, zoho-to-bigquery-pipeline.md |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Creator Patterns
|
|
59
|
+
|
|
60
|
+
### Form Hierarchy
|
|
61
|
+
|
|
62
|
+
| Level | Purpose | Relationship |
|
|
63
|
+
|-------|---------|--------------|
|
|
64
|
+
| Parent form | Core entity (Customers, Projects) | Standalone |
|
|
65
|
+
| Child form | Related record (Invoices) | Lookup field to parent |
|
|
66
|
+
| Subform | Inline 1:N data (Line Items) | Embedded, max 200 rows |
|
|
67
|
+
|
|
68
|
+
**When to Use Subforms vs. Separate Forms:**
|
|
69
|
+
|
|
70
|
+
| Use Subform | Use Separate Form |
|
|
71
|
+
|-------------|-------------------|
|
|
72
|
+
| Items always viewed with parent | Records accessed independently |
|
|
73
|
+
| Under 50 rows typical (200 max) | Could grow to thousands |
|
|
74
|
+
| No complex workflows on items | Needs own workflows/blueprints |
|
|
75
|
+
|
|
76
|
+
### Field Types Quick Reference
|
|
77
|
+
|
|
78
|
+
| Type | Use For | Avoid When |
|
|
79
|
+
|------|---------|------------|
|
|
80
|
+
| Single Line | Names, short text, IDs | > 255 characters |
|
|
81
|
+
| Multi Line | Notes, descriptions | Need rich formatting |
|
|
82
|
+
| Rich Text | Formatted content | Simple text (heavy storage) |
|
|
83
|
+
| Number | Integers, quantities | Decimal values needed |
|
|
84
|
+
| Decimal | Currency, rates | Integer-only values |
|
|
85
|
+
| Lookup | Relationships | Storing IDs as text |
|
|
86
|
+
| Formula | Computed values | User needs to edit |
|
|
87
|
+
| Subform | Inline related records | > 200 rows expected |
|
|
88
|
+
|
|
89
|
+
### HIPAA-Compliant Forms
|
|
90
|
+
|
|
91
|
+
When `CLOUDSTREAM_COMPLIANCE_MODE=hipaa`, apply to forms with ePHI:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Field: Patient_Name [PHI]
|
|
95
|
+
- Help Text: "[PHI] Patient's full legal name"
|
|
96
|
+
- Encryption: ENABLED
|
|
97
|
+
- Access: Minimum necessary roles
|
|
98
|
+
- Audit: ON (log all reads/writes)
|
|
99
|
+
- Reports: HIDDEN by default
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**HIPAA Form Rules:**
|
|
103
|
+
1. Add `[PHI]` prefix to help text of every ePHI field
|
|
104
|
+
2. Enable field-level encryption for all ePHI fields
|
|
105
|
+
3. Set field permissions to minimum necessary roles
|
|
106
|
+
4. Hide ePHI from all reports by default
|
|
107
|
+
5. Never include ePHI in email notifications
|
|
108
|
+
|
|
109
|
+
→ See [creator/form-design.md](creator/form-design.md) for complete patterns
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Catalyst Patterns
|
|
114
|
+
|
|
115
|
+
### Function Types
|
|
116
|
+
|
|
117
|
+
| Type | Timeout | Trigger | Use Case |
|
|
118
|
+
|------|---------|---------|----------|
|
|
119
|
+
| Basic I/O | 30 sec | HTTP (SDK) | CRUD endpoints, widget backends |
|
|
120
|
+
| Cron | 15 min | Schedule | Batch syncs, archival, reports |
|
|
121
|
+
| Event | 15 min | Table/file ops | Post-processing, notifications |
|
|
122
|
+
| AppSail | Unlimited | HTTP | Long-running, full web apps |
|
|
123
|
+
|
|
124
|
+
### Basic I/O Pattern
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
module.exports = async (context, basicIO) => {
|
|
128
|
+
const catalyst = require('zcatalyst-sdk-node');
|
|
129
|
+
const app = catalyst.initialize(context);
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const input = JSON.parse(basicIO.getArgument('data') || '{}');
|
|
133
|
+
|
|
134
|
+
// Your business logic here
|
|
135
|
+
const result = await processRequest(app, input);
|
|
136
|
+
|
|
137
|
+
basicIO.write(JSON.stringify({ status: 'success', data: result }));
|
|
138
|
+
} catch (error) {
|
|
139
|
+
basicIO.write(JSON.stringify({ status: 'error', message: error.message }));
|
|
140
|
+
} finally {
|
|
141
|
+
context.close(); // MANDATORY
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Cron Pattern (Paginated Sync)
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
module.exports = async (cronDetails, context) => {
|
|
150
|
+
const startTime = Date.now();
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
let hasMore = true;
|
|
154
|
+
while (hasMore) {
|
|
155
|
+
// Check timeout (leave 2 min buffer)
|
|
156
|
+
if (Date.now() - startTime > 13 * 60 * 1000) {
|
|
157
|
+
console.log('Approaching timeout - stopping');
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Process batch...
|
|
162
|
+
hasMore = await processBatch();
|
|
163
|
+
}
|
|
164
|
+
} finally {
|
|
165
|
+
context.close(); // MANDATORY
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### AppSail Requirements
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
// MUST bind to process.env.PORT (Catalyst requirement)
|
|
174
|
+
const PORT = process.env.PORT || 9000;
|
|
175
|
+
app.listen(PORT, () => console.log(`Running on ${PORT}`));
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
→ See [catalyst/function-patterns.md](catalyst/function-patterns.md) for complete examples
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Deluge Patterns
|
|
183
|
+
|
|
184
|
+
### Data Types
|
|
185
|
+
|
|
186
|
+
`TEXT`, `NUMBER`, `DECIMAL`, `BOOLEAN`, `DATE`, `DATETIME`, `LIST`, `MAP`, `FILE`, `JSON`
|
|
187
|
+
|
|
188
|
+
### Common Operations
|
|
189
|
+
|
|
190
|
+
```deluge
|
|
191
|
+
// CREATE record
|
|
192
|
+
newRecord = zoho.creator.createRecord("app", "Form_Name", dataMap);
|
|
193
|
+
|
|
194
|
+
// READ with pagination
|
|
195
|
+
records = zoho.creator.getRecords("app", "Report_Name", criteria, 1, 200);
|
|
196
|
+
|
|
197
|
+
// UPDATE record
|
|
198
|
+
zoho.creator.updateRecord("app", "Form_Name", recordId, updateMap);
|
|
199
|
+
|
|
200
|
+
// DELETE record
|
|
201
|
+
zoho.creator.deleteRecord("app", "Form_Name", recordId);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### CRM Operations
|
|
205
|
+
|
|
206
|
+
```deluge
|
|
207
|
+
// Get records
|
|
208
|
+
records = zoho.crm.getRecords("Contacts", criteria, 1, 200);
|
|
209
|
+
|
|
210
|
+
// Search records
|
|
211
|
+
results = zoho.crm.searchRecords("Contacts", "(Email:equals:" + email + ")");
|
|
212
|
+
|
|
213
|
+
// Create record
|
|
214
|
+
newId = zoho.crm.createRecord("Deals", dataMap);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Error Handling Pattern
|
|
218
|
+
|
|
219
|
+
```deluge
|
|
220
|
+
try
|
|
221
|
+
{
|
|
222
|
+
result = zoho.crm.getRecordById("Deals", dealId);
|
|
223
|
+
if (result == null)
|
|
224
|
+
{
|
|
225
|
+
return {"status": "error", "code": "NOT_FOUND"};
|
|
226
|
+
}
|
|
227
|
+
return {"status": "success", "data": result};
|
|
228
|
+
}
|
|
229
|
+
catch (e)
|
|
230
|
+
{
|
|
231
|
+
// Log to Error_Logs form
|
|
232
|
+
logError("CRM_ERROR", e.toString(), "getDeal", "Error", dealId);
|
|
233
|
+
return {"status": "error", "message": e.toString()};
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Validation Pattern
|
|
238
|
+
|
|
239
|
+
```deluge
|
|
240
|
+
errors = List();
|
|
241
|
+
|
|
242
|
+
if (input.Customer_Name == null || input.Customer_Name == "")
|
|
243
|
+
{
|
|
244
|
+
errors.add("Customer name is required");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (input.Amount == null || input.Amount <= 0)
|
|
248
|
+
{
|
|
249
|
+
errors.add("Amount must be greater than zero");
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (errors.size() > 0)
|
|
253
|
+
{
|
|
254
|
+
cancel submit;
|
|
255
|
+
alert errors.toString("\n");
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
→ See [deluge/syntax-reference.md](deluge/syntax-reference.md) and [deluge/error-handling.md](deluge/error-handling.md)
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Integration Patterns
|
|
264
|
+
|
|
265
|
+
### OAuth Token Management
|
|
266
|
+
|
|
267
|
+
**Zoho Access Token Lifecycle:**
|
|
268
|
+
```
|
|
269
|
+
Auth Code (10 min TTL) → Access Token (1 hour TTL) → Refresh Token (no expiry)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Preferred: Use Connections (auto-refresh)**
|
|
273
|
+
|
|
274
|
+
```deluge
|
|
275
|
+
response = invokeUrl [
|
|
276
|
+
url: "https://www.zohoapis.com/crm/v5/Deals"
|
|
277
|
+
type: GET
|
|
278
|
+
connection: "zoho-crm-connection" // Handles refresh automatically
|
|
279
|
+
];
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Standalone Apps: Manual Refresh**
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
class ZohoTokenManager {
|
|
286
|
+
async getAccessToken() {
|
|
287
|
+
// Refresh proactively at 50 minutes
|
|
288
|
+
const bufferMs = 10 * 60 * 1000;
|
|
289
|
+
if (this.accessToken && Date.now() < this.expiresAt - bufferMs) {
|
|
290
|
+
return this.accessToken;
|
|
291
|
+
}
|
|
292
|
+
// Refresh logic...
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Multi-DC Support
|
|
298
|
+
|
|
299
|
+
| DC | Accounts URL | API Domain | Region |
|
|
300
|
+
|----|--------------|------------|--------|
|
|
301
|
+
| com | accounts.zoho.com | zohoapis.com | US |
|
|
302
|
+
| eu | accounts.zoho.eu | zohoapis.eu | Europe |
|
|
303
|
+
| in | accounts.zoho.in | zohoapis.in | India |
|
|
304
|
+
| com.au | accounts.zoho.com.au | zohoapis.com.au | Australia |
|
|
305
|
+
|
|
306
|
+
**Per-Client Token Management:**
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
// Each client has separate OAuth app - NEVER share tokens
|
|
310
|
+
const zoho = new ZohoTokenManager(
|
|
311
|
+
process.env.ZOHO_CLIENT_ID,
|
|
312
|
+
process.env.ZOHO_CLIENT_SECRET,
|
|
313
|
+
process.env.ZOHO_REFRESH_TOKEN,
|
|
314
|
+
process.env.ZOHO_DC || "com"
|
|
315
|
+
);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Token Storage Rules
|
|
319
|
+
|
|
320
|
+
| ✅ Safe Storage | ❌ Never Store In |
|
|
321
|
+
|-----------------|-------------------|
|
|
322
|
+
| Catalyst Segments | Deluge variables |
|
|
323
|
+
| Environment variables | Git repos (even private) |
|
|
324
|
+
| GCP Secret Manager | Client-side JS |
|
|
325
|
+
| .env file (gitignored) | Log files |
|
|
326
|
+
|
|
327
|
+
→ See [integration/oauth-token-management.md](integration/oauth-token-management.md)
|
|
328
|
+
|
|
329
|
+
### CORS Proxy (for Widgets)
|
|
330
|
+
|
|
331
|
+
Creator widgets cannot call external APIs directly. Use Catalyst AppSail:
|
|
332
|
+
|
|
333
|
+
```javascript
|
|
334
|
+
// AppSail CORS proxy
|
|
335
|
+
app.post('/api/proxy', async (req, res) => {
|
|
336
|
+
const { url, method, headers, body } = req.body;
|
|
337
|
+
|
|
338
|
+
// Whitelist allowed domains
|
|
339
|
+
const allowedDomains = ['api.stripe.com', 'api.sendgrid.com'];
|
|
340
|
+
if (!allowedDomains.includes(new URL(url).hostname)) {
|
|
341
|
+
return res.status(403).json({ error: 'Domain not whitelisted' });
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const response = await fetch(url, { method, headers, body });
|
|
345
|
+
res.json(await response.json());
|
|
346
|
+
});
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
→ See [integration/cors-proxy-architecture.md](integration/cors-proxy-architecture.md)
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Analytics Patterns
|
|
354
|
+
|
|
355
|
+
### Report Types
|
|
356
|
+
|
|
357
|
+
| Type | Best For |
|
|
358
|
+
|------|----------|
|
|
359
|
+
| Chart | Trends, comparisons |
|
|
360
|
+
| Pivot Table | Multi-dimensional analysis |
|
|
361
|
+
| KPI Widget | Single metric display |
|
|
362
|
+
| Dashboard | Combined executive views |
|
|
363
|
+
| Tabular | Detailed listings, audit trails |
|
|
364
|
+
|
|
365
|
+
### SQL Queries in Analytics
|
|
366
|
+
|
|
367
|
+
```sql
|
|
368
|
+
-- Revenue by month
|
|
369
|
+
SELECT
|
|
370
|
+
YEAR("Invoice_Date") AS year,
|
|
371
|
+
MONTH("Invoice_Date") AS month,
|
|
372
|
+
SUM("Amount") AS total_revenue
|
|
373
|
+
FROM "Invoices"
|
|
374
|
+
WHERE "Status" = 'Paid'
|
|
375
|
+
GROUP BY YEAR("Invoice_Date"), MONTH("Invoice_Date")
|
|
376
|
+
ORDER BY year DESC, month DESC
|
|
377
|
+
|
|
378
|
+
-- Customer lifetime value
|
|
379
|
+
SELECT
|
|
380
|
+
"Customer_Name",
|
|
381
|
+
SUM("Amount") AS lifetime_value,
|
|
382
|
+
COUNT("Invoice_ID") AS total_invoices
|
|
383
|
+
FROM "Invoices"
|
|
384
|
+
GROUP BY "Customer_Name"
|
|
385
|
+
HAVING SUM("Amount") > 1000
|
|
386
|
+
ORDER BY lifetime_value DESC
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Embedding Analytics in Creator
|
|
390
|
+
|
|
391
|
+
```html
|
|
392
|
+
<iframe
|
|
393
|
+
src="https://analytics.zoho.com/open-view/{workspace}/{view}?ZOHO_CRITERIA=%22Status%22%3D%27Active%27"
|
|
394
|
+
width="100%"
|
|
395
|
+
height="500">
|
|
396
|
+
</iframe>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Row-Level Security
|
|
400
|
+
|
|
401
|
+
```sql
|
|
402
|
+
-- Sales reps: only their own data
|
|
403
|
+
"Owner_Email" = ZOHO_LOGINUSER_EMAIL
|
|
404
|
+
|
|
405
|
+
-- Managers: their team's data
|
|
406
|
+
"Team" = ZOHO_LOGINUSER_ROLE
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
→ See [analytics/dashboard-patterns.md](analytics/dashboard-patterns.md)
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## Common Mistakes
|
|
414
|
+
|
|
415
|
+
| Mistake | Consequence | Fix |
|
|
416
|
+
|---------|-------------|-----|
|
|
417
|
+
| Missing `context.close()` | Function hangs until timeout | Always use `finally` block |
|
|
418
|
+
| Not binding to `PORT` | AppSail container fails | `app.listen(process.env.PORT)` |
|
|
419
|
+
| Exceeding 30s in I/O | Request timeout (504) | Use Cron/Event function |
|
|
420
|
+
| Hardcoded tokens | Security vulnerability | Use Connections or env vars |
|
|
421
|
+
| Over-scoped OAuth | Security risk | Minimum necessary scopes |
|
|
422
|
+
| Ignoring DC | Wrong API domain | Detect from client config |
|
|
423
|
+
| Subform > 200 rows | Data loss | Use separate form |
|
|
424
|
+
| No error logging | Silent failures | Log to Error_Logs form |
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Related Skills
|
|
429
|
+
|
|
430
|
+
| Skill | When Used Together |
|
|
431
|
+
|-------|-------------------|
|
|
432
|
+
| [compliance-patterns](../compliance-patterns/) | HIPAA/SOC2 forms and data handling |
|
|
433
|
+
| [bigquery-patterns](../bigquery-patterns/) | Zoho Analytics → BigQuery pipelines |
|
|
434
|
+
| [backend-patterns](../backend-patterns/) | Catalyst function architecture |
|
|
435
|
+
| [gcp-data-engineering](../gcp-data-engineering/) | Data warehouse integration |
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Quick Command Reference
|
|
440
|
+
|
|
441
|
+
| Command | Purpose |
|
|
442
|
+
|---------|---------|
|
|
443
|
+
| `/zoho-scaffold` | Generate Creator app, Catalyst function, or Widget |
|
|
444
|
+
| `/deluge` | Generate or fix Deluge script |
|
|
445
|
+
| `/compliance-check` | Audit Zoho forms for compliance |
|
|
446
|
+
| `/code-review` | Review Deluge and Catalyst code |
|