@cloudstreamsoftware/claude-tools 1.0.0 → 1.1.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/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,356 @@
|
|
|
1
|
+
# Deluge Cross-App Integration
|
|
2
|
+
|
|
3
|
+
## Zoho Ecosystem Data Flow
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
CRM (Sales) ──→ Books (Finance) ──→ Analytics (Reporting)
|
|
7
|
+
↕ ↕ ↑
|
|
8
|
+
Creator (Ops) ──→ Inventory ──────────────→┘
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> **CRITICAL:** CRM-to-Books has a native 2-hour sync cycle. Do NOT rebuild this. See integration/crm-books-native-sync.md for details on when to extend vs replace.
|
|
12
|
+
|
|
13
|
+
## CRM Operations
|
|
14
|
+
|
|
15
|
+
### Get Record by ID
|
|
16
|
+
|
|
17
|
+
```deluge
|
|
18
|
+
// zoho.crm.getRecordById(module, recordId)
|
|
19
|
+
try
|
|
20
|
+
{
|
|
21
|
+
deal = zoho.crm.getRecordById("Deals", dealId);
|
|
22
|
+
|
|
23
|
+
if (deal != null)
|
|
24
|
+
{
|
|
25
|
+
dealName = deal.get("Deal_Name");
|
|
26
|
+
amount = deal.get("Amount");
|
|
27
|
+
stage = deal.get("Stage");
|
|
28
|
+
contactId = deal.get("Contact_Name").get("id");
|
|
29
|
+
|
|
30
|
+
info "Deal: " + dealName + " - $" + amount + " (" + stage + ")";
|
|
31
|
+
}
|
|
32
|
+
else
|
|
33
|
+
{
|
|
34
|
+
info "Deal not found: " + dealId;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e)
|
|
38
|
+
{
|
|
39
|
+
info "CRM getRecord failed: " + e.toString();
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Search Records
|
|
44
|
+
|
|
45
|
+
```deluge
|
|
46
|
+
// Search CRM with criteria
|
|
47
|
+
criteria = "(Email:equals:" + customerEmail + ")";
|
|
48
|
+
contacts = zoho.crm.searchRecords("Contacts", criteria);
|
|
49
|
+
|
|
50
|
+
if (contacts.size() > 0)
|
|
51
|
+
{
|
|
52
|
+
contact = contacts.get(0);
|
|
53
|
+
contactId = contact.get("id");
|
|
54
|
+
contactName = contact.get("Full_Name");
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
{
|
|
58
|
+
info "No contact found for: " + customerEmail;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Create CRM Record
|
|
63
|
+
|
|
64
|
+
```deluge
|
|
65
|
+
// Create a new Deal in CRM
|
|
66
|
+
dealMap = Map();
|
|
67
|
+
dealMap.put("Deal_Name", input.Project_Name + " - " + input.Customer_Name);
|
|
68
|
+
dealMap.put("Amount", input.Estimated_Value);
|
|
69
|
+
dealMap.put("Stage", "Qualification");
|
|
70
|
+
dealMap.put("Closing_Date", zoho.currentdate.addMonth(2).toString("yyyy-MM-dd"));
|
|
71
|
+
dealMap.put("Contact_Name", contactId); // Lookup by ID
|
|
72
|
+
|
|
73
|
+
try
|
|
74
|
+
{
|
|
75
|
+
newDeal = zoho.crm.createRecord("Deals", dealMap);
|
|
76
|
+
dealId = newDeal.get("id");
|
|
77
|
+
info "Created CRM Deal: " + dealId;
|
|
78
|
+
|
|
79
|
+
// Store reference back in Creator
|
|
80
|
+
input.CRM_Deal_ID = dealId;
|
|
81
|
+
}
|
|
82
|
+
catch (e)
|
|
83
|
+
{
|
|
84
|
+
info "CRM Deal creation failed: " + e.toString();
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Update CRM Record
|
|
89
|
+
|
|
90
|
+
```deluge
|
|
91
|
+
updateMap = Map();
|
|
92
|
+
updateMap.put("Stage", "Closed Won");
|
|
93
|
+
updateMap.put("Amount", input.Final_Amount);
|
|
94
|
+
updateMap.put("Closing_Date", zoho.currentdate.toString("yyyy-MM-dd"));
|
|
95
|
+
|
|
96
|
+
try
|
|
97
|
+
{
|
|
98
|
+
response = zoho.crm.updateRecord("Deals", dealId, updateMap);
|
|
99
|
+
info "Deal updated: " + response;
|
|
100
|
+
}
|
|
101
|
+
catch (e)
|
|
102
|
+
{
|
|
103
|
+
info "CRM update failed: " + e.toString();
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Books Operations
|
|
108
|
+
|
|
109
|
+
### Create Invoice in Books
|
|
110
|
+
|
|
111
|
+
```deluge
|
|
112
|
+
// Create Zoho Books invoice from Creator data
|
|
113
|
+
lineItems = List();
|
|
114
|
+
|
|
115
|
+
for each item in input.Line_Items
|
|
116
|
+
{
|
|
117
|
+
line = Map();
|
|
118
|
+
line.put("name", item.Description);
|
|
119
|
+
line.put("quantity", item.Quantity);
|
|
120
|
+
line.put("rate", item.Rate);
|
|
121
|
+
line.put("tax_id", item.Tax_ID);
|
|
122
|
+
lineItems.add(line);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
invoiceData = Map();
|
|
126
|
+
invoiceData.put("customer_id", input.Books_Customer_ID);
|
|
127
|
+
invoiceData.put("date", zoho.currentdate.toString("yyyy-MM-dd"));
|
|
128
|
+
invoiceData.put("due_date", zoho.currentdate.addDay(30).toString("yyyy-MM-dd"));
|
|
129
|
+
invoiceData.put("line_items", lineItems);
|
|
130
|
+
invoiceData.put("reference_number", input.Invoice_Number);
|
|
131
|
+
invoiceData.put("notes", "Created from Creator project: " + input.Project_Name);
|
|
132
|
+
|
|
133
|
+
try
|
|
134
|
+
{
|
|
135
|
+
orgId = "YOUR_BOOKS_ORG_ID";
|
|
136
|
+
response = zoho.books.createRecord("invoices", orgId, invoiceData, "zoho-books-connection");
|
|
137
|
+
|
|
138
|
+
if (response.get("code") == 0)
|
|
139
|
+
{
|
|
140
|
+
booksInvoiceId = response.get("invoice").get("invoice_id");
|
|
141
|
+
input.Books_Invoice_ID = booksInvoiceId;
|
|
142
|
+
info "Books Invoice created: " + booksInvoiceId;
|
|
143
|
+
}
|
|
144
|
+
else
|
|
145
|
+
{
|
|
146
|
+
info "Books error: " + response.get("message");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (e)
|
|
150
|
+
{
|
|
151
|
+
info "Books invoice creation failed: " + e.toString();
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Get Books Records
|
|
156
|
+
|
|
157
|
+
```deluge
|
|
158
|
+
// Get customer from Books
|
|
159
|
+
try
|
|
160
|
+
{
|
|
161
|
+
orgId = "YOUR_BOOKS_ORG_ID";
|
|
162
|
+
customer = zoho.books.getRecordsByID("contacts", orgId, booksCustomerId, "zoho-books-connection");
|
|
163
|
+
|
|
164
|
+
customerName = customer.get("contact").get("contact_name");
|
|
165
|
+
outstandingBalance = customer.get("contact").get("outstanding_receivable_amount");
|
|
166
|
+
info customerName + " owes: $" + outstandingBalance;
|
|
167
|
+
}
|
|
168
|
+
catch (e)
|
|
169
|
+
{
|
|
170
|
+
info "Books lookup failed: " + e.toString();
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Cross-Application Triggers
|
|
175
|
+
|
|
176
|
+
### CRM Deal Won → Create Books Invoice
|
|
177
|
+
|
|
178
|
+
```deluge
|
|
179
|
+
// Workflow: On Edit of CRM Deal, when Stage = "Closed Won"
|
|
180
|
+
if (input.Stage == "Closed Won" && input.Stage_previous != "Closed Won")
|
|
181
|
+
{
|
|
182
|
+
// Step 1: Get contact details from CRM
|
|
183
|
+
contact = zoho.crm.getRecordById("Contacts", input.Contact_Name.get("id"));
|
|
184
|
+
email = contact.get("Email");
|
|
185
|
+
|
|
186
|
+
// Step 2: Find or create Books customer
|
|
187
|
+
orgId = "YOUR_BOOKS_ORG_ID";
|
|
188
|
+
searchResult = zoho.books.getRecords("contacts", orgId, {
|
|
189
|
+
"email": email
|
|
190
|
+
}, "zoho-books-connection");
|
|
191
|
+
|
|
192
|
+
booksCustomerId = "";
|
|
193
|
+
if (searchResult.get("contacts").size() > 0)
|
|
194
|
+
{
|
|
195
|
+
booksCustomerId = searchResult.get("contacts").get(0).get("contact_id");
|
|
196
|
+
}
|
|
197
|
+
else
|
|
198
|
+
{
|
|
199
|
+
// Create new customer in Books
|
|
200
|
+
newCustomer = Map();
|
|
201
|
+
newCustomer.put("contact_name", contact.get("Full_Name"));
|
|
202
|
+
newCustomer.put("email", email);
|
|
203
|
+
newCustomer.put("company_name", contact.get("Account_Name").get("name"));
|
|
204
|
+
createResp = zoho.books.createRecord("contacts", orgId, newCustomer, "zoho-books-connection");
|
|
205
|
+
booksCustomerId = createResp.get("contact").get("contact_id");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Step 3: Create invoice
|
|
209
|
+
invoiceData = Map();
|
|
210
|
+
invoiceData.put("customer_id", booksCustomerId);
|
|
211
|
+
invoiceData.put("line_items", [{
|
|
212
|
+
"name": input.Deal_Name,
|
|
213
|
+
"quantity": 1,
|
|
214
|
+
"rate": input.Amount
|
|
215
|
+
}]);
|
|
216
|
+
|
|
217
|
+
zoho.books.createRecord("invoices", orgId, invoiceData, "zoho-books-connection");
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Data Mapping Between Apps
|
|
222
|
+
|
|
223
|
+
### Field Mapping Reference
|
|
224
|
+
|
|
225
|
+
| CRM Field | Books Field | Creator Field | Notes |
|
|
226
|
+
|-----------|-------------|---------------|-------|
|
|
227
|
+
| Contact_Name | contact_name | Customer_Name | Text match |
|
|
228
|
+
| Email | email | Email | Unique identifier |
|
|
229
|
+
| Account_Name | company_name | Company | May differ |
|
|
230
|
+
| Amount | total | Total_Amount | Numeric |
|
|
231
|
+
| Phone | phone | Phone | Format varies |
|
|
232
|
+
| Owner | - | Assigned_To | CRM-only concept |
|
|
233
|
+
|
|
234
|
+
### Mapping Function
|
|
235
|
+
|
|
236
|
+
```deluge
|
|
237
|
+
// Reusable mapping function
|
|
238
|
+
// Custom Function: mapCRMToBooks(crmRecord)
|
|
239
|
+
crmRecord = input.crmRecord.toJSON();
|
|
240
|
+
|
|
241
|
+
booksData = Map();
|
|
242
|
+
booksData.put("contact_name", crmRecord.get("Full_Name"));
|
|
243
|
+
booksData.put("email", crmRecord.get("Email"));
|
|
244
|
+
booksData.put("phone", crmRecord.get("Phone"));
|
|
245
|
+
|
|
246
|
+
// Handle company name differences
|
|
247
|
+
if (crmRecord.containsKey("Account_Name") && crmRecord.get("Account_Name") != null)
|
|
248
|
+
{
|
|
249
|
+
booksData.put("company_name", crmRecord.get("Account_Name").get("name"));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Address mapping (CRM uses components, Books uses concatenated)
|
|
253
|
+
address = "";
|
|
254
|
+
if (crmRecord.get("Mailing_Street") != null) { address = address + crmRecord.get("Mailing_Street") + "\n"; }
|
|
255
|
+
if (crmRecord.get("Mailing_City") != null) { address = address + crmRecord.get("Mailing_City") + ", "; }
|
|
256
|
+
if (crmRecord.get("Mailing_State") != null) { address = address + crmRecord.get("Mailing_State") + " "; }
|
|
257
|
+
if (crmRecord.get("Mailing_Zip") != null) { address = address + crmRecord.get("Mailing_Zip"); }
|
|
258
|
+
booksData.put("billing_address", {"address": address});
|
|
259
|
+
|
|
260
|
+
return booksData;
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Handling Sync Conflicts
|
|
264
|
+
|
|
265
|
+
### Last-Write-Wins (Simple)
|
|
266
|
+
|
|
267
|
+
```deluge
|
|
268
|
+
// Compare timestamps to determine which system has latest data
|
|
269
|
+
crmModified = deal.get("Modified_Time");
|
|
270
|
+
creatorModified = creatorRecord.get("Modified_Time");
|
|
271
|
+
|
|
272
|
+
if (crmModified > creatorModified)
|
|
273
|
+
{
|
|
274
|
+
// CRM is authoritative - update Creator
|
|
275
|
+
updateCreatorFromCRM(deal, creatorRecord.get("ID"));
|
|
276
|
+
}
|
|
277
|
+
else
|
|
278
|
+
{
|
|
279
|
+
// Creator is authoritative - update CRM
|
|
280
|
+
updateCRMFromCreator(creatorRecord, deal.get("id"));
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Source-of-Truth Pattern (Recommended)
|
|
285
|
+
|
|
286
|
+
```deluge
|
|
287
|
+
// Define which system owns which fields
|
|
288
|
+
// CRM owns: Contact info, deal stage, pipeline
|
|
289
|
+
// Books owns: Payment status, invoice amounts, tax
|
|
290
|
+
// Creator owns: Project details, tasks, timesheets
|
|
291
|
+
|
|
292
|
+
// Only sync fields owned by the source system
|
|
293
|
+
// Never overwrite a field from a non-authoritative system
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Native Sync vs Custom Sync Decision Framework
|
|
297
|
+
|
|
298
|
+
| Factor | Use Native Sync | Build Custom |
|
|
299
|
+
|--------|----------------|-------------|
|
|
300
|
+
| Standard entities (Contacts, Invoices) | Yes | No |
|
|
301
|
+
| 2-hour delay acceptable | Yes | No |
|
|
302
|
+
| Custom fields need syncing | Extend native | Yes |
|
|
303
|
+
| Real-time needed (< 5 min) | No | Yes |
|
|
304
|
+
| Complex transformations | No | Yes |
|
|
305
|
+
| Multi-org sync | No | Yes |
|
|
306
|
+
| Conditional sync (only some records) | No | Yes |
|
|
307
|
+
|
|
308
|
+
> **WARNING:** Before building custom sync, verify the native CRM→Books sync doesn't already handle your use case. Duplicating native sync creates data conflicts and maintenance burden.
|
|
309
|
+
|
|
310
|
+
## Cross-App Error Handling
|
|
311
|
+
|
|
312
|
+
```deluge
|
|
313
|
+
// Robust cross-app operation with rollback tracking
|
|
314
|
+
syncErrors = List();
|
|
315
|
+
syncedRecords = List();
|
|
316
|
+
|
|
317
|
+
records = zoho.creator.getRecords("app", "Pending_Sync_Report", "", 1, 50);
|
|
318
|
+
|
|
319
|
+
for each record in records
|
|
320
|
+
{
|
|
321
|
+
try
|
|
322
|
+
{
|
|
323
|
+
// Attempt CRM update
|
|
324
|
+
crmResult = zoho.crm.updateRecord("Deals", record.get("CRM_ID"), {
|
|
325
|
+
"Stage": record.get("New_Stage")
|
|
326
|
+
});
|
|
327
|
+
syncedRecords.add(record.get("ID"));
|
|
328
|
+
}
|
|
329
|
+
catch (e)
|
|
330
|
+
{
|
|
331
|
+
syncErrors.add({
|
|
332
|
+
"record_id": record.get("ID"),
|
|
333
|
+
"crm_id": record.get("CRM_ID"),
|
|
334
|
+
"error": e.toString(),
|
|
335
|
+
"timestamp": zoho.currenttime
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Mark synced records
|
|
341
|
+
for each syncedId in syncedRecords
|
|
342
|
+
{
|
|
343
|
+
zoho.creator.updateRecord("app", "Sync_Queue", syncedId, {"Sync_Status": "Completed"});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Report errors
|
|
347
|
+
if (syncErrors.size() > 0)
|
|
348
|
+
{
|
|
349
|
+
sendmail [
|
|
350
|
+
from: zoho.adminuserid
|
|
351
|
+
to: "admin@company.com"
|
|
352
|
+
subject: "Cross-App Sync Errors: " + syncErrors.size() + " failures"
|
|
353
|
+
message: syncErrors.toString()
|
|
354
|
+
];
|
|
355
|
+
}
|
|
356
|
+
```
|