toga-ai 1.0.721 → 1.0.722
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/knowledge/1.0/apps/worker/workflows/netsuite-duplicate-items-dedup.md +2 -2
- package/knowledge/clients/compass-usa/INDEX.md +1 -2
- package/knowledge/clients/compass-usa/features/item-catalogs-and-duplicate-items.md +51 -3
- package/knowledge/clients/compass-usa/features/mits-sales-order-transmission-alerting.md +2 -2
- package/knowledge/clients/compass-usa/profile.md +0 -1
- package/knowledge/clients/compass-usa/workflows/catalog-fold-reversal.md +3 -3
- package/package.json +1 -1
- package/knowledge/clients/compass-usa/features/two-catalog-item-model.md +0 -103
|
@@ -15,7 +15,7 @@ related:
|
|
|
15
15
|
- ../features/netsuite-togasupply-per-client-sync.md
|
|
16
16
|
- ../../library/features/netsuite-suiteql-rest-shim.md
|
|
17
17
|
- ../../../clients/compass-usa/workflows/catalog-fold-reversal.md
|
|
18
|
-
- ../../../clients/compass-usa/features/
|
|
18
|
+
- ../../../clients/compass-usa/features/item-catalogs-and-duplicate-items.md
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
## Summary
|
|
@@ -39,7 +39,7 @@ after the code fix is deployed.
|
|
|
39
39
|
> running this on any client, confirm the client is **single-catalog**; if not, the dedup must be
|
|
40
40
|
> **catalog-aware** (dedup within a catalog, never across). See the Compass
|
|
41
41
|
> [catalog-fold reversal](../../../clients/compass-usa/workflows/catalog-fold-reversal.md) and
|
|
42
|
-
> [
|
|
42
|
+
> [Compass item catalogs & duplicate items](../../../clients/compass-usa/features/item-catalogs-and-duplicate-items.md).
|
|
43
43
|
|
|
44
44
|
## Root cause — why the duplicates existed at all
|
|
45
45
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
| [Compass ASN → ItemFulfillment Auto-Creation](features/asn-to-item-fulfillment.md) | 2.0 | For Compass USA, posting an AdvanceShippingNotice (ASN) auto-creates the ItemFulfillment (IF) on the upstream SalesOrder. | _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Model/Compass/PurchaseOrder.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client_Compass/2026-06-11 - AsnItemTrackingNumberAcl.sql, dbchanges2/Client_Compass/2026-06-15b - BackfillSA132781ItemFulfillmentTracking.sql, dbchanges2/Client_Compass/2026-06-16 - CleanupSA132763CrossLineTracking.sql, dbchanges2/Client_Compass/2026-06-16b - CleanupSA132743CrossLineTracking.sql, dbchanges2/Client_Compass/2026-06-16c - BackfillSA132763C40QYUCTracking.sql, dbchanges2/Client_Compass/2026-06-18a - CleanupSA132898DuplicateTracking.sql, dbchanges2/Client_Compass/2026-06-18b - CleanupSA132881DuplicateTracking.sql, dbchanges2/Client_Compass/2026-07-02a - FixSA133377TrackingSerialAndDuplicateIF.sql |
|
|
7
7
|
| [Cost Centers — Unit Locations, numeric-only policy](features/cost-centers.md) | 2.0 | A Compass "cost center" — the value a user picks in commerce and that lands on an order — is **not** a `CostCenters` row. | toga2-commerce/src/pages/Cart/api/CartApi.ts, worker1.5/crons/toga2/compass/import_locations.php, _underscore/Model/Compass/SalesOrder.php, api2/Component/Api/V2/V2.php, dbchanges2/Client_Compass/2026-07-06 - RemoveNonNumericCostCenters.sql |
|
|
8
8
|
| [Compass isFulfillable — Data Quality & the Type-Derived Rule](features/isfulfillable-data-quality-and-type-rule.md) | 2.0 | A **prod-data investigation (2026-08-12, read-only)** into why so many Compass storefront lines still have a dead **Qty Fulfilled** cell. | _underscore/Model/Client/Item.php, library/app/api/toga2.php, worker/crons/toga2/netsuite/backfill_isfulfillable_all_clients.php, dbchanges2/Core/2026-07-17 - RegisterItemIsFulfillableInterceptors.sql, toga2-supply/src/pages/Orders/view/OrderView/components/sections/OrderItemsTableSection.tsx |
|
|
9
|
-
| [Compass Item Catalogs (Compass vs Agilant) & the Duplicate Items the NetSuite Sync Creates](features/item-catalogs-and-duplicate-items.md) | 1.0 | `Client_Compass.Items` is **split across catalogs by which pipeline created the item**, and the two halves are routinely mistaken for one. | library/app/api/toga2.php, _underscore/Model/Compass/PurchaseOrder.php, _underscore/Model/Compass/Usa/PurchaseOrder.php, worker/crons/toga2/netsuite/common_sync_togasupply.php, worker/crons/toga2/compass/workflow/3a_import_office_depot_purchase_orders.php |
|
|
9
|
+
| [Compass Item Catalogs (Compass vs Agilant) & the Duplicate Items the NetSuite Sync Creates](features/item-catalogs-and-duplicate-items.md) | 1.0 | `Client_Compass.Items` is **split across catalogs by which pipeline created the item**, and the two halves are routinely mistaken for one. | library/app/api/toga2.php, _underscore/Model/Compass/PurchaseOrder.php, _underscore/Model/Compass/Usa/PurchaseOrder.php, worker/crons/toga2/netsuite/common_sync_togasupply.php, worker/crons/toga2/compass/workflow/3a_import_office_depot_purchase_orders.php, worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php |
|
|
10
10
|
| [Compass: Item-Fulfillment TableViews (for-sales-order-items & for-sales-orders, tracking via bridge)](features/item-fulfillment-tracking-tableview.md) | 2.0 | Two sibling Compass TableViews in `Client_Compass` display fulfilled items in toga2-supply, both driven by `TableViews` / `TableViewJoins` / `TableViewFields` c | dbchanges2/Client_Compass/2026-06-10 - ItemFulfillmentsForSalesOrderItemsTableView.sql, dbchanges2/Client_Compass/2026-06-11 - ItemFulfillmentsForSalesOrdersTableView.sql, dbchanges2/Client_Compass/2026-06-15a - FixItemFulfillmentTrackingNumberJoins.sql, dbchanges2/Client/2026-07-15a - ExcludeFeeItemsFromItemFulfillmentsForSalesOrdersView.sql |
|
|
11
11
|
| [Compass MITS PO → SO Item Linking](features/mits-po-to-so-item-linking.md) | 2.0 | MITS sends Compass inbound Purchase Orders (`POST /v2/purchase-orders`) against a Sales Order (`mitsSalesOrder`). | _underscore/Model/Compass/PurchaseOrder.php, _underscore/Model/Compass/Usa/PurchaseOrder.php, api2/Component/Api/V2/V2.php, worker/crons/toga2/compass/workflow/3a_import_office_depot_purchase_orders.php |
|
|
12
12
|
| [Compass MITS PO Transmission to Vendors](features/mits-po-transmission-to-vendors.md) | 2.0 | The 1.0 worker cron `2_transmit_mits_purchase_orders_to_vendors.php` transmits Compass PurchaseOrders to their vendors (Office Depot, Strategic Systems, Compass | worker/crons/toga2/compass/workflow/2_transmit_mits_purchase_orders_to_vendors.php, worker/crons/toga2/compasscanada/workflow/2_transmit_mits_purchase_orders_to_vendors.php, library/app/client/compass.php |
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
| [Persona Model & Levy-Sector Gating (worker2 PEOPLE cron)](features/persona-model-and-levy-gating.md) | 2.0 | Compass USA catalogue visibility is driven by **personas** in `Client_Compass`. | worker2/Worker/Client/Compass/PeopleFile.php |
|
|
22
22
|
| [Compass Sales-Order Line-Number Renumbering (and why it hangs off the SO hooks)](features/sales-order-line-renumbering.md) | 2.0 | Compass sales-order lines must stay numbered **1..N with no gaps** after any add, edit, or delete — downstream MITS/PO linking reads `lineNumber` as an identity | _underscore/Model/Compass/SalesOrderItem.php, _underscore/Model/Compass/SalesOrder.php |
|
|
23
23
|
| [Stranded Approval Reassignment (repointing approvals off dead duplicate Compass Users rows)](features/stranded-approval-reassignment.md) | 2.0 | A Compass employee who leaves and comes back after more than `CONTACT_UNLINK_GRACE_DAYS` (5) is **inserted as a brand-new `Users` row** by the PEOPLE importer i | _underscore/Model/Compass/ApprovalDecision.php, worker2/Worker/Client/Compass/ApprovalReassignment.php, worker2/Worker/Client/Compass/PeopleFile.php |
|
|
24
|
-
| [Compass USA — intentional two-catalog Item model (store vs Agilant procurement)](features/two-catalog-item-model.md) | 2.0 | Compass USA keeps its items in **two intentional catalogs**, and the **same part number legitimately exists once per catalog**. | library/app/api/toga2.php, worker/crons/toga2/netsuite/common_sync_togasupply.php, worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php |
|
|
25
24
|
| [Compass USA](profile.md) | 2.0 | Compass USA is a TOGA client running a multi-tier supply-chain commerce operation. | |
|
|
26
25
|
| [Compass USA — reversing the 199-item catalog fold (MITS outage recovery)](workflows/catalog-fold-reversal.md) | 2.0 | The **root cause** of the Compass MITS transmission outage (the `assetType`-NULL and duplicate-vendor symptoms) was an ad-hoc cross-client **duplicate-items mer | test/team/2.0 deployment/duplicate_items_merge_ALL_CLIENTS.sql, test/team/2.0 deployment/duplicate_items_merge_analysis.sql, worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php, library/app/api/toga2.php, worker/crons/toga2/netsuite/common_sync_togasupply.php |
|
|
27
26
|
| [Compass Cross-Kit Bundle Corruption — Detection & Repair](workflows/cross-kit-bundle-corruption.md) | 2.0 | A frontend regression in `toga2-commerce`'s edit-order bundle submission mis-attributed bundle (kit) line items and **fees/warranties** to the **wrong kit**, pe | src/api/syncSalesOrderItemsFromLocalStorageCartToApi.ts |
|
|
@@ -7,19 +7,22 @@ client: compass-usa
|
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
9
|
updated: 2026-09-01
|
|
10
|
-
owners: ["bala"]
|
|
10
|
+
owners: ["bala", "jcardinal"]
|
|
11
11
|
files:
|
|
12
12
|
- library/app/api/toga2.php
|
|
13
13
|
- _underscore/Model/Compass/PurchaseOrder.php
|
|
14
14
|
- _underscore/Model/Compass/Usa/PurchaseOrder.php
|
|
15
15
|
- worker/crons/toga2/netsuite/common_sync_togasupply.php
|
|
16
16
|
- worker/crons/toga2/compass/workflow/3a_import_office_depot_purchase_orders.php
|
|
17
|
+
- worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php
|
|
17
18
|
related:
|
|
18
19
|
- odp-edi-850-item-resolution.md
|
|
19
20
|
- mits-po-to-so-item-linking.md
|
|
21
|
+
- mits-sales-order-transmission-alerting.md
|
|
20
22
|
- isfulfillable-data-quality-and-type-rule.md
|
|
21
23
|
- ../workflows/odp-duplicate-po-line-cleanup.md
|
|
22
24
|
- ../workflows/odp-order-pipeline-to-netsuite.md
|
|
25
|
+
- ../workflows/catalog-fold-reversal.md
|
|
23
26
|
- ../profile.md
|
|
24
27
|
- ../../../1.0/apps/library/features/netsuite-item-isfulfillable-sync.md
|
|
25
28
|
- ../../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md
|
|
@@ -62,6 +65,26 @@ the same list — they are **two different source systems' views** of overlappin
|
|
|
62
65
|
(`vendorId = 1`) point at **catalog-2** items. Filtering the ODP item lookup to catalog 1 therefore
|
|
63
66
|
breaks a large slice of the Office Depot pipeline outright.
|
|
64
67
|
|
|
68
|
+
## Customer → catalog rule (which catalog an order resolves to)
|
|
69
|
+
|
|
70
|
+
Confirmed by the developer and by pre-merge data (2026-08-31):
|
|
71
|
+
|
|
72
|
+
- **`customerId = 2` (Compass) sales orders → catalog 1 (Compass/store) items.**
|
|
73
|
+
- Everyone else — **Office Depot `customerId = 1`, Agilant `customerId = 3`** → catalog 2
|
|
74
|
+
(Agilant) items.
|
|
75
|
+
|
|
76
|
+
Pre-merge snapshot: `customerId = 2` order lines were ~100% on catalog 1 (**182,787 vs 1**).
|
|
77
|
+
The store (catalog-1) item is the one that carries the MITS classification
|
|
78
|
+
(`assetType`/`category`/`type`); a Compass line that resolves to a catalog-2 Agilant item has
|
|
79
|
+
NULL classification and **MITS rejects the whole order** (HTTP 400 "The AssetType field is
|
|
80
|
+
required"). So this mapping is load-bearing.
|
|
81
|
+
|
|
82
|
+
**⚠ Every catalog re-point MUST be scoped by `customerId`.** An ad-hoc
|
|
83
|
+
`UPDATE ... WHERE itemId = <agilantId>` with no customer filter wrongly moved **687
|
|
84
|
+
Office-Depot lines** onto a Compass item and had to be corrected. This is the durable lesson
|
|
85
|
+
from the 2026-08-31 catalog-fold reversal — see
|
|
86
|
+
[catalog-fold reversal](../workflows/catalog-fold-reversal.md).
|
|
87
|
+
|
|
65
88
|
## Where the "Agilant" catalog is hardcoded
|
|
66
89
|
|
|
67
90
|
The 1.0 side writes and reads catalog 2 **by name**, in four places — none of them configurable:
|
|
@@ -93,13 +116,21 @@ Plus `-1` / `-2` suffixed copies: items **2431, 2432, 2443, 2653**.
|
|
|
93
116
|
**Two distinct duplicate shapes, and only the first exists in prod today:**
|
|
94
117
|
- **Different part numbers** (the table above) — the two rows never match on part number, so each
|
|
95
118
|
pipeline keeps using "its own" item and quantities/fulfillments diverge. This is the live shape.
|
|
96
|
-
- **Same part number, two catalogs — NOT present in prod.** This is the shape behind
|
|
97
|
-
[dual-catalog duplicate PO-line bug](../workflows/odp-duplicate-po-line-cleanup.md) (4,886
|
|
119
|
+
- **Same part number, two catalogs — NOT present in prod (2026-09-01).** This is the shape behind
|
|
120
|
+
the [dual-catalog duplicate PO-line bug](../workflows/odp-duplicate-po-line-cleanup.md) (4,886
|
|
98
121
|
duplicate PO lines across 1,320 Office Depot POs when that was investigated).
|
|
99
122
|
**Verified on prod `Client_Compass` 2026-09-01: zero part numbers are duplicated at all, and zero
|
|
100
123
|
span more than one catalog.** It matters only as a thing to re-check, because a part-number lookup
|
|
101
124
|
with no catalog filter has **no ambiguity check on its exact-match branch**
|
|
102
125
|
([850 line-item resolution](odp-edi-850-item-resolution.md)).
|
|
126
|
+
**⚠ Unresolved tension — reconcile before relying on "partNumber is unique."** The
|
|
127
|
+
[2026-08-31 catalog-fold reversal](../workflows/catalog-fold-reversal.md) is recorded as having
|
|
128
|
+
folded **199 catalog-1 items into their catalog-2 Agilant canonical by `UPPER(partNumber)`**,
|
|
129
|
+
which requires those 199 to have shared a part number across the two catalogs pre-merge, and the
|
|
130
|
+
reversal restored them. That does not square with "zero part numbers span two catalogs" verified
|
|
131
|
+
the same day. Confirm on prod whether the restored catalog-1 twins carry **distinct** part numbers
|
|
132
|
+
(e.g. the `#B1H` / `-S` variant forms above) or genuinely-shared ones before treating table-wide
|
|
133
|
+
`partNumber` uniqueness as settled.
|
|
103
134
|
|
|
104
135
|
## "Who changed this part number?" — the audit trail says nobody
|
|
105
136
|
|
|
@@ -143,8 +174,25 @@ children" rule:
|
|
|
143
174
|
- **⚠ Do not "fix" a mismatch by creating an item** so a string matches. That is how the junk items
|
|
144
175
|
got there in the first place — fix the `VendorItems` mapping instead
|
|
145
176
|
([850 line-item resolution](odp-edi-850-item-resolution.md)).
|
|
177
|
+
- **The NetSuite sync UPDATE path never touches `assetType`/`category`/`type`.** `getCreateItem`
|
|
178
|
+
stamps them as NULL on create (so a **new** Agilant item is born unclassified → a Compass line
|
|
179
|
+
on it fails MITS), but the sync UPDATE only PUTs `inventoryType` / `isFulfillable`. Practical
|
|
180
|
+
consequence: once classification is set on an item it is **durable across sync runs** (the sync
|
|
181
|
+
will not revert it) — the exposure is only newly-created items. This is why a store-catalog data
|
|
182
|
+
repair survives, but the Compass NetSuite sync must still be **stopped before** any catalog
|
|
183
|
+
re-point (it re-creates Compass order lines on Agilant items). See
|
|
184
|
+
[catalog-fold reversal](../workflows/catalog-fold-reversal.md).
|
|
146
185
|
|
|
147
186
|
## Change history
|
|
187
|
+
- 2026-09-01 — Folded in the **customer → catalog rule** (`customerId = 2` → catalog 1, everyone
|
|
188
|
+
else → catalog 2; verified 182,787 vs 1 pre-merge) and the mandatory `customerId` scope on any
|
|
189
|
+
catalog re-point (an unscoped one moved 687 Office-Depot lines). Added that the NetSuite sync
|
|
190
|
+
UPDATE path never touches `assetType`/`category`/`type` (so classification is durable once set;
|
|
191
|
+
only new items are born unclassified) and that the Compass sync must be stopped before a re-point.
|
|
192
|
+
Cross-linked the [catalog-fold reversal](../workflows/catalog-fold-reversal.md) and flagged an
|
|
193
|
+
**unresolved tension**: that reversal folded/restored 199 catalog-1 items by `UPPER(partNumber)`,
|
|
194
|
+
which implies shared cross-catalog part numbers pre-merge and does not square with the same-day
|
|
195
|
+
"partNumber is unique table-wide" verification — needs a prod re-check. (jcardinal)
|
|
148
196
|
- 2026-09-01 — Recorded a **second, independent victim of the same catalog-scoping trap, on the 2.0
|
|
149
197
|
side**: `_Model_Compass_PurchaseOrder::handleMrOrder` references MR sales-order items with a
|
|
150
198
|
hardcoded `COMPASS_CATALOG_UUID` (`961dbcbc…` = catalog **1**), which is the mirror image of the
|
|
@@ -17,7 +17,7 @@ files:
|
|
|
17
17
|
- dbchanges2/Logs/2026-08-04a - MITS rejection business recipients.sql
|
|
18
18
|
related:
|
|
19
19
|
- mits-po-transmission-to-vendors.md
|
|
20
|
-
-
|
|
20
|
+
- item-catalogs-and-duplicate-items.md
|
|
21
21
|
- ../workflows/catalog-fold-reversal.md
|
|
22
22
|
- ../../compass-canada/profile.md
|
|
23
23
|
- ../../../2.0/apps/worker2/features/error-escalation-cron.md
|
|
@@ -134,7 +134,7 @@ order lines resolved to Agilant items that have no store classification. The sam
|
|
|
134
134
|
their VendorItems, which is what triggered the SQL 1242 abort (see gotchas below). Full root
|
|
135
135
|
cause + the reversal playbook: [catalog-fold reversal](../workflows/catalog-fold-reversal.md).
|
|
136
136
|
Compass keeps two intentional catalogs and the customer→catalog rule is load-bearing — see
|
|
137
|
-
[
|
|
137
|
+
[Compass item catalogs & duplicate items](./item-catalogs-and-duplicate-items.md).
|
|
138
138
|
|
|
139
139
|
**Fix the data:** assign the correct `assetTypeId` to the affected `Client_Compass.Items`
|
|
140
140
|
(business owns the mapping), and check whether the NetSuite item sync owns `assetType` — if it
|
|
@@ -31,7 +31,6 @@ related:
|
|
|
31
31
|
- workflows/granting-persona-bundle-access.md
|
|
32
32
|
- workflows/granting-navigation-access.md
|
|
33
33
|
- features/mits-sales-order-transmission-alerting.md
|
|
34
|
-
- features/two-catalog-item-model.md
|
|
35
34
|
- workflows/catalog-fold-reversal.md
|
|
36
35
|
- features/asn-to-item-fulfillment.md
|
|
37
36
|
- features/order-fulfillment-status-per-line.md
|
|
@@ -14,7 +14,7 @@ files:
|
|
|
14
14
|
- library/app/api/toga2.php
|
|
15
15
|
- worker/crons/toga2/netsuite/common_sync_togasupply.php
|
|
16
16
|
related:
|
|
17
|
-
- ../features/
|
|
17
|
+
- ../features/item-catalogs-and-duplicate-items.md
|
|
18
18
|
- ../features/mits-sales-order-transmission-alerting.md
|
|
19
19
|
- ../../../1.0/apps/worker/workflows/netsuite-duplicate-items-dedup.md
|
|
20
20
|
---
|
|
@@ -25,7 +25,7 @@ The **root cause** of the Compass MITS transmission outage (the `assetType`-NULL
|
|
|
25
25
|
duplicate-vendor symptoms) was an ad-hoc cross-client **duplicate-items merge** that wrongly
|
|
26
26
|
folded Compass's **two intentional catalogs** together. This workflow records the damage and
|
|
27
27
|
the **durable playbook** used to reverse it. See the
|
|
28
|
-
[two-catalog item model](../features/
|
|
28
|
+
[two-catalog item model](../features/item-catalogs-and-duplicate-items.md) for why the catalogs are
|
|
29
29
|
intentional.
|
|
30
30
|
|
|
31
31
|
## What broke (root cause)
|
|
@@ -91,7 +91,7 @@ damage.**
|
|
|
91
91
|
- **Stop the Compass NetSuite sync first.** The sync re-creates Compass order lines on Agilant
|
|
92
92
|
items, so the reversal is only durable if the sync is stopped; re-enabling risks re-pointing
|
|
93
93
|
new/re-synced orders back to Agilant (2 lines seen after a test re-enable). See the
|
|
94
|
-
[two-catalog item model](../features/
|
|
94
|
+
[two-catalog item model](../features/item-catalogs-and-duplicate-items.md).
|
|
95
95
|
- **Never `UPDATE IGNORE` + delete-leftover for a catalog operation** — it permanently deletes
|
|
96
96
|
collision rows and cannot be reversed. Use FK-checks-ON, fail-loud, single transaction.
|
|
97
97
|
|
package/package.json
CHANGED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Compass USA — intentional two-catalog Item model (store vs Agilant procurement)
|
|
3
|
-
framework: "2.0"
|
|
4
|
-
project: _Underscore
|
|
5
|
-
client: compass-usa
|
|
6
|
-
type: client-feature
|
|
7
|
-
status: active
|
|
8
|
-
updated: 2026-09-01
|
|
9
|
-
owners: ["jcardinal"]
|
|
10
|
-
files:
|
|
11
|
-
- library/app/api/toga2.php
|
|
12
|
-
- worker/crons/toga2/netsuite/common_sync_togasupply.php
|
|
13
|
-
- worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php
|
|
14
|
-
related:
|
|
15
|
-
- ../workflows/catalog-fold-reversal.md
|
|
16
|
-
- ./mits-sales-order-transmission-alerting.md
|
|
17
|
-
- ../../../1.0/apps/worker/workflows/netsuite-duplicate-items-dedup.md
|
|
18
|
-
- ../../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Summary
|
|
22
|
-
|
|
23
|
-
Compass USA keeps its items in **two intentional catalogs**, and the **same part number
|
|
24
|
-
legitimately exists once per catalog**. These are **not duplicates** — folding them together
|
|
25
|
-
broke MITS transmission platform-wide (see
|
|
26
|
-
[catalog-fold reversal](../workflows/catalog-fold-reversal.md)). `Client_Compass.Catalogs`:
|
|
27
|
-
|
|
28
|
-
| id | name | Purpose |
|
|
29
|
-
|---|---|---|
|
|
30
|
-
| 1 | **Compass** | Customer / store catalog. Items carry store classification (`assetType`, `category`, `type`). |
|
|
31
|
-
| 2 | **Agilant** | Procurement / NetSuite catalog. Items are synced from NetSuite; **no** classification fields. |
|
|
32
|
-
| 3 | Office Depot | Empty. |
|
|
33
|
-
|
|
34
|
-
**Rule: a part number that appears in both catalogs is one item per catalog, on purpose.**
|
|
35
|
-
Any dedup/merge that treats cross-catalog same-part-number rows as duplicates is wrong for
|
|
36
|
-
this client.
|
|
37
|
-
|
|
38
|
-
## Customer → catalog rule (which catalog an order resolves to)
|
|
39
|
-
|
|
40
|
-
Confirmed by the developer and by pre-merge data:
|
|
41
|
-
|
|
42
|
-
- **`customerId = 2` (Compass) sales orders → catalog 1 (store) items.**
|
|
43
|
-
- Everyone else — **Office Depot `customerId = 1`, Agilant `customerId = 3`** → catalog 2
|
|
44
|
-
(Agilant) items.
|
|
45
|
-
|
|
46
|
-
Verified pre-merge (2026-08-31 snapshot): `customerId = 2` order lines were ~100% on
|
|
47
|
-
catalog 1 (**182,787 vs 1**).
|
|
48
|
-
|
|
49
|
-
**Every catalog re-point MUST be scoped by `customerId`.** An ad-hoc
|
|
50
|
-
`UPDATE ... WHERE itemId = <agilantId>` with no customer filter wrongly moved **687
|
|
51
|
-
Office-Depot lines** onto a Compass item and had to be corrected. Scope by `customerId = 2`.
|
|
52
|
-
|
|
53
|
-
## Why the store catalog matters for MITS
|
|
54
|
-
|
|
55
|
-
The MITS transmit cron needs the **store** classification. When a Compass order line resolves
|
|
56
|
-
to an **Agilant** (catalog-2) item, that item has `assetType`/`category`/`type` NULL, so the
|
|
57
|
-
payload `assetType` is null and **MITS rejects the whole order** (HTTP 400 "The AssetType
|
|
58
|
-
field is required"). So the customer→catalog mapping is load-bearing, not cosmetic. See
|
|
59
|
-
[MITS sales-order transmit alerting](./mits-sales-order-transmission-alerting.md).
|
|
60
|
-
|
|
61
|
-
## How NetSuite → TOGa Supply sync interacts with the catalogs
|
|
62
|
-
|
|
63
|
-
The NetSuite → TOGa Supply sync is **Agilant-catalog-only**. This has two durable
|
|
64
|
-
consequences for Compass:
|
|
65
|
-
|
|
66
|
-
- **Item CREATE always stamps `catalog: Agilant` and sets NO classification.**
|
|
67
|
-
`App_Api_Toga2::getCreateItem` (`library/app/api/toga2.php` ~L6194-6270) builds the create
|
|
68
|
-
payload with `catalog => Agilant` and no `assetType`/`category`/`type`; the item lookup in
|
|
69
|
-
`worker/crons/toga2/netsuite/common_sync_togasupply.php` is built off the Agilant catalog
|
|
70
|
-
only. So **new items are born on catalog 2, unclassified** — and a Compass order line landing
|
|
71
|
-
on such an item fails MITS.
|
|
72
|
-
- **Item UPDATE only PUTs `inventoryType` / `isFulfillable`, never `assetType`/`category`/
|
|
73
|
-
`type`.** So once classification is set on an item it is **durable across sync runs** — the
|
|
74
|
-
sync will not revert it. The problem is only **new** items, which arrive unclassified.
|
|
75
|
-
|
|
76
|
-
**Consequence for any data repair:** because the sync re-creates Compass order lines pointing
|
|
77
|
-
at Agilant items, a store-catalog reversal is only durable if the **Compass NetSuite sync is
|
|
78
|
-
stopped first**. Re-enabling it risks re-pointing new/re-synced Compass orders back to Agilant
|
|
79
|
-
(2 such lines were observed right after a test re-enable). A proper long-term fix is a
|
|
80
|
-
sync-lookup change so `customerId = 2` resolves to catalog 1 — outstanding.
|
|
81
|
-
|
|
82
|
-
## Gotchas / known issues
|
|
83
|
-
|
|
84
|
-
- **Same part number in both catalogs is NOT a duplicate.** The cross-client
|
|
85
|
-
[duplicate-items dedup](../../../1.0/apps/worker/workflows/netsuite-duplicate-items-dedup.md)
|
|
86
|
-
treated Compass's catalog-1 twins as dupes and folded 199 of them into Agilant, causing the
|
|
87
|
-
MITS outage. Any dedup on this client must be **catalog-aware**.
|
|
88
|
-
- **The MITS crons hold API credentials inline** in the transmit files — treat them as
|
|
89
|
-
secret-bearing when copying snippets anywhere.
|
|
90
|
-
- Catalog 3 (Office Depot) is empty — do not assume Office Depot orders use it; ODP customer
|
|
91
|
-
`customerId = 1` resolves to catalog 2.
|
|
92
|
-
|
|
93
|
-
## Change history
|
|
94
|
-
- 2026-09-01 — Documented Compass USA's intentional two-catalog item model (1 = Compass/store
|
|
95
|
-
with classification, 2 = Agilant/NetSuite procurement without), the `customerId = 2` →
|
|
96
|
-
catalog 1 rule (verified 182,787 vs 1 pre-merge), and the mandatory `customerId` scope on any
|
|
97
|
-
catalog re-point (an unscoped one moved 687 Office-Depot lines). Recorded that the NetSuite →
|
|
98
|
-
TOGa Supply sync is Agilant-catalog-only: CREATE stamps `catalog: Agilant` with no
|
|
99
|
-
classification (new items born unclassified → MITS 400), while UPDATE never touches
|
|
100
|
-
classification (so a set value is durable). Written after the cross-client dedup folded 199
|
|
101
|
-
catalog-1 twins into Agilant and broke MITS. (jcardinal)
|
|
102
|
-
</content>
|
|
103
|
-
</invoke>
|