agent-docs 1.0.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/.cursor/plans/OPTIMISE.md +379 -0
- package/.cursor/plans/VERSIONING.md +207 -0
- package/.cursor/rules/IMPORTANT.mdc +97 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +13 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- package/.github/dependabot.yml +38 -0
- package/.github/pull_request_template.md +10 -0
- package/.github/workflows/format.yml +35 -0
- package/CODE_OF_CONDUCT.md +64 -0
- package/CONTRIBUTING.md +52 -0
- package/LICENSE.md +20 -0
- package/PLAN.md +707 -0
- package/README.md +133 -0
- package/SECURITY.md +21 -0
- package/docs/APEXANNOTATIONS.md +472 -0
- package/docs/APEXDOC.md +198 -0
- package/docs/CML.md +877 -0
- package/docs/CODEANALYZER.md +435 -0
- package/docs/CONTEXTDEFINITIONS.md +617 -0
- package/docs/ESLINT.md +827 -0
- package/docs/ESLINTJSDOC.md +520 -0
- package/docs/FIELDSERVICE.md +4452 -0
- package/docs/GRAPHBINARY.md +208 -0
- package/docs/GRAPHENGINE.md +616 -0
- package/docs/GRAPHML.md +337 -0
- package/docs/GRAPHSON.md +302 -0
- package/docs/GREMLIN.md +490 -0
- package/docs/GRYO.md +232 -0
- package/docs/HUSKY.md +106 -0
- package/docs/JEST.md +387 -0
- package/docs/JORJE.md +537 -0
- package/docs/JSDOC.md +621 -0
- package/docs/PMD.md +910 -0
- package/docs/PNPM.md +409 -0
- package/docs/PRETTIER.md +716 -0
- package/docs/PRETTIERAPEX.md +874 -0
- package/docs/REVENUETRANSACTIONMANAGEMENT.md +887 -0
- package/docs/TINKERPOP.md +252 -0
- package/docs/VITEST.md +706 -0
- package/docs/VSCODE.md +231 -0
- package/docs/XPATH31.md +213 -0
- package/package.json +32 -0
- package/postinstall.mjs +51 -0
- package/prettier.config.js +18 -0
package/docs/CML.md
ADDED
|
@@ -0,0 +1,877 @@
|
|
|
1
|
+
# CML Reference (Constraint Modeling Language)
|
|
2
|
+
|
|
3
|
+
> **Version**: 1.0.0 | **Platform**: Salesforce Revenue Cloud Product
|
|
4
|
+
> Configurator
|
|
5
|
+
|
|
6
|
+
DSL for defining constraint models for product configuration. Compiles to
|
|
7
|
+
constraint model used by constraint engine to construct compliant
|
|
8
|
+
configurations.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Quick Reference
|
|
13
|
+
|
|
14
|
+
### Syntax Cheatsheet
|
|
15
|
+
|
|
16
|
+
```c
|
|
17
|
+
// Constants & Properties
|
|
18
|
+
define MAX_SIZE 100 // Fixed constant
|
|
19
|
+
define COLORS ["Red", "Blue"] // List constant
|
|
20
|
+
property maxVal = 9999; // Configurable property
|
|
21
|
+
extern int threshold = 50; // External variable with default
|
|
22
|
+
|
|
23
|
+
// Types & Inheritance
|
|
24
|
+
type Product { string name; }
|
|
25
|
+
type Laptop : Product { int RAM; } // Inherits from Product
|
|
26
|
+
|
|
27
|
+
// Variables & Domains
|
|
28
|
+
int quantity = [1..10]; // Range domain
|
|
29
|
+
string color = COLORS; // List reference
|
|
30
|
+
decimal(2) price = [0..1000.00]; // Decimal range
|
|
31
|
+
|
|
32
|
+
// Relationships
|
|
33
|
+
relation items : Item[1..5]; // Min 1, max 5
|
|
34
|
+
relation parts : Part[0..*]; // Zero to unlimited
|
|
35
|
+
relation components : Component[1..*] order (TypeA, TypeB);
|
|
36
|
+
|
|
37
|
+
// Constraints
|
|
38
|
+
constraint(qty > 0); // Basic
|
|
39
|
+
constraint(A && B -> C, "Error message"); // Implication with message
|
|
40
|
+
constraint(rooms[Bedroom] > 0); // Type filter
|
|
41
|
+
|
|
42
|
+
// Rules
|
|
43
|
+
message(condition, "text", "Info|Warning|Error");
|
|
44
|
+
preference(processor == "i7"); // Soft constraint
|
|
45
|
+
require(laptop > 0, warranty > 0); // Auto-add
|
|
46
|
+
exclude(productA > 0, productB > 0); // Prevent combo
|
|
47
|
+
hide(optionA > 0, optionB); // Hide/disable
|
|
48
|
+
action(qty > 10, applyDiscount()); // Trigger action
|
|
49
|
+
|
|
50
|
+
// Functions
|
|
51
|
+
sum(), count(), min(), max(), avg(), parent()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Key Annotations
|
|
55
|
+
|
|
56
|
+
| Annotation | Target | Purpose |
|
|
57
|
+
| ----------------- | ------------ | -------------------------------- |
|
|
58
|
+
| `@displayName` | Type/Var/Rel | UI display name |
|
|
59
|
+
| `@description` | Type | Description text |
|
|
60
|
+
| `@group` | Type | UI grouping |
|
|
61
|
+
| `@hide`/`@hidden` | Type/Var/Rel | Hide from UI |
|
|
62
|
+
| `@sequence` | Type/Var | Resolution order (lower = first) |
|
|
63
|
+
| `@required` | Var/Rel | Mark as required |
|
|
64
|
+
| `@readOnly` | Var | Read-only field |
|
|
65
|
+
| `@defaultValue` | Var | Default value |
|
|
66
|
+
| `@contextPath` | Var | Map to transaction field |
|
|
67
|
+
| `@abort` | Constraint | Stop on first error |
|
|
68
|
+
|
|
69
|
+
Combined syntax: `@(key=value, key2=value2)`
|
|
70
|
+
|
|
71
|
+
### Performance Targets
|
|
72
|
+
|
|
73
|
+
| Metric | Target | Impact |
|
|
74
|
+
| -------------- | ------ | ------------------------- |
|
|
75
|
+
| Execution Time | <100ms | UI responsiveness |
|
|
76
|
+
| Backtracks | <1000 | Efficient resolution |
|
|
77
|
+
| Violations | 0 | All constraints satisfied |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Setup: Enabling CML (Constraint Rules Engine)
|
|
82
|
+
|
|
83
|
+
### Prerequisites
|
|
84
|
+
|
|
85
|
+
- **Edition**: Enterprise/Performance/Unlimited/Developer with Revenue Cloud
|
|
86
|
+
Growth or Advanced license
|
|
87
|
+
- **Permission Set**: "Product Configuration Constraints Designer"
|
|
88
|
+
- **Restrictions**: Not available in Government Cloud or EU Operating Zone (OZ)
|
|
89
|
+
|
|
90
|
+
### Step 1: Enable in Revenue Settings
|
|
91
|
+
|
|
92
|
+
1. Setup → **Revenue Settings**
|
|
93
|
+
2. Enable **Set Up Configuration Rules and Constraints with Constraint Rules
|
|
94
|
+
Engine**
|
|
95
|
+
3. `AdvancedConfigurator` becomes default rule engine
|
|
96
|
+
|
|
97
|
+
> **Note**: Beta feature—validate in sandbox first.
|
|
98
|
+
|
|
99
|
+
### Step 2: Create Transaction Processing Type
|
|
100
|
+
|
|
101
|
+
Create a Transaction Processing Type record:
|
|
102
|
+
|
|
103
|
+
- Set **Rule Engine** = `AdvancedConfigurator` (not `StandardConfigurator`)
|
|
104
|
+
- Optionally append "Advanced Configurator" to name for identification
|
|
105
|
+
|
|
106
|
+
| Rule Engine Value | Uses |
|
|
107
|
+
| ---------------------- | ----------------------------- |
|
|
108
|
+
| `AdvancedConfigurator` | Constraint Rules Engine (CML) |
|
|
109
|
+
| `StandardConfigurator` | Business Rules Engine (BRE) |
|
|
110
|
+
|
|
111
|
+
### Step 3: Create ConstraintEngineNodeStatus Field
|
|
112
|
+
|
|
113
|
+
**Required field** for CRE to function. Create on each object:
|
|
114
|
+
|
|
115
|
+
| Object | Field Name | API Name | Type | Length |
|
|
116
|
+
| ------------------- | ----------------------------- | ------------------------------------ | -------------- | ------ |
|
|
117
|
+
| Quote Line Item | Constraint Engine Node Status | `ConstraintEngineNodeStatus__c` | Long Text Area | 5000 |
|
|
118
|
+
| Order Item | Constraint Engine Node Status | `ConstraintEngineNodeStatus__c` | Long Text Area | 5000 |
|
|
119
|
+
| Asset Action Source | Constraint Engine Node Status | `AssetConstraintEngineNodeStatus__c` | Long Text Area | 5000 |
|
|
120
|
+
|
|
121
|
+
**Field setup**:
|
|
122
|
+
|
|
123
|
+
1. Object Manager → Select object → Fields & Relationships → New
|
|
124
|
+
2. Type: Text Area (Long), Length: 5000
|
|
125
|
+
3. Set field-level security for CRE profiles
|
|
126
|
+
4. Field auto-populated by constraint engine at runtime
|
|
127
|
+
|
|
128
|
+
### Step 4: Configure Context Definitions
|
|
129
|
+
|
|
130
|
+
Context definitions map transaction data to constraint models.
|
|
131
|
+
|
|
132
|
+
**Standard Contexts**:
|
|
133
|
+
|
|
134
|
+
- `SalesTransactionContext` — Quotes/orders
|
|
135
|
+
- `InsuranceContext` — Insurance products
|
|
136
|
+
- `AssetContext` — Asset-based config (Summer '25+)
|
|
137
|
+
|
|
138
|
+
#### Update SalesTransactionContext
|
|
139
|
+
|
|
140
|
+
1. Setup → Context Service → **Context Definitions** → Find
|
|
141
|
+
`SalesTransactionContext`
|
|
142
|
+
2. **Attributes tab**: Add `ConstraintEngineNodeStatus` attribute
|
|
143
|
+
- Type: `INPUTOUTPUT`
|
|
144
|
+
- Data Type: `STRING`
|
|
145
|
+
- Node: `SalesTransactionItem`
|
|
146
|
+
3. **Map Data tab**: Map attribute to field
|
|
147
|
+
- `QuoteEntitiesMapping`: Map to
|
|
148
|
+
`QuoteLineItem.ConstraintEngineNodeStatus__c`
|
|
149
|
+
- `OrderEntitiesMapping`: Map to `OrderItem.ConstraintEngineNodeStatus__c`
|
|
150
|
+
4. **Activate** the context definition
|
|
151
|
+
|
|
152
|
+
**Optional TransactionType mapping** (to switch engines per transaction):
|
|
153
|
+
|
|
154
|
+
- Map `TransactionType` attribute on `SalesTransaction` node to
|
|
155
|
+
`Quote.TransactionType` / `Order.TransactionType`
|
|
156
|
+
|
|
157
|
+
#### For Insurance (extend InsuranceContext)
|
|
158
|
+
|
|
159
|
+
1. Extend `InsuranceContext`
|
|
160
|
+
2. Add `ConstraintEngineNodeStatus` to `InsuranceItem` node (INPUTOUTPUT,
|
|
161
|
+
STRING)
|
|
162
|
+
3. Map to `QuoteLineItem.ConstraintEngineNodeStatus__c`
|
|
163
|
+
4. Activate
|
|
164
|
+
|
|
165
|
+
#### For Assets (Summer '25+)
|
|
166
|
+
|
|
167
|
+
1. Extend `AssetContext__stdctx`
|
|
168
|
+
2. Setup → Revenue Settings → **Set Up Asset Context for Product Configurator**
|
|
169
|
+
→ Select your context
|
|
170
|
+
3. Map `AssetConstraintEngineNodeStatus` attribute
|
|
171
|
+
4. Edit `AssetToSalesTransactionMapping` → Map to
|
|
172
|
+
`SalesTransactionItem.ConstraintEngineNodeStatus__c`
|
|
173
|
+
|
|
174
|
+
### Step 5: Assign Permission Sets
|
|
175
|
+
|
|
176
|
+
| Permission Set | Purpose |
|
|
177
|
+
| ------------------------------------------ | ---------------------------------------------------- |
|
|
178
|
+
| Product Configuration Constraints Designer | Create/manage constraint models |
|
|
179
|
+
| Product Configurator | Configure products at runtime |
|
|
180
|
+
| Constraint Rules Engine Licenseless | CRE access to standard objects for table constraints |
|
|
181
|
+
|
|
182
|
+
### Rule Engine Selection Logic
|
|
183
|
+
|
|
184
|
+
| CRE Enabled | BRE Enabled | TPT Value | Engine Used |
|
|
185
|
+
| ----------- | ----------- | -------------------- | ----------- |
|
|
186
|
+
| Yes | No | — | CRE |
|
|
187
|
+
| No | Yes | StandardConfigurator | BRE |
|
|
188
|
+
| Yes | Yes | StandardConfigurator | BRE |
|
|
189
|
+
| Yes | Yes | Other/None | CRE |
|
|
190
|
+
|
|
191
|
+
### Impact on Existing Quotes
|
|
192
|
+
|
|
193
|
+
- Pre-CRE quotes don't run CRE rules unless migrated to CML
|
|
194
|
+
- New quotes with Advanced Configurator TPT use CRE automatically
|
|
195
|
+
- Quotes with Standard Configurator TPT continue using BRE
|
|
196
|
+
- **Best practice**: Migrate existing rules to CML before enabling CRE in
|
|
197
|
+
production
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Creating Constraint Models
|
|
202
|
+
|
|
203
|
+
### Workflow
|
|
204
|
+
|
|
205
|
+
1. **Create Model**: App Launcher → Constraint Models → New
|
|
206
|
+
- Enter name, API name
|
|
207
|
+
- Specify context definition (e.g., `InsuranceContext`,
|
|
208
|
+
`SalesTransactionContext`)
|
|
209
|
+
2. **Select Version**: Constraint models support versioning (one active at a
|
|
210
|
+
time)
|
|
211
|
+
3. **Add Products**: Click Add Item → Product → Select items
|
|
212
|
+
- Bundles auto-import product component groups and cardinality from PCM
|
|
213
|
+
4. **Define Constraints/Rules**: Select item → Add constraint/rule → Configure
|
|
214
|
+
expressions
|
|
215
|
+
5. **Create Associations**: Connect CML types to product records (see
|
|
216
|
+
[Associations](#associations))
|
|
217
|
+
6. **Activate**: Save → Activate for production use
|
|
218
|
+
|
|
219
|
+
### Visual Builder vs CML Editor
|
|
220
|
+
|
|
221
|
+
- **Bidirectional**: Switch between interfaces; changes sync automatically
|
|
222
|
+
- **Visual Builder**: Point-and-click rule definition; constraint names appear
|
|
223
|
+
as comments in CML
|
|
224
|
+
- **CML Editor**: Full code access; some features only available here (labeled
|
|
225
|
+
"not editable" in Visual Builder)
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Core Syntax
|
|
230
|
+
|
|
231
|
+
### Global Properties
|
|
232
|
+
|
|
233
|
+
```c
|
|
234
|
+
define MAX_ROOM_SIZE 1000 // Fixed constant
|
|
235
|
+
define COLORS ["Red", "Blue", "Green"] // List constant
|
|
236
|
+
property maxDouble = 99999999; // Configurable property
|
|
237
|
+
|
|
238
|
+
// External variables (from transaction context)
|
|
239
|
+
extern int MAX_VALUE = 9999; // With default
|
|
240
|
+
extern decimal(2) threshold = 1.5;
|
|
241
|
+
|
|
242
|
+
// Mapped external variable
|
|
243
|
+
@(contextPath="Order.AccountId")
|
|
244
|
+
extern string accountId;
|
|
245
|
+
|
|
246
|
+
@(contextPath="OrderLineItem.Quantity")
|
|
247
|
+
extern int lineItemQuantity;
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Types
|
|
251
|
+
|
|
252
|
+
Represent products, bundles, components, product classes.
|
|
253
|
+
|
|
254
|
+
```c
|
|
255
|
+
type House {
|
|
256
|
+
string address;
|
|
257
|
+
int numberOfRooms = [1..MAX_ROOM];
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Inheritance
|
|
261
|
+
type Room { decimal(2) area; }
|
|
262
|
+
type LivingRoom : Room;
|
|
263
|
+
type Bedroom : Room;
|
|
264
|
+
type MasterBedroom : Bedroom;
|
|
265
|
+
|
|
266
|
+
// With annotations
|
|
267
|
+
@(displayName="Premium Laptop", group="Electronics", sequence=1)
|
|
268
|
+
type Laptop { ... }
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Variables
|
|
272
|
+
|
|
273
|
+
| Type | Description | Example |
|
|
274
|
+
| ------------ | ------------------------ | ------------------------ |
|
|
275
|
+
| `int` | Integer | `int qty = [1..10];` |
|
|
276
|
+
| `decimal(n)` | Decimal with n precision | `decimal(2) price;` |
|
|
277
|
+
| `string` | String | `string color = COLORS;` |
|
|
278
|
+
| `bool` | Boolean | `bool active;` |
|
|
279
|
+
| `date` | Date | `date orderDate;` |
|
|
280
|
+
| `datetime` | Date and time | `datetime timestamp;` |
|
|
281
|
+
|
|
282
|
+
**Domains**:
|
|
283
|
+
|
|
284
|
+
```c
|
|
285
|
+
int quantity = [1..10]; // Range
|
|
286
|
+
string color = COLORS; // List reference
|
|
287
|
+
string status = ["Active", "Inactive"];// Inline list
|
|
288
|
+
decimal(2) price = [0..1000.00]; // Decimal range
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Functions**:
|
|
292
|
+
|
|
293
|
+
```c
|
|
294
|
+
totalArea = rooms.sum(area); // Sum across relationship
|
|
295
|
+
roomCount = rooms.count(); // Count items
|
|
296
|
+
minPrice = products.min(price); // Minimum value
|
|
297
|
+
maxSize = components.max(size); // Maximum value
|
|
298
|
+
avgPrice = items.avg(unitPrice); // Average value
|
|
299
|
+
houseArea = parent(totalArea); // Access parent variable
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Calculated & Proxy Variables**:
|
|
303
|
+
|
|
304
|
+
```c
|
|
305
|
+
type Bundle {
|
|
306
|
+
relation products : Product[1..*];
|
|
307
|
+
decimal(2) totalPrice = products.sum(price); // Calculated
|
|
308
|
+
decimal(2) discount = totalPrice * 0.1; // Derived
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
type Room {
|
|
312
|
+
decimal(2) houseArea = parent(totalArea); // Proxy to parent
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Relationships
|
|
317
|
+
|
|
318
|
+
```c
|
|
319
|
+
relation rooms : Room[1..MAX_ROOM]; // Basic
|
|
320
|
+
relation items : Item[1..*] order (TypeA, TypeB); // With creation order
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Cardinality**: | Syntax | Meaning | |--------|---------| | `[1..5]` | Min 1,
|
|
324
|
+
max 5 | | `[0..*]` | Zero to unlimited | | `[1..*]` | At least one, unlimited |
|
|
325
|
+
|
|
326
|
+
**Importing from PCM**:
|
|
327
|
+
|
|
328
|
+
- **With Product Component Groups**: Imports full PCM structure, enables
|
|
329
|
+
group-level constraints
|
|
330
|
+
- **Without**: Imports relationships only, simpler model
|
|
331
|
+
|
|
332
|
+
### Constraints
|
|
333
|
+
|
|
334
|
+
```c
|
|
335
|
+
// Basic
|
|
336
|
+
constraint(rooms[Bedroom] > 0);
|
|
337
|
+
constraint(numberOfRooms == rooms[Room]);
|
|
338
|
+
constraint(totalArea > 1000 && totalArea < 5000);
|
|
339
|
+
|
|
340
|
+
// Implication (if left true, right must be true)
|
|
341
|
+
constraint(Display == "1080p" && Size == "15 Inch" -> Processor == "i7-CPU");
|
|
342
|
+
|
|
343
|
+
// With error message
|
|
344
|
+
constraint(rooms[Bedroom] > 0, "At least one bedroom required");
|
|
345
|
+
|
|
346
|
+
// Abort on first error (prevents backtracking)
|
|
347
|
+
@(abort=true)
|
|
348
|
+
constraint(price > maxBudget, "Price exceeds maximum budget");
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Table Constraints** (valid combinations):
|
|
352
|
+
|
|
353
|
+
```c
|
|
354
|
+
table constraint validConfigurations {
|
|
355
|
+
(Display, Size, Processor)
|
|
356
|
+
("1080p", "15 Inch", "i7-CPU")
|
|
357
|
+
("4k", "24 Inch", "i9-CPU")
|
|
358
|
+
}
|
|
359
|
+
constraint(validConfigurations(Display, Size, Processor));
|
|
360
|
+
|
|
361
|
+
// With SOQL filter
|
|
362
|
+
table constraint activeConfigs {
|
|
363
|
+
SOQL: "SELECT Display__c, Size__c, Processor__c FROM ValidConfig__c WHERE Active__c = true"
|
|
364
|
+
(Display, Size, Processor)
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Rules
|
|
369
|
+
|
|
370
|
+
| Rule | Syntax | Description |
|
|
371
|
+
| ---------- | ----------------------------------------------- | ------------------------------ |
|
|
372
|
+
| Message | `message(cond, "text", "Info\|Warning\|Error")` | Display message |
|
|
373
|
+
| Preference | `preference(expr)` | Suggest preferred value (soft) |
|
|
374
|
+
| Require | `require(condA, condB)` | Auto-add when condition met |
|
|
375
|
+
| Exclude | `exclude(condA, condB)` | Prevent combination |
|
|
376
|
+
| Hide | `hide(cond, target)` | Hide element |
|
|
377
|
+
| Disable | `disable(cond, target)` | Disable element |
|
|
378
|
+
| Action | `action(cond, action())` | Execute action |
|
|
379
|
+
|
|
380
|
+
```c
|
|
381
|
+
// Dynamic message with severity
|
|
382
|
+
message(totalPrice > 10000, "High-value order - manager approval may be required", "Warning");
|
|
383
|
+
|
|
384
|
+
// Preference (engine can override)
|
|
385
|
+
preference(processor == "i7");
|
|
386
|
+
|
|
387
|
+
// Auto-add warranty when laptop selected
|
|
388
|
+
require(laptop[Laptop] > 0, warranty[Warranty] > 0);
|
|
389
|
+
|
|
390
|
+
// Prevent incompatible products
|
|
391
|
+
exclude(productA[ProductA] > 0, productB[ProductB] > 0);
|
|
392
|
+
|
|
393
|
+
// Conditional hide/disable (same behavior for attribute values)
|
|
394
|
+
hide(optionA[OptionA] > 0, optionB);
|
|
395
|
+
disable(totalPrice > 10000, discount);
|
|
396
|
+
|
|
397
|
+
// Trigger action
|
|
398
|
+
action(quantity > 10, applyDiscount(15));
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Comments
|
|
402
|
+
|
|
403
|
+
```c
|
|
404
|
+
// Single-line comment
|
|
405
|
+
/* Block comment */
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Complete Example
|
|
411
|
+
|
|
412
|
+
```c
|
|
413
|
+
define COLORS ["Red", "Blue", "White"]
|
|
414
|
+
define MAX_ROOM 10
|
|
415
|
+
define MAX_ROOM_SIZE 100
|
|
416
|
+
|
|
417
|
+
type House {
|
|
418
|
+
string address;
|
|
419
|
+
int numberOfRooms = [1..MAX_ROOM];
|
|
420
|
+
decimal(2) totalArea = rooms.sum(area);
|
|
421
|
+
|
|
422
|
+
relation rooms : Room[1..MAX_ROOM] order (LivingRoom, Bedroom);
|
|
423
|
+
|
|
424
|
+
constraint(rooms[Bedroom] > 0);
|
|
425
|
+
constraint(numberOfRooms == rooms[Room]);
|
|
426
|
+
message(totalArea > 5000, "This is a spacious house!");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
type Room {
|
|
430
|
+
decimal(2) width = [1..MAX_ROOM_SIZE];
|
|
431
|
+
decimal(2) length = [1..MAX_ROOM_SIZE];
|
|
432
|
+
decimal(2) area = width * length;
|
|
433
|
+
string color = COLORS;
|
|
434
|
+
decimal(2) houseArea = parent(totalArea);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
type LivingRoom : Room;
|
|
438
|
+
type Bedroom : Room;
|
|
439
|
+
type MasterBedroom : Bedroom;
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Associations
|
|
445
|
+
|
|
446
|
+
Connect CML types to product catalog records.
|
|
447
|
+
|
|
448
|
+
### Type Associations
|
|
449
|
+
|
|
450
|
+
Connect type to product, classification, or component group:
|
|
451
|
+
|
|
452
|
+
1. Select Object Category (Product/Product Classification/Product Component
|
|
453
|
+
Group)
|
|
454
|
+
2. Select specific record to connect
|
|
455
|
+
3. Association table displays type ID and product record ID
|
|
456
|
+
|
|
457
|
+
### Relationship Associations
|
|
458
|
+
|
|
459
|
+
Connect relationship to bundle components:
|
|
460
|
+
|
|
461
|
+
1. Select Type Relationship (relationship defined in CML)
|
|
462
|
+
2. Select Bundle from catalog
|
|
463
|
+
3. Select Product or Classification from bundle
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Performance & Optimization
|
|
468
|
+
|
|
469
|
+
### Understanding Backtracking
|
|
470
|
+
|
|
471
|
+
Backtracking occurs when the constraint engine makes a choice leading to
|
|
472
|
+
conflict, then backs up to try another. High backtracking (>1000) indicates:
|
|
473
|
+
|
|
474
|
+
- Conflicting constraints
|
|
475
|
+
- Poor sequence ordering
|
|
476
|
+
- Overly restrictive domains
|
|
477
|
+
- Complex interdependencies
|
|
478
|
+
|
|
479
|
+
### Optimization Techniques
|
|
480
|
+
|
|
481
|
+
#### 1. Narrow Domains
|
|
482
|
+
|
|
483
|
+
```c
|
|
484
|
+
// Bad: Large domain with constraining constraint
|
|
485
|
+
int RAM = [0..1000];
|
|
486
|
+
constraint(RAM >= 8 && RAM <= 64);
|
|
487
|
+
|
|
488
|
+
// Good: Domain already narrowed
|
|
489
|
+
int RAM = [8..64];
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
#### 2. Use Sequence Annotations
|
|
493
|
+
|
|
494
|
+
```c
|
|
495
|
+
type Desktop {
|
|
496
|
+
@(defaultValue="1080p", sequence=1)
|
|
497
|
+
string Display = ["1080p", "4k"]; // Resolve first (independent)
|
|
498
|
+
|
|
499
|
+
@(defaultValue="i5-CPU", sequence=2)
|
|
500
|
+
string Processor = ["i5-CPU", "i7-CPU"]; // Resolve second (depends on Display)
|
|
501
|
+
|
|
502
|
+
@(defaultValue="15 Inch", sequence=3)
|
|
503
|
+
string Size = ["15 Inch", "24 Inch"]; // Resolve last (most constrained)
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**Strategy**: Independent variables first (low sequence) → Dependent variables
|
|
508
|
+
next → Most constrained last.
|
|
509
|
+
|
|
510
|
+
#### 3. Separate Complex Constraints
|
|
511
|
+
|
|
512
|
+
```c
|
|
513
|
+
// Bad: Complex nested
|
|
514
|
+
constraint(A && (B || C) && D && (E || F));
|
|
515
|
+
|
|
516
|
+
// Good: Separated
|
|
517
|
+
constraint(A);
|
|
518
|
+
constraint(B || C);
|
|
519
|
+
constraint(D);
|
|
520
|
+
constraint(E || F);
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
#### 4. Optimize Relationships
|
|
524
|
+
|
|
525
|
+
```c
|
|
526
|
+
// Bad: Many separate relationships
|
|
527
|
+
relation mouse : Mouse[0..1];
|
|
528
|
+
relation keyboard : Keyboard[0..1];
|
|
529
|
+
|
|
530
|
+
// Good: Combined relationship
|
|
531
|
+
relation accessories : Accessory[0..*];
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
#### 5. Optimize Table Constraints
|
|
535
|
+
|
|
536
|
+
| Size | Performance | Action |
|
|
537
|
+
| --------- | --------------------- | ------------------------------------------- |
|
|
538
|
+
| <100 rows | Fast | OK |
|
|
539
|
+
| 100-1000 | Acceptable | Monitor |
|
|
540
|
+
| >1000 | Consider alternatives | Split, filter with SOQL, or use constraints |
|
|
541
|
+
|
|
542
|
+
```c
|
|
543
|
+
// Use SOQL filter to reduce rows
|
|
544
|
+
table constraint validConfigs {
|
|
545
|
+
SOQL: "SELECT ... FROM ValidConfig__c WHERE Active__c = true"
|
|
546
|
+
...
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
#### 6. Minimize External Variable Lookups
|
|
551
|
+
|
|
552
|
+
```c
|
|
553
|
+
// Use defaults to avoid unnecessary lookups
|
|
554
|
+
extern string customerTier = "Standard";
|
|
555
|
+
|
|
556
|
+
// Batch related fields in context definition rather than multiple extern calls
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Best Practices Summary
|
|
560
|
+
|
|
561
|
+
| Practice | Avoid | Prefer |
|
|
562
|
+
| ------------- | ------------------------------------- | ----------------------------- |
|
|
563
|
+
| Domains | `[0..500]` with `constraint(v > 110)` | `[110..500]` |
|
|
564
|
+
| Constraints | `constraint(A, B && B.attr == "X")` | Separate constraints |
|
|
565
|
+
| Relationships | Multiple separate relations | Combined relation |
|
|
566
|
+
| Sequence | No annotations | `@(sequence=N)` by dependency |
|
|
567
|
+
| Logic | Complex nested | Simple, separated |
|
|
568
|
+
| Tables | >1000 rows | Filtered or split |
|
|
569
|
+
| Externals | Many lookups | Batched, with defaults |
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Debugging & Troubleshooting
|
|
574
|
+
|
|
575
|
+
### Enable Debug Logging
|
|
576
|
+
|
|
577
|
+
1. Setup → **Debug Logs** → New
|
|
578
|
+
2. Select user/Apex class
|
|
579
|
+
3. Set **Apex Code**: FINE
|
|
580
|
+
4. Set expiration (1-7 days for testing)
|
|
581
|
+
|
|
582
|
+
### Log Sections
|
|
583
|
+
|
|
584
|
+
#### RLM_CONFIGURATOR_BEGIN
|
|
585
|
+
|
|
586
|
+
Request payload to `ExecuteConstraintsRESTService`:
|
|
587
|
+
|
|
588
|
+
- `contextProperties`: Context mappings
|
|
589
|
+
- `rootLineItems`: Root items with attributes, properties, domains, child items
|
|
590
|
+
- `orgId`: Organization ID
|
|
591
|
+
|
|
592
|
+
**Check**: Required attributes present, domains correct, line item structure
|
|
593
|
+
matches model.
|
|
594
|
+
|
|
595
|
+
#### RLM_CONFIGURATOR_STATS
|
|
596
|
+
|
|
597
|
+
Execution statistics:
|
|
598
|
+
|
|
599
|
+
| Metric | Target | Meaning |
|
|
600
|
+
| -------------------------------- | ------ | ----------------------------- |
|
|
601
|
+
| `Total Execution Time` | <100ms | Higher = performance issue |
|
|
602
|
+
| `Number of Backtracks` | <1000 | Higher = constraint conflicts |
|
|
603
|
+
| `Constraints Violation Stats` | 0 | Most violated constraints |
|
|
604
|
+
| `ChoicePoint Backtracking Stats` | — | Problematic decision points |
|
|
605
|
+
| `Constraints Execution Stats` | — | "Distinct: X Total: Y" |
|
|
606
|
+
|
|
607
|
+
#### RLM_CONFIGURATOR_END
|
|
608
|
+
|
|
609
|
+
Response payload:
|
|
610
|
+
|
|
611
|
+
- `cfgStatus`: SUCCESS/FAILURE
|
|
612
|
+
- `attributes`: Final values after resolution
|
|
613
|
+
- `attributeDomains`: Final domains (may be narrowed)
|
|
614
|
+
- `ruleActions`: Rules executed
|
|
615
|
+
- `lineItems`: Child configurations
|
|
616
|
+
|
|
617
|
+
### Common Scenarios
|
|
618
|
+
|
|
619
|
+
| Scenario | Symptoms | Debug Steps |
|
|
620
|
+
| --------------------- | ------------------------------------ | ----------------------------------------------------------------------------------- |
|
|
621
|
+
| Constraint Violations | FAILURE status, high violation count | Check Violation Stats → Review constraint logic → Verify domains allow valid combos |
|
|
622
|
+
| Performance Issues | >100ms time, >1000 backtracks | Check ChoicePoint Stats → Narrow domains → Simplify constraints → Fix sequences |
|
|
623
|
+
| Unexpected Behavior | Wrong values, rules not triggering | Verify model activated → Check associations → Review BEGIN/END payloads |
|
|
624
|
+
| Missing Attributes | NullPointerException | Verify attributes in BEGIN → Check associations → Remove/use unused attributes |
|
|
625
|
+
|
|
626
|
+
### Debugging Checklist
|
|
627
|
+
|
|
628
|
+
- [ ] Debug logging at FINE level
|
|
629
|
+
- [ ] Constraint model activated
|
|
630
|
+
- [ ] Associations created and correct
|
|
631
|
+
- [ ] Context definition activated and mapped
|
|
632
|
+
- [ ] Transaction Type uses Advanced Configurator
|
|
633
|
+
- [ ] All attributes defined with appropriate domains
|
|
634
|
+
- [ ] No conflicting constraints
|
|
635
|
+
- [ ] Sequence annotations optimal
|
|
636
|
+
- [ ] Performance targets met
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
## Extending CML
|
|
641
|
+
|
|
642
|
+
### Custom Variables
|
|
643
|
+
|
|
644
|
+
**Standalone** (intermediate calculations):
|
|
645
|
+
|
|
646
|
+
```c
|
|
647
|
+
type Laptop {
|
|
648
|
+
string Processor;
|
|
649
|
+
int RAM;
|
|
650
|
+
int totalMemory = RAM * 1024; // Calculated
|
|
651
|
+
bool isHighEnd = Processor == "i9" || RAM >= 32; // Derived
|
|
652
|
+
}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
**Reference Library Variables**: Apply pre-configured variables from reference
|
|
656
|
+
libraries in Constraint Builder.
|
|
657
|
+
|
|
658
|
+
### External Variables with ContextPath
|
|
659
|
+
|
|
660
|
+
Map to transaction fields:
|
|
661
|
+
|
|
662
|
+
```c
|
|
663
|
+
// Header fields
|
|
664
|
+
@(contextPath="Order.AccountId")
|
|
665
|
+
extern string accountId;
|
|
666
|
+
|
|
667
|
+
@(contextPath="Quote.TotalPrice")
|
|
668
|
+
extern decimal(2) quoteTotal;
|
|
669
|
+
|
|
670
|
+
// Line item fields
|
|
671
|
+
@(contextPath="OrderLineItem.Quantity")
|
|
672
|
+
extern int lineItemQty;
|
|
673
|
+
|
|
674
|
+
// Custom fields
|
|
675
|
+
@(contextPath="Order.CustomField__c")
|
|
676
|
+
extern string customValue = "Default"; // Default if not mapped
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
**Common Mappings**:
|
|
680
|
+
|
|
681
|
+
| Context Path | Context Node | Salesforce Field |
|
|
682
|
+
| -------------------------- | -------------------- | ---------------------- |
|
|
683
|
+
| `Order.AccountId` | SalesTransaction | Order.AccountId |
|
|
684
|
+
| `OrderLineItem.Quantity` | SalesTransactionItem | QuoteLineItem.Quantity |
|
|
685
|
+
| `Quote.TotalPrice` | SalesTransaction | Quote.TotalPrice |
|
|
686
|
+
| `InsuranceItem.PolicyType` | InsuranceItem | PolicyType\_\_c |
|
|
687
|
+
|
|
688
|
+
### Import from Salesforce Objects
|
|
689
|
+
|
|
690
|
+
Table constraints can reference Salesforce objects for data-driven rules:
|
|
691
|
+
|
|
692
|
+
1. Create custom object with fields matching table constraint variables
|
|
693
|
+
2. Populate with valid combinations
|
|
694
|
+
3. Reference in table constraint (SOQL query)
|
|
695
|
+
|
|
696
|
+
**Benefits**: Separate data from code, business users can update, no deployment
|
|
697
|
+
for data changes.
|
|
698
|
+
|
|
699
|
+
### Import from PCM
|
|
700
|
+
|
|
701
|
+
When adding bundles to constraint models:
|
|
702
|
+
|
|
703
|
+
- **Imported**: Product component groups, child products, classifications,
|
|
704
|
+
relationships, cardinality
|
|
705
|
+
- **Not imported**: Class attributes (add manually in CML Editor)
|
|
706
|
+
|
|
707
|
+
**Group-level constraints** (CML Editor only):
|
|
708
|
+
|
|
709
|
+
```c
|
|
710
|
+
constraint(bundle.components[DisplayGroup].count() >= 1);
|
|
711
|
+
constraint(bundle.components[DisplayGroup].sum(price) < 500);
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### Extending Context Definitions
|
|
715
|
+
|
|
716
|
+
1. Setup → Context Service → Context Definitions
|
|
717
|
+
2. Edit/Extend context definition
|
|
718
|
+
3. Add attributes to appropriate node (SalesTransaction, SalesTransactionItem)
|
|
719
|
+
4. Map Data tab → Map to Salesforce fields
|
|
720
|
+
5. Activate
|
|
721
|
+
|
|
722
|
+
**Example Extension**:
|
|
723
|
+
|
|
724
|
+
```c
|
|
725
|
+
// After adding PolicyType, CoverageLimit to InsuranceContext
|
|
726
|
+
type InsuranceProduct {
|
|
727
|
+
@(contextPath="InsuranceItem.PolicyType")
|
|
728
|
+
extern string policyType;
|
|
729
|
+
|
|
730
|
+
@(contextPath="InsuranceItem.CoverageLimit")
|
|
731
|
+
extern decimal(2) coverageLimit;
|
|
732
|
+
|
|
733
|
+
constraint(policyType == "Comprehensive" -> coverageLimit >= 50000);
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### Advanced Patterns
|
|
738
|
+
|
|
739
|
+
**Multi-level Context Access**:
|
|
740
|
+
|
|
741
|
+
```c
|
|
742
|
+
@(contextPath="Order.Account.Industry")
|
|
743
|
+
extern string accountIndustry;
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
**Conditional External Variables**:
|
|
747
|
+
|
|
748
|
+
```c
|
|
749
|
+
extern bool enableAdvancedRules;
|
|
750
|
+
extern string userProfile;
|
|
751
|
+
|
|
752
|
+
constraint(enableAdvancedRules && userProfile == "Admin" -> complexConstraint());
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
**Cross-Product Context**:
|
|
756
|
+
|
|
757
|
+
```c
|
|
758
|
+
type Bundle {
|
|
759
|
+
extern string customerTier; // Shared across products
|
|
760
|
+
relation products : Product[1..*];
|
|
761
|
+
constraint(customerTier == "Premium" -> products[PremiumFeature] > 0);
|
|
762
|
+
}
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### Insurance Clause Integration
|
|
766
|
+
|
|
767
|
+
```c
|
|
768
|
+
// Rule key maps to Insurance Clause records
|
|
769
|
+
boolean Ex__autoSilver__auto__vehicleUsage = Year > 2020 && Auto_Value > 10000 && Auto_Value < 30000;
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
Clauses support dynamic content with variables replaced at runtime.
|
|
773
|
+
|
|
774
|
+
---
|
|
775
|
+
|
|
776
|
+
## Visual Builder Reference
|
|
777
|
+
|
|
778
|
+
### Rule Types
|
|
779
|
+
|
|
780
|
+
| Rule Type | Purpose |
|
|
781
|
+
| ---------------------------- | ----------------------------------------- |
|
|
782
|
+
| Basic Logic Constraint | Enforce conditions on products/attributes |
|
|
783
|
+
| Conditional Logic Constraint | If-then constraints |
|
|
784
|
+
| Dynamic Message Rule | Show info/warning/error messages |
|
|
785
|
+
| Require Rule | Auto-add products/components |
|
|
786
|
+
| Exclude Rule | Prevent combinations |
|
|
787
|
+
| Hide/Disable Rule | Hide/disable based on conditions |
|
|
788
|
+
| Preference Rule | Suggest preferred values |
|
|
789
|
+
|
|
790
|
+
### Expression Building
|
|
791
|
+
|
|
792
|
+
1. **Left-hand element**: Product, bundle, attribute, variable, or transaction
|
|
793
|
+
header
|
|
794
|
+
2. **Operator**: `==`, `!=`, `>`, `<`, `>=`, `<=`
|
|
795
|
+
3. **Right-hand element**: Another element or static value
|
|
796
|
+
|
|
797
|
+
### Grouping Logic
|
|
798
|
+
|
|
799
|
+
Reference expressions by number with `and`, `or`, `xor`:
|
|
800
|
+
|
|
801
|
+
```
|
|
802
|
+
// Valid
|
|
803
|
+
(1 and 2) or 3
|
|
804
|
+
(1 and ((2 or 3) or (4 and 5)))
|
|
805
|
+
|
|
806
|
+
// Invalid (ambiguous)
|
|
807
|
+
1 and 2 or 3 and 4
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
**Rules**:
|
|
811
|
+
|
|
812
|
+
- Use only expression numbers, `()`, `and`, `or`, `xor`
|
|
813
|
+
- Each expression number used exactly once
|
|
814
|
+
- All expressions must be included
|
|
815
|
+
- Use `()` for clear precedence
|
|
816
|
+
|
|
817
|
+
---
|
|
818
|
+
|
|
819
|
+
## Limitations & Considerations
|
|
820
|
+
|
|
821
|
+
### Execution Limits
|
|
822
|
+
|
|
823
|
+
| Limit | Value |
|
|
824
|
+
| ---------------------- | -------------------------------------- |
|
|
825
|
+
| Maximum Execution Time | 10 seconds |
|
|
826
|
+
| Performance Target | <100ms, <1000 backtracks, 0 violations |
|
|
827
|
+
| Timeout Behavior | Constraint evaluation fails |
|
|
828
|
+
|
|
829
|
+
### Data Type Limitations
|
|
830
|
+
|
|
831
|
+
- **Datetime**: Not supported as constraint model attributes
|
|
832
|
+
- **Numeric**: Must have defined domain (range or values) to avoid errors
|
|
833
|
+
- **Unused Attributes**: Cause `NullPointerException`—remove or use in
|
|
834
|
+
constraint
|
|
835
|
+
|
|
836
|
+
### Naming Restrictions
|
|
837
|
+
|
|
838
|
+
- **Supported Characters**: Unicode letters, numbers, underscores only
|
|
839
|
+
- **No Spaces**: CML variable names cannot include spaces
|
|
840
|
+
- **Special Characters**: Will cause errors
|
|
841
|
+
|
|
842
|
+
### Bundle & Relationship Limitations
|
|
843
|
+
|
|
844
|
+
- Constraints on child products require entire bundle in model
|
|
845
|
+
- Product classes imported but class attributes are not—add manually
|
|
846
|
+
- Cannot define group-level constraints in Visual Builder (use CML Editor)
|
|
847
|
+
- Duplicate relationship names overwrite association records
|
|
848
|
+
|
|
849
|
+
### Constraint Evaluation
|
|
850
|
+
|
|
851
|
+
- Constraints referencing multiple optional child instances fail if any instance
|
|
852
|
+
missing
|
|
853
|
+
- Complex constraints with nested filtering and unused variables cause
|
|
854
|
+
performance issues
|
|
855
|
+
- Cross-classification references can cause engine to auto-add instances
|
|
856
|
+
- User input order affects constraint resolution behavior
|
|
857
|
+
|
|
858
|
+
### Visual Builder Limitations
|
|
859
|
+
|
|
860
|
+
- Some CML Editor constraints not editable in Visual Builder (labeled "not
|
|
861
|
+
editable")
|
|
862
|
+
- Limitations exist for manually created bundles in CML Editor
|
|
863
|
+
|
|
864
|
+
---
|
|
865
|
+
|
|
866
|
+
## Key Notes Summary
|
|
867
|
+
|
|
868
|
+
| Topic | Note |
|
|
869
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
870
|
+
| Bundle Requirements | Constraints on child products require entire bundle in model |
|
|
871
|
+
| Compilation Flow | CML → constraint model → constraint engine → compliant configurations |
|
|
872
|
+
| Visual Builder ↔ CML | Bidirectional; constraint names appear as comments in CML |
|
|
873
|
+
| Availability | Not available in Government Cloud or EU Operating Zone |
|
|
874
|
+
| Revenue Cloud Mapping | Types = products/bundles/components/classes; Variables = fields/attributes; Relationships = bundle structure |
|
|
875
|
+
| Associations Required | Type + relationship associations connect CML to catalog records |
|
|
876
|
+
| Permission Sets | "Product Configuration Constraints Designer" for creating/managing models |
|
|
877
|
+
| Context Definitions | Specify context (e.g., `InsuranceContext`) when creating models for external variable mapping |
|