toga-ai 1.0.741 → 1.0.742
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.
|
@@ -204,7 +204,11 @@ children" rule:
|
|
|
204
204
|
re-catalogs it.** The `toga2-commerce` storefront relays whatever item `GET /v2/bundles/{uuid}`
|
|
205
205
|
returns; its `catalogId = 1` filter guards standalone item search only, never bundles. So a kit
|
|
206
206
|
whose `BundleItems.itemId` points at the wrong-catalog twin makes **every checkout POST the wrong
|
|
207
|
-
item** (434 rows / 110 bundles after the 2026-08-31 fold).
|
|
207
|
+
item** (434 rows / 110 bundles after the 2026-08-31 fold). **The fix surface is the DB bundle rows
|
|
208
|
+
PLUS the serving cache, never the frontend code** — after the DB rows were restored, a **shared**
|
|
209
|
+
bundle cache (api2/`_underscore` response cache and/or a CDN in front of `/v2/bundles`) kept
|
|
210
|
+
serving the stale Agilant uuid to new checkouts (two different users still POSTed the Agilant 2427
|
|
211
|
+
uuid) until it was invalidated. See
|
|
208
212
|
[catalog-fold reversal](../workflows/catalog-fold-reversal.md) and
|
|
209
213
|
[bundle item visibility & selectability](../../../2.0/apps/toga2-commerce/features/bundle-item-visibility-and-selectability.md).
|
|
210
214
|
- **⚠ `isFulfillable` is born on the catalog-2 (Agilant) item** and propagates to the client-facing
|
|
@@ -223,6 +227,11 @@ children" rule:
|
|
|
223
227
|
[catalog-fold reversal](../workflows/catalog-fold-reversal.md).
|
|
224
228
|
|
|
225
229
|
## Change history
|
|
230
|
+
- 2026-09-02 — Corrected the `BundleItems` fix surface: restoring the DB bundle rows is **not**
|
|
231
|
+
sufficient — a **shared** server-side bundle cache (api2/`_underscore` response cache and/or a CDN
|
|
232
|
+
in front of `/v2/bundles`) kept serving the stale Agilant uuid to new checkouts until it was
|
|
233
|
+
invalidated (proven by two different users still POSTing the Agilant 2427 uuid after the DB fix).
|
|
234
|
+
Fix surface = DB bundle rows **plus** the serving cache, never the frontend code. (jcardinal)
|
|
226
235
|
- 2026-09-02 — **Resolved the flagged "distinct vs shared partNumber" tension**: the Agilant twins
|
|
227
236
|
carry **distinct** part-number variants (the `#ABA` form ≠ the plain part number, e.g.
|
|
228
237
|
`C40QYUC#ABA` vs `C40QYUC`), so table-wide `partNumber` uniqueness holds and the catalog-fold
|
|
@@ -120,13 +120,28 @@ qualifiers):
|
|
|
120
120
|
**Rehearse on a same-day full prod clone, then apply with a pre-run backup. CTO review gated the
|
|
121
121
|
approach** (rehearse-on-clone, fail-loud, customer-scoped, tenant-locked).
|
|
122
122
|
|
|
123
|
-
### Stragglers:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
`
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
### Stragglers: broken-window orders need a manual, by-id re-map (SO item + PO VendorItem)
|
|
124
|
+
Orders created **before** the data fix + cache flush stay on the Agilant twin and must be
|
|
125
|
+
re-pointed by hand — the `#ABA` twins share no part number, so neither the merge's part-number map
|
|
126
|
+
nor a partNumber-twin re-point catches them. The pattern per straggler, scoped to **pending
|
|
127
|
+
`customerId = 2` lines**:
|
|
128
|
+
1. **`SalesOrderItems.itemId`** — re-point the Agilant twin → the Compass twin.
|
|
129
|
+
2. **`PurchaseOrderItems.vendorItemId` + `cost`** (if a PO was already built) — re-point to the
|
|
130
|
+
Compass `VendorItem` (correct SKU + cost).
|
|
131
|
+
3. **`PurchaseOrders.dtSubmitted = NULL`** — so cron 2 re-transmits the PO correctly (cXML, right
|
|
132
|
+
SKU/cost).
|
|
133
|
+
|
|
134
|
+
Verified twin / VendorItem mappings this session:
|
|
135
|
+
|
|
136
|
+
| Agilant item | Compass item | Compass VendorItem | Vendor SKU | Cost |
|
|
137
|
+
|---|---|---|---|---|
|
|
138
|
+
| 2427 (`C40QYUC`) | 2157 | 3597 | 5775600 | 945.17 |
|
|
139
|
+
| 2431 (`C40QYUC-1`) | 2158 | 3598 | 7761063 | 945.17 |
|
|
140
|
+
|
|
141
|
+
PO `VendorItem` re-maps: **3845 → 3597** @ `945.17`, **3884 → 3600** @ `1627.38` (`B7HJ2UC#ABA`).
|
|
142
|
+
Orders fixed: `50312344-1`, `50312409-1`, `SA136868`, `SA136874`, plus the earlier 5 pending
|
|
143
|
+
(`SA136819`, `SA136820`, `SA136845`, `SA136852`, `SA136862`). Why a mis-mapped PO line transmits the
|
|
144
|
+
wrong SKU + cost and drops to EMAIL rather than cXML:
|
|
130
145
|
[MITS PO transmission to vendors](../features/mits-po-transmission-to-vendors.md).
|
|
131
146
|
|
|
132
147
|
## The folded `BundleItems` was the storefront's ongoing bad-order source
|
|
@@ -135,10 +150,32 @@ rows across 110 bundles**. The `toga2-commerce` storefront does **not** choose a
|
|
|
135
150
|
relays whatever item uuid `GET /v2/bundles/{uuid}` returns (`bundleItems.item.uuid`). The
|
|
136
151
|
`catalogId = 1` filter runs **only** on standalone item search (`genericApi.ts`, `FilterApi.ts`,
|
|
137
152
|
`translatedSearchApi.ts`), **never** on bundles. So a folded `BundleItems.itemId` makes **every new
|
|
138
|
-
checkout of that kit POST the Agilant item** — a fresh wrong-catalog order each time. **The fix
|
|
139
|
-
|
|
153
|
+
checkout of that kit POST the Agilant item** — a fresh wrong-catalog order each time. **The fix
|
|
154
|
+
surface is the DB bundle rows PLUS the serving cache (below) — never the frontend code.**
|
|
155
|
+
Storefront-side detail:
|
|
140
156
|
[bundle item visibility & selectability](../../../2.0/apps/toga2-commerce/features/bundle-item-visibility-and-selectability.md).
|
|
141
157
|
|
|
158
|
+
## Restoring `BundleItems` is NOT enough — a stale bundle cache kept minting bad orders
|
|
159
|
+
Even **after** `BundleItems.itemId` was restored in the DB (bundle 17 → item 2157, bundle 15 →
|
|
160
|
+
2158, verified), **new** Compass storefront orders **still** came in on the Agilant twin. Proof:
|
|
161
|
+
order **SA136874** (created 2026-09-02 13:03:16 by user **83091**) — its incoming
|
|
162
|
+
`POST /v2/sales-orders` in `Logs_Compass.Api` carried the **Agilant** item 2427 uuid
|
|
163
|
+
(`88bd4bb2…`), not the Compass 2157 uuid — while the DB bundle already pointed at 2157.
|
|
164
|
+
**SA136868** (11:25) showed the same. Because **multiple distinct users** got the stale item, this
|
|
165
|
+
is a **shared server-side cache** (the api2/`_underscore` response cache and/or a CDN in front of
|
|
166
|
+
`/v2/bundles`), **not** a per-browser one — so the DB fix is invisible to shoppers until the cache
|
|
167
|
+
is flushed. The developer invalidated the **front-end cache**, which stopped the new bad orders.
|
|
168
|
+
**Durable rule: a catalog-fold reversal is not complete until the bundle/item cache is invalidated
|
|
169
|
+
across every layer — front-end, api2/`_underscore` response cache, and any CDN in front of
|
|
170
|
+
`/v2/bundles`.**
|
|
171
|
+
|
|
172
|
+
**Operational sequence (do it in this order):**
|
|
173
|
+
1. Fix the data (restore `BundleItems`, re-point stragglers — below).
|
|
174
|
+
2. **Invalidate the bundle/item cache** (front-end + api2/`_underscore` + any CDN on `/v2/bundles`).
|
|
175
|
+
3. Confirm new incoming `POST /v2/sales-orders` in `Logs_Compass.Api` stop carrying the Agilant uuid.
|
|
176
|
+
4. **Only then re-enable vendor transmission (cron 2)** — otherwise it transmits the still-bad
|
|
177
|
+
post-fix orders.
|
|
178
|
+
|
|
142
179
|
## The NetSuite→TOGa sync is NOT the source of new cust-2 bad orders (suspect ruled out)
|
|
143
180
|
The 1.0 NetSuite→TOGa TOGaSupply sync (`worker/crons/toga2/netsuite/`,
|
|
144
181
|
`App_Api_Toga2::syncSalesOrderFromNetsuite`, `library/app/api/toga2.php` ~L752) writes **only the
|
|
@@ -172,6 +209,14 @@ rule still holds: `cust 2` → catalog 1; `cust 1` and `cust 3` → catalog 2.
|
|
|
172
209
|
nothing. Restore `BundleItems` to stop new wrong-catalog checkouts. (The sync still *creates
|
|
173
210
|
items* in catalog 2 — that is the original duplicate-item source, see the
|
|
174
211
|
[two-catalog item model](../features/item-catalogs-and-duplicate-items.md).)
|
|
212
|
+
- **The reversal is NOT complete until the bundle/item cache is invalidated.** After `BundleItems`
|
|
213
|
+
was restored in the DB, new cust-2 checkouts kept POSTing the Agilant uuid because a **shared
|
|
214
|
+
server-side cache** (api2/`_underscore` response cache and/or a CDN in front of `/v2/bundles`)
|
|
215
|
+
still served the stale bundle — proven by two different users (SA136868, SA136874) getting the same
|
|
216
|
+
stale item after the DB fix. Sequence: fix data → **invalidate cache (front-end + api2/`_underscore`
|
|
217
|
+
+ any CDN on `/v2/bundles`)** → confirm incoming `/v2/sales-orders` POSTs stop carrying the Agilant
|
|
218
|
+
uuid → **only then re-enable cron 2**. The fix surface is the DB bundle rows **plus** the serving
|
|
219
|
+
cache — never the frontend code.
|
|
175
220
|
- **Never `UPDATE IGNORE` + delete-leftover for a catalog operation** — it permanently deletes
|
|
176
221
|
collision rows and cannot be reversed. Use FK-checks-ON, fail-loud, single transaction.
|
|
177
222
|
|
|
@@ -207,6 +252,21 @@ catalog-1 items were folded into catalog-2 **AND** storefront/transmit depends o
|
|
|
207
252
|
NULL-`assetType` order lines alone are **not** damage (Prudential and Quad show that as normal).
|
|
208
253
|
|
|
209
254
|
## Change history
|
|
255
|
+
- 2026-09-02 — **CRITICAL: restoring `BundleItems` in the DB was not enough — a stale shared bundle
|
|
256
|
+
cache kept minting bad orders.** After the DB bundle rows were restored (bundle 17 → 2157, 15 →
|
|
257
|
+
2158), new cust-2 checkouts still POSTed the Agilant uuid: order SA136874 (13:03, user 83091) and
|
|
258
|
+
SA136868 (11:25) each carried the Agilant 2427 uuid on the incoming `/v2/sales-orders` while the DB
|
|
259
|
+
bundle already pointed at 2157. Two different users → a **shared server-side cache** (api2/
|
|
260
|
+
`_underscore` response cache and/or a CDN in front of `/v2/bundles`), not per-browser; the developer
|
|
261
|
+
invalidated the front-end cache to stop it. Added the rule that a fold reversal is incomplete until
|
|
262
|
+
the bundle/item cache is invalidated across every layer, and the operational order (fix data →
|
|
263
|
+
invalidate cache → confirm POSTs clean → only then re-enable cron 2). Extended the straggler cleanup
|
|
264
|
+
into the full by-id pattern for broken-window orders (re-point `SalesOrderItems.itemId`
|
|
265
|
+
Agilant-twin→Compass-twin, `PurchaseOrderItems.vendorItemId`+cost to the Compass VendorItem, clear
|
|
266
|
+
`PurchaseOrders.dtSubmitted` so cron 2 re-transmits): 2427→2157 / VI 3597 / SKU 5775600 / $945.17,
|
|
267
|
+
2431→2158 / VI 3598 / SKU 7761063 / $945.17; PO VI 3845→3597 @945.17, 3884→3600 @1627.38; orders
|
|
268
|
+
fixed 50312344-1, 50312409-1, SA136868, SA136874 + the earlier 5 pending
|
|
269
|
+
(SA136819/820/845/852/862). (jcardinal)
|
|
210
270
|
- 2026-09-02 — **Completed the reversal and root-caused the rest of the incident.** Recorded that
|
|
211
271
|
the first reversal was **incomplete** — it restored `Items`/`VendorItems`/`VendorItemCosts` and
|
|
212
272
|
re-pointed only `customerId = 2` `SalesOrderItems`, leaving **10 tables** folded (cust-1/cust-3
|
package/package.json
CHANGED