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.
@@ -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/two-catalog-item-model.md
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
- > [two-catalog item model](../../../clients/compass-usa/features/two-catalog-item-model.md).
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 the
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
- - two-catalog-item-model.md
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
- [two-catalog item model](./two-catalog-item-model.md).
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/two-catalog-item-model.md
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/two-catalog-item-model.md) for why the catalogs are
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/two-catalog-item-model.md).
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,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.721",
3
+ "version": "1.0.722",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -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>