@wix/agent-skills 1.12.0 → 1.13.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.
Files changed (37) hide show
  1. package/README.md +4 -0
  2. package/package.json +1 -1
  3. package/skills/wix-app/references/data-collection/WIX_DATA.md +10 -0
  4. package/skills/wix-design-system/SKILL.md +3 -1
  5. package/skills/wix-manage/SKILL.md +32 -54
  6. package/skills/wix-manage/references/ecommerce/api-recommendation-tracking.md +3 -2
  7. package/skills/wix-manage/references/ecommerce/ecom-load-context.md +144 -0
  8. package/skills/wix-manage/references/ecommerce/ecom-pricing.md +84 -0
  9. package/skills/wix-manage/references/ecommerce/ecom-shipping.md +64 -0
  10. package/skills/wix-manage/references/ecommerce/{setup-coupons.md → pricing-promotions/ecom-pricing-create-coupon.md} +20 -6
  11. package/skills/wix-manage/references/ecommerce/{setup-discount-rules.md → pricing-promotions/ecom-pricing-create-discount-rule.md} +31 -1
  12. package/skills/wix-manage/references/ecommerce/{flow-bundle-and-save.md → pricing-promotions/ecom-pricing-flow-bundle-and-save.md} +11 -52
  13. package/skills/wix-manage/references/ecommerce/{flow-seasonal-promotion.md → pricing-promotions/ecom-pricing-flow-seasonal-promotion.md} +17 -57
  14. package/skills/wix-manage/references/ecommerce/{flow-stock-mover.md → pricing-promotions/ecom-pricing-flow-stock-mover.md} +28 -70
  15. package/skills/wix-manage/references/ecommerce/{flow-upsell-boost.md → pricing-promotions/ecom-pricing-flow-upsell-boost.md} +15 -68
  16. package/skills/wix-manage/references/ecommerce/{goal-clear-inventory.md → pricing-promotions/ecom-pricing-goal-clear-inventory.md} +22 -13
  17. package/skills/wix-manage/references/ecommerce/{goal-drive-cross-sells.md → pricing-promotions/ecom-pricing-goal-drive-cross-sells.md} +26 -8
  18. package/skills/wix-manage/references/ecommerce/{goal-increase-aov.md → pricing-promotions/ecom-pricing-goal-increase-aov.md} +32 -25
  19. package/skills/wix-manage/references/ecommerce/{goal-seasonal-revenue.md → pricing-promotions/ecom-pricing-goal-seasonal-revenue.md} +21 -8
  20. package/skills/wix-manage/references/ecommerce/{troubleshoot-discount-not-applying.md → pricing-promotions/ecom-pricing-troubleshoot-not-applying.md} +1 -1
  21. package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +23 -47
  22. package/skills/wix-manage/references/ecommerce/{api-shipping.md → shipping/ecom-shipping-api.md} +4 -3
  23. package/skills/wix-manage/references/ecommerce/{flow-fix-coverage-gaps.md → shipping/ecom-shipping-fix-coverage.md} +23 -17
  24. package/skills/wix-manage/references/ecommerce/{flow-add-free-shipping.md → shipping/ecom-shipping-free-shipping.md} +23 -18
  25. package/skills/wix-manage/references/ecommerce/{flow-optimize-shipping-rates.md → shipping/ecom-shipping-optimize-rates.md} +19 -16
  26. package/skills/wix-manage/references/ecommerce/{setup-store-pickup-location.md → shipping/ecom-shipping-setup-pickup.md} +12 -10
  27. package/skills/wix-manage/references/ecommerce/{setup-shipping-rates.md → shipping/ecom-shipping-setup-rates.md} +1 -2
  28. package/skills/wix-manage/references/ecommerce/{setup-shipping-regions.md → shipping/ecom-shipping-setup-regions.md} +1 -2
  29. package/skills/wix-manage/references/sites/query-sites.md +104 -32
  30. package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +0 -147
  31. package/skills/wix-manage/references/ecommerce/guardrail-discount-conflicts.md +0 -118
  32. package/skills/wix-manage/references/ecommerce/guardrail-margin-protection.md +0 -88
  33. package/skills/wix-manage/references/ecommerce/guardrail-rate-pricing-sanity.md +0 -108
  34. package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +0 -124
  35. package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +0 -298
  36. package/skills/wix-manage/references/ecommerce/skill-graph.md +0 -139
  37. package/skills/wix-manage/references/ecommerce/troubleshoot-checkout-delivery-dropoff.md +0 -124
@@ -1,37 +1,43 @@
1
1
  ---
2
2
  name: "Query Sites"
3
- description: Lists and queries all sites associated with a Wix account using Sites API. Covers pagination with cursor-based navigation.
3
+ description: Lists and queries all sites associated with a Wix account using the Sites API. Covers filtering, sorting, and cursor-based pagination.
4
4
  ---
5
5
  # Query Sites
6
6
 
7
- This recipe demonstrates how to list and query all sites associated with a Wix account.
7
+ This recipe demonstrates how to list and query the sites associated with a Wix account.
8
8
 
9
9
  ## Prerequisites
10
10
 
11
- - Account-level API access
12
- - Authorization for site listing permissions
11
+ - Account-level API access (authenticated as a Wix user or using an account-level API key)
12
+ - Permission `SITE_LIST.READ` (scope `SCOPE.ACC-DC-OS.READ-SITE`)
13
13
 
14
14
  ## Required APIs
15
15
 
16
16
  - **Query Sites API**: [REST](https://dev.wix.com/docs/api-reference/account-level/sites/sites/query-sites)
17
17
 
18
+ > Returns up to **100** sites per request. Use cursor paging (below) to retrieve more.
19
+
18
20
  ---
19
21
 
20
- ## Query All Sites
22
+ ## Query Sites
21
23
 
22
24
  **Endpoint**: `POST https://www.wixapis.com/site-list/v2/sites/query`
23
25
 
26
+ The request takes a `query` object that supports `filter`, `sort`, and `cursorPaging`.
27
+
24
28
  **Request Body**:
25
29
  ```json
26
30
  {
27
31
  "query": {
28
- "cursorPaging": {
29
- "limit": 50
30
- }
32
+ "filter": { "editorType": "EDITOR" },
33
+ "sort": [{ "fieldName": "createdDate", "order": "ASC" }],
34
+ "cursorPaging": { "limit": 50 }
31
35
  }
32
36
  }
33
37
  ```
34
38
 
39
+ All three fields are optional — `{ "query": { "cursorPaging": { "limit": 50 } } }` lists every site.
40
+
35
41
  **Request**:
36
42
  ```bash
37
43
  curl -X POST \
@@ -40,9 +46,9 @@ curl -X POST \
40
46
  -H 'Content-Type: application/json' \
41
47
  -d '{
42
48
  "query": {
43
- "cursorPaging": {
44
- "limit": 50
45
- }
49
+ "filter": { "editorType": "EDITOR" },
50
+ "sort": [{ "fieldName": "createdDate", "order": "ASC" }],
51
+ "cursorPaging": { "limit": 50 }
46
52
  }
47
53
  }'
48
54
  ```
@@ -51,75 +57,141 @@ curl -X POST \
51
57
 
52
58
  ## Response Structure
53
59
 
60
+ The response has the sites array plus **two** paging objects: a top-level `cursorPaging`
61
+ (echoes the applied limit and the next cursor) and `metadata` (count, `cursors.next`, `hasNext`).
62
+
63
+ > ⚠️ There is **no** `pagingMetadata` field. Read paging info from `metadata`.
64
+
54
65
  ```json
55
66
  {
56
67
  "sites": [
57
68
  {
58
- "id": "site-id-123",
59
- "name": "My Website",
60
- "displayName": "My Website",
61
- "siteUrl": "https://username.wixsite.com/mywebsite",
69
+ "id": "f6061c5f-6aa3-42f8-8822-36a4981dabb2",
70
+ "htmlAppId": "70df538d-906c-44ca-9f27-c186b62f2b2b",
71
+ "name": "my-site-47",
72
+ "displayName": "My Site 47",
73
+ "createdDate": "2023-02-01T14:56:09.831Z",
74
+ "updatedDate": "2026-06-22T03:55:49.031Z",
62
75
  "published": true,
63
- "createdDate": "2024-01-15T10:30:00Z",
64
- "updatedDate": "2024-06-20T14:45:00Z"
76
+ "premium": false,
77
+ "viewUrl": "https://username.wixsite.com/my-site-47",
78
+ "editUrl": "/editor/f6061c5f-6aa3-42f8-8822-36a4981dabb2?editorSessionId=...",
79
+ "thumbnail": "/site-thumbnail/f6061c5f-6aa3-42f8-8822-36a4981dabb2",
80
+ "ownerAccountId": "e6a89eda-d100-4b2d-8a47-3040e2134497",
81
+ "contributorAccountIds": [],
82
+ "editorType": "EDITOR",
83
+ "blocked": false,
84
+ "namespace": "WIX",
85
+ "domainConnected": false,
86
+ "parentChildRole": "NONE"
65
87
  }
66
88
  ],
67
- "pagingMetadata": {
89
+ "cursorPaging": {
90
+ "limit": 50,
91
+ "cursor": "<cursor-for-next-page>"
92
+ },
93
+ "metadata": {
68
94
  "count": 50,
69
95
  "cursors": {
70
- "next": "cursor-for-next-page"
96
+ "next": "<cursor-for-next-page>"
71
97
  },
72
98
  "hasNext": true
73
99
  }
74
100
  }
75
101
  ```
76
102
 
103
+ ### Site object fields
104
+
105
+ Each entry in `sites` has these fields (from the `Site` schema):
106
+
107
+ | Field | Type | Notes |
108
+ |---|---|---|
109
+ | `id` | string | Site ID — use for site-level API calls |
110
+ | `htmlAppId` | string | Internal HTML app ID |
111
+ | `name` | string | URL slug / internal name |
112
+ | `displayName` | string | Human-readable site name |
113
+ | `createdDate` / `updatedDate` | datetime | |
114
+ | `trashedDate` | datetime | Present only if the site is in the trash |
115
+ | `published` | boolean | Whether the site is published |
116
+ | `premium` | boolean | Whether the site has a Wix Premium (paid) plan |
117
+ | `viewUrl` | string | Public site address; empty string when unpublished. **There is no `siteUrl` field.** |
118
+ | `editUrl` | string | Relative editor path; prefix with `https://manage.wix.com` to open |
119
+ | `thumbnail` | string | Relative thumbnail path |
120
+ | `ownerAccountId` | string | |
121
+ | `contributorAccountIds` | string[] | |
122
+ | `editorType` | string | e.g. `EDITOR`, `ODEDITOR` — also a valid `filter` field |
123
+ | `blocked` | boolean | |
124
+ | `folderId` / `parentId` | string | Set for sites organized in folders / parent-child setups |
125
+ | `namespace` | string | e.g. `WIX` |
126
+ | `domainConnected` | boolean | |
127
+ | `parentChildRole` | string | e.g. `NONE` |
128
+
77
129
  ---
78
130
 
79
131
  ## Pagination
80
132
 
81
- For accounts with many sites, use cursor-based pagination:
133
+ Cursor-based. Read the next cursor from `metadata.cursors.next` and stop when
134
+ `metadata.hasNext` is `false`.
135
+
136
+ > The cursor does **not** carry the page limit, and it already encodes the filter/sort
137
+ > from the first request. On follow-up pages send **only** the cursor (plus `limit` if you
138
+ > want a non-default page size) — do **not** repeat `filter` or `sort`.
82
139
 
83
- **First Request**:
140
+ **First request**:
84
141
  ```json
85
142
  {
86
143
  "query": {
87
- "cursorPaging": {
88
- "limit": 50
89
- }
144
+ "filter": { "editorType": "EDITOR" },
145
+ "sort": [{ "fieldName": "createdDate", "order": "ASC" }],
146
+ "cursorPaging": { "limit": 50 }
90
147
  }
91
148
  }
92
149
  ```
93
150
 
94
- **Next Page** (using cursor from response):
151
+ **Next page** (cursor from `metadata.cursors.next`):
95
152
  ```json
96
153
  {
97
154
  "query": {
98
155
  "cursorPaging": {
99
156
  "limit": 50,
100
- "cursor": "<cursor-from-previous-response>"
157
+ "cursor": "<metadata.cursors.next from previous response>"
101
158
  }
102
159
  }
103
160
  }
104
161
  ```
105
162
 
106
- Continue until `hasNext` is `false`.
163
+ **Loop**:
164
+ ```javascript
165
+ async function listAllSites() {
166
+ const sites = [];
167
+ let cursor = null;
168
+ do {
169
+ const cursorPaging = cursor ? { limit: 100, cursor } : { limit: 100 };
170
+ const res = await wixRequest({ query: { cursorPaging } }); // POST .../site-list/v2/sites/query
171
+ sites.push(...res.sites);
172
+ cursor = res.metadata.hasNext ? res.metadata.cursors.next : null;
173
+ } while (cursor);
174
+ return sites;
175
+ }
176
+ ```
107
177
 
108
178
  ---
109
179
 
110
180
  ## Common Use Cases
111
181
 
112
- ### List All Sites
113
- Retrieve all sites without filtering - useful for account dashboards or site selection interfaces.
182
+ ### List all sites
183
+ Omit `filter` and page through with `cursorPaging` until `metadata.hasNext` is `false`.
114
184
 
115
- ### Find a Specific Site
116
- After querying, filter results by name or ID to locate a specific site.
185
+ ### Find a specific site
186
+ Prefer server-side `filter` (e.g. `{ "editorType": "EDITOR" }`) and `sort` over fetching
187
+ everything and filtering client-side. Filterable fields match the site object (e.g. `name`,
188
+ `displayName`, `editorType`, `published`).
117
189
 
118
190
  ---
119
191
 
120
192
  ## Next Steps
121
193
 
122
194
  After finding a site:
123
- - Use the site ID for site-level API calls
195
+ - Use the site `id` for site-level API calls
124
196
  - Create new sites using [Create Site from Template](create-site-from-template.md)
125
197
  - Manage site settings and content
@@ -1,147 +0,0 @@
1
- ---
2
- name: "Goal: Reduce Cart Abandonment"
3
- description: Maps cart abandonment reduction to recovery automation KPIs. Covers abandoned cart email automation activation, missing sales detection, and eligibility thresholds. Also references shipping flows that affect checkout drop-off.
4
- layer: goal
5
- references:
6
- - name: "Flow: Fix Coverage Gaps"
7
- path: ecommerce/flow-fix-coverage-gaps.md
8
- load: false
9
- - name: "Recipe: Apply Shipping Recommendations"
10
- path: ecommerce/recipe-apply-shipping-recommendations.md
11
- load: false
12
- - name: "Setup Store Pickup Location"
13
- path: ecommerce/setup-store-pickup-location.md
14
- load: false
15
- ---
16
- # Goal: Reduce Cart Abandonment
17
-
18
- > **Related skills**:
19
- > - [Flow: Fix Coverage Gaps](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/flow-fix-coverage-gaps) — shipping coverage gaps block checkout entirely
20
- > - [Recipe: Apply Shipping Recommendations](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/recipe-apply-shipping-recommendations)
21
- > - [Setup Store Pickup Location](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/setup-store-pickup-location)
22
-
23
- Reduce checkout abandonment caused by shipping friction — coverage gaps, unexpected costs, and missing free shipping options — by optimizing the delivery step of the checkout funnel.
24
-
25
- ---
26
-
27
- ## Business Goal
28
-
29
- The merchant wants to reduce the percentage of customers who abandon checkout, specifically at the delivery/shipping step. Shipping-related friction is the leading cause of checkout abandonment, and the delivery step conversion rate (delivery_step_cvr) is the primary metric.
30
-
31
- **Benchmark:** A healthy delivery_step_cvr is approximately 65%. Stores below this benchmark have significant shipping-related friction.
32
-
33
- ---
34
-
35
- ## KPIs
36
-
37
- | KPI | Definition | How to measure | Benchmark |
38
- |---|---|---|---|
39
- | Delivery step CVR | Customers completing delivery step / customers reaching delivery step | Site metrics: delivery_step_cvr | 65% |
40
- | Cart abandonment rate | Carts created but not converted to orders / total carts | 1 - (orders / carts) | Industry avg ~70% |
41
- | Free shipping qualification rate | Orders qualifying for free shipping / total orders | Track orders meeting free shipping threshold | Higher is better |
42
- | Revenue from recovered checkouts | Incremental revenue from improved conversion | (new_cvr - old_cvr) * checkout_sessions * AOV | - |
43
-
44
- ---
45
-
46
- ## Triggers
47
-
48
- Activate this goal when the merchant expresses any of the following intents:
49
-
50
- - "cart abandonment"
51
- - "checkout drop-off"
52
- - "shipping friction"
53
- - "delivery step"
54
- - "people are leaving at checkout"
55
- - "customers not completing orders"
56
- - "why are customers abandoning"
57
- - "checkout conversion"
58
- - Any request about reducing drop-off during the purchase flow
59
-
60
- ---
61
-
62
- ## Diagnostic Questions
63
-
64
- Before recommending actions, assess the root cause of abandonment. Ask or investigate:
65
-
66
- 1. **Where are buyers dropping off?** — Is it specifically the delivery step, or payment, or earlier in the funnel?
67
- 2. **Are shipping costs visible before checkout?** — Surprise shipping costs are the #1 abandonment driver.
68
- 3. **Is there a free shipping option?** — Free shipping (even with a threshold) dramatically reduces abandonment.
69
- 4. **Are there shipping coverage gaps?** — Customers in unserved regions cannot complete checkout at all.
70
- 5. **Are shipping rates reasonable?** — Rates above 10-15% of order value cause sticker shock.
71
- 6. **Are payment methods adequate?** — Missing payment options can look like shipping-step abandonment in metrics.
72
- 7. **Are recovery emails enabled?** — Abandoned cart emails can recapture 5-15% of abandoned carts.
73
-
74
- ---
75
-
76
- ## Recommended Actions (Prioritized)
77
-
78
- Actions are ordered by impact. Address blocking issues first, then conversion drivers, then optimization.
79
-
80
- ### Priority 1: Flow: Fix Shipping Coverage Gaps (Blocking)
81
-
82
- Coverage gaps are the most critical issue — if a customer's region is not covered by any shipping option, they literally cannot complete checkout.
83
-
84
- **When to use:** When delivery profiles show regions without active shipping options, inactive regions, or missing domestic coverage.
85
-
86
- **Impact:** Removes a hard blocker. Customers in uncovered regions have 0% conversion.
87
-
88
- ### Priority 2: Flow: Add Free Shipping (Conversion Driver)
89
-
90
- Free shipping is the single most effective lever for reducing cart abandonment. Even with a minimum order threshold, offering a free shipping option significantly improves delivery step conversion.
91
-
92
- **When to use:** When the store has no free shipping option, or when the existing free shipping threshold is set too high relative to AOV.
93
-
94
- **Impact:** Typically improves delivery_step_cvr by 10-20 percentage points. The threshold should be calibrated to AOV (typically 1.2x-1.5x AOV).
95
-
96
- ### Priority 3: Flow: Optimize Shipping Rates (Sticker Shock Reduction)
97
-
98
- High shipping rates cause sticker shock even when coverage exists. Rate optimization ensures pricing is competitive and proportional to order value.
99
-
100
- **When to use:** When shipping rates are disproportionately high relative to product prices, or when rates lack tiered/conditional pricing.
101
-
102
- **Impact:** Reduces abandonment from price sensitivity. Most effective when combined with free shipping at a threshold.
103
-
104
- ---
105
-
106
- ## Measurement Plan
107
-
108
- ### Before optimization
109
-
110
- 1. Record baseline delivery_step_cvr from site metrics
111
- 2. Record current cart abandonment rate
112
- 3. Identify the specific shipping configuration state:
113
- - Number of active regions with shipping options
114
- - Presence/absence of free shipping
115
- - Average shipping rate as percentage of AOV
116
-
117
- ### During optimization (weekly monitoring for 30 days)
118
-
119
- 1. Track delivery_step_cvr weekly
120
- 2. Compare week-over-week trend
121
- 3. Monitor free shipping qualification rate (if threshold was added)
122
- 4. Check for new coverage gaps if regions were modified
123
-
124
- ### After optimization (30-day assessment)
125
-
126
- 1. Calculate CVR improvement: `new_delivery_step_cvr - baseline_delivery_step_cvr`
127
- 2. Estimate revenue recovered: `cvr_improvement * checkout_sessions * AOV`
128
- 3. Evaluate threshold effectiveness:
129
- - Free shipping qualification rate > 40% = threshold well-calibrated
130
- - Free shipping qualification rate < 10% = threshold too high, consider lowering
131
- 4. Assess whether further optimization is needed:
132
- - delivery_step_cvr >= 65% = healthy, monitor quarterly
133
- - delivery_step_cvr 50-65% = improving, continue optimization
134
- - delivery_step_cvr < 50% = investigate non-shipping causes (payment, UX)
135
-
136
- ---
137
-
138
- ## Decision Matrix
139
-
140
- | Scenario | Priority Action | Rationale |
141
- |---|---|---|
142
- | Regions without shipping options | Fix Coverage Gaps (P1) | Hard blocker — 0% conversion in uncovered regions |
143
- | No free shipping option exists | Add Free Shipping (P2) | #1 conversion driver for delivery step |
144
- | Free shipping exists but threshold too high | Add Free Shipping (recalibrate) | Lower threshold to match AOV |
145
- | High shipping rates, free shipping exists | Optimize Shipping Rates (P3) | Reduce sticker shock for below-threshold orders |
146
- | delivery_step_cvr >= 65% | No immediate action needed | Already at healthy benchmark |
147
- | Abandonment not at delivery step | Investigate other causes | Payment methods, UX, trust signals may be the issue |
@@ -1,118 +0,0 @@
1
- ---
2
- name: "Guardrail: Discount Conflicts"
3
- description: Validation rules for detecting and preventing discount stacking conflicts, coupon overlap, and unintended deep discounts before applying new promotions. Covers automatic discount rules, coupon interactions, and safe discount limits.
4
- layer: guardrail
5
- references:
6
- - name: "Troubleshoot: Discount Not Applying"
7
- path: ecommerce/troubleshoot-discount-not-applying.md
8
- load: false
9
- ---
10
- # Guardrail: Discount Conflicts
11
-
12
- > **Related skills** (read with `ReadFullDocsArticle` if needed):
13
- > - [Troubleshoot: Discount Not Applying](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/skills/troubleshoot-discount-not-applying)
14
-
15
- ## When to use this guardrail
16
-
17
- Run these checks **before** creating or updating any discount — whether automatic discount rule or coupon. Discount conflicts are one of the most common merchant mistakes — overlapping discounts silently stack and give customers a much deeper discount than intended. This is especially dangerous when **automatic discounts and coupons interact**, since merchants often forget that both mechanisms apply simultaneously.
18
-
19
- ---
20
-
21
- ## Check 1: Existing active discount rules on the same scope
22
-
23
- **Why:** Wix eCommerce stacks automatic discount rules. If a 20% catalog-wide discount and a 15% collection discount both apply to the same product, the customer may get both applied.
24
-
25
- **How to check:**
26
-
27
- 1. Query all active discount rules:
28
-
29
- **Endpoint**: `POST https://www.wixapis.com/ecom/v1/discount-rules/query`
30
-
31
- **Request**:
32
- ```json
33
- {
34
- "query": {
35
- "filter": {
36
- "active": true
37
- },
38
- "paging": {
39
- "limit": 100
40
- }
41
- }
42
- }
43
- ```
44
-
45
- 2. For each existing active rule, compare its scope against the new rule:
46
- - If both target `CATALOG` scope: **conflict** — both apply to all products
47
- - If new rule targets `CATALOG` and existing targets `COLLECTION`: **conflict** — catalog-wide includes that collection
48
- - If both target the same `COLLECTION` ID: **conflict** — same products affected
49
- - If both target the same `SPECIFIC_PRODUCTS` ID: **conflict** — same product
50
-
51
- 3. If a conflict is found, warn the merchant:
52
- > "There's already an active discount '{existingRuleName}' ({existingDiscount}%) that applies to the same products. Adding this new {newDiscount}% discount may stack, giving customers a combined discount. Would you like to deactivate the existing rule first, or proceed with both?"
53
-
54
- ---
55
-
56
- ## Check 2: Discount percentage sanity
57
-
58
- **Why:** A discount above 50% is unusual and may indicate a typo (the merchant meant 15% not 50%). A discount of 100% makes the product free.
59
-
60
- **Rules:**
61
- - Discount > 50%: Warn — "This discount is {percentage}% off. Are you sure? This means a $100 product would sell for ${100 - percentage}."
62
- - Discount = 100%: Block unless explicitly confirmed — "This would make the product free. Please confirm this is intentional."
63
- - Discount > 100%: Block — "A discount cannot exceed 100%."
64
-
65
- ---
66
-
67
- ## Check 3: Time overlap with existing promotions
68
-
69
- **Why:** Two promotions running simultaneously on overlapping products cause stacking during the overlap period.
70
-
71
- **How to check:**
72
-
73
- 1. For the new rule's `activeTimeInfo` (start/end), check if any existing active rule has an overlapping time window on the same scope.
74
- 2. Overlap exists when: `existingStart < newEnd AND existingEnd > newStart`
75
- 3. If overlap found on the same scope: warn the merchant about the overlap period.
76
-
77
- ---
78
-
79
- ## Check 4: Cross-mechanism stacking (Automatic + Coupon)
80
-
81
- **Why:** Automatic discounts and coupons stack with each other at checkout. A customer with a 20% coupon buying during a 20% automatic sale gets both applied — the effective discount is much deeper than either one alone. This is the most commonly overlooked stacking issue.
82
-
83
- **How to check:**
84
-
85
- 1. If you are creating an **automatic discount**: Query active coupons that target overlapping products/collections.
86
- 2. If you are creating a **coupon**: Query active automatic discount rules that target overlapping products/collections.
87
- 3. If overlap found, warn the merchant with the combined impact:
88
- > "You have an active {automatic discount / coupon} '{name}' ({X}% off) that applies to the same products. If you create this {coupon / automatic discount}, customers will get BOTH discounts — a combined effective discount of approximately {combined}%. Is this intentional?"
89
-
90
- **Key rule:** Only one coupon can be used per checkout, but automatic discounts have no such limit. The worst case is: multiple automatic discounts + one coupon all stacking on the same product.
91
-
92
- ---
93
-
94
- ## Check 5: Minimum profit margin
95
-
96
- **Why:** Deep discounts on low-margin products can result in selling at a loss.
97
-
98
- **Rules:**
99
- - If the merchant has provided cost/margin information, verify that the discount doesn't reduce the price below cost
100
- - If no cost information is available, warn for discounts > 40% as a general safety threshold
101
-
102
- ---
103
-
104
- ## Summary: Decision matrix
105
-
106
- | Scenario | Action |
107
- |---|---|
108
- | No conflicts found | Proceed with creating the discount |
109
- | Scope overlap with existing active automatic discount | Warn merchant, ask to deactivate existing or confirm stacking |
110
- | Cross-mechanism stacking (automatic + coupon on same scope) | Warn merchant with combined effective discount percentage |
111
- | Discount > 50% | Warn merchant, ask for confirmation |
112
- | Discount = 100% | Block unless explicitly confirmed |
113
- | Time overlap on same scope | Warn about overlap period |
114
-
115
- ## References
116
-
117
- - [Discount Rules API (Automatic Discounts)](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/extensions/discounts/discount-rules/introduction)
118
- - [Coupons API](https://dev.wix.com/docs/api-reference/business-solutions/coupons/coupons/introduction)
@@ -1,88 +0,0 @@
1
- ---
2
- name: "Guardrail: Margin Protection"
3
- description: Safety constraints for discount percentages — global discount cap, minimum margin requirements, user override protocol, and percentage sanity checks.
4
- layer: guardrail
5
- ---
6
- # Guardrail: Margin Protection
7
-
8
- ## When to apply
9
-
10
- Run before EVERY discount rule creation or update. Check both the new rule's discount AND the cumulative effect with existing active rules (stacking).
11
-
12
- ---
13
-
14
- ## Constraint 1: Global discount cap
15
-
16
- The default maximum discount percentage (`discountMargin`) is **25%**.
17
-
18
- Any discount rule that exceeds this cap should be flagged before creation:
19
-
20
- > "This discount ({pct}%) exceeds the default cap of 25%. Proceeding only because you explicitly requested it."
21
-
22
- Respect the cap unless user input explicitly overrides it.
23
-
24
- ---
25
-
26
- ## Constraint 2: Minimum margin requirement
27
-
28
- The default minimum margin percentage (`minMarginPct`) is **15%**.
29
-
30
- Never create a discount that would push the effective margin below 15% unless the user explicitly overrides this constraint.
31
-
32
- If cost data is available, calculate:
33
- - `effective_margin = (price - cost - discount_amount) / price × 100`
34
- - If `effective_margin < minMarginPct` → block and explain the margin impact.
35
-
36
- ---
37
-
38
- ## Constraint 3: Percentage sanity checks
39
-
40
- | Discount value | Action |
41
- |---|---|
42
- | Discount > 50% | Warn — "This discount is {pct}% off. A $100 product would sell for ${100 - pct}. Are you sure?" |
43
- | Discount = 100% | Block unless explicitly confirmed — "This makes the product free." |
44
- | Discount > 100% | Block always — "A discount cannot exceed 100%." |
45
-
46
- ---
47
-
48
- ## Constraint 4: User input override protocol (ABSOLUTE PRIORITY)
49
-
50
- User input overrides ALL constraints — margin caps, discount caps, naming conventions, percentage limits.
51
-
52
- **How it works:**
53
-
54
- - If the user says "50% discount" and the cap is 25%, honor 50%.
55
- - If the user says "set margin to 5%" and the minimum is 15%, honor 5%.
56
- - Document which constraints were overridden in reasoning so there is a clear audit trail.
57
-
58
- **Example reasoning output:**
59
-
60
- > "Creating a 50% discount as requested. Note: this overrides the default 25% discount cap. The effective margin on a product with 60% gross margin would drop to 10%, below the default 15% minimum margin threshold. Proceeding per explicit user instruction."
61
-
62
- ---
63
-
64
- ## Constraint 5: Stacking cumulative check
65
-
66
- When creating a new discount, also check the cumulative effect with existing active rules:
67
-
68
- 1. Query all active discount rules that overlap in scope with the new rule.
69
- 2. Calculate the combined discount percentage (accounting for multiplicative stacking).
70
- 3. If the combined discount exceeds the global cap or violates the minimum margin, warn the merchant:
71
-
72
- > "Combined with the existing '{existingRuleName}' ({existingPct}%), the total effective discount would be approximately {combinedPct}%. This exceeds the {cap}% cap / pushes margin below {minMarginPct}%."
73
-
74
- ---
75
-
76
- ## Summary: Decision matrix
77
-
78
- | Scenario | Action |
79
- |---|---|
80
- | Discount ≤ 25% and margin ≥ 15% | Proceed |
81
- | Discount > 25% but ≤ 50%, no user override | Warn, ask for confirmation |
82
- | Discount > 25%, user explicitly requested | Proceed, document override |
83
- | Discount > 50% | Warn with dollar example, ask for confirmation |
84
- | Discount = 100% | Block unless explicitly confirmed |
85
- | Discount > 100% | Block always |
86
- | Combined stacking exceeds cap | Warn about cumulative effect |
87
- | Margin drops below 15%, no user override | Block, explain margin impact |
88
- | Margin drops below 15%, user override | Proceed, document override |