toga-ai 1.0.553 → 1.0.554
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/2.0/apps/api2/features/v2-rest-query-contract.md +21 -1
- package/knowledge/2.0/apps/toga2-commerce/INDEX.md +1 -0
- package/knowledge/2.0/apps/toga2-commerce/features/category-tile-sort-order.md +164 -0
- package/knowledge/2.0/apps/toga2-commerce/features/filter-search-results-page.md +6 -1
- package/knowledge/INDEX.md +1 -1
- package/knowledge/clients/compass-usa/profile.md +13 -1
- package/package.json +1 -1
|
@@ -47,7 +47,18 @@ controller.
|
|
|
47
47
|
- **Pagination is `page` + `recordsPerPage`. There is no `limit`/`offset`.** Defaults:
|
|
48
48
|
`recordsPerPage` **25**, `depth` **3**. Max `recordsPerPage` **10000** — exceeding it returns
|
|
49
49
|
**`EV-13`** (HTTP 400).
|
|
50
|
-
- **Sort:** `-field` = DESC, bare `field` = ASC.
|
|
50
|
+
- **Sort:** `-field` = DESC, `+field` = ASC, bare `field` = ASC. All three are handled
|
|
51
|
+
(`V2.php` ~L3673–3682). **Prefer bare for ascending:** the query string is parsed *without*
|
|
52
|
+
urldecoding (see Encoding rules), so a client that percent-encodes the `+` as `%2B` sends a
|
|
53
|
+
field literally named `%2Bfield` and the sort is silently dropped. Bare has no such failure mode.
|
|
54
|
+
- **A LIST select is `SELECT SQL_CALC_FOUND_ROWS DISTINCT <table>.<primaryKey>`** (`V2.php:3884`;
|
|
55
|
+
the aggregate-fields path is the one exception). Two consequences: (a) join fan-out collapses to
|
|
56
|
+
one row per record, so **duplicate child rows are invisible in the response** — a duplicate join
|
|
57
|
+
row is not a rendering bug you can see; (b) when the collapsed duplicates carry **different**
|
|
58
|
+
values in the sorted column, `ORDER BY` has more than one candidate value for a single output row
|
|
59
|
+
and that record's **position is non-deterministic**. Sorting on a joined column is only stable if
|
|
60
|
+
the join is genuinely 1:1, or the duplicates agree. Worked example:
|
|
61
|
+
[category tile sort order](../../toga2-commerce/features/category-tile-sort-order.md).
|
|
51
62
|
|
|
52
63
|
### ⚠ `depth` is not free — the default 3 re-reads child rows and races concurrent deletes
|
|
53
64
|
|
|
@@ -158,6 +169,15 @@ where=(field:op:value,LOGIC,field:op:value,(nested,OR,nested))
|
|
|
158
169
|
invisible; re-request with `fields=` to force `EZ-2` and see the denied list.
|
|
159
170
|
|
|
160
171
|
## Change history
|
|
172
|
+
- 2026-08-11 — **Corrected the sort contract and documented the `DISTINCT` LIST select.** The old
|
|
173
|
+
"do not send `+`" was wrong as an absolute: `V2.php` ~L3673–3682 explicitly handles `+` as ASC.
|
|
174
|
+
The real caveat is encoding — the query string is parsed without urldecoding, so a
|
|
175
|
+
percent-encoded `+` (`%2B`) becomes part of the field name and the sort is silently dropped;
|
|
176
|
+
bare remains the recommended ascending form. Also recorded that a LIST select is
|
|
177
|
+
`SELECT SQL_CALC_FOUND_ROWS DISTINCT <table>.<primaryKey>` (`V2.php:3884`), which hides duplicate
|
|
178
|
+
join rows entirely **and** makes `ORDER BY` non-deterministic for a record whose collapsed
|
|
179
|
+
duplicates disagree on the sorted column. Found while diagnosing storefront category tile
|
|
180
|
+
ordering (duplicate `AssortmentItems` rows for one item). (bala)
|
|
161
181
|
- 2026-08-11 — Recorded that **`depth` (default 3) makes a response race concurrent deletes**:
|
|
162
182
|
`getFullModelData()` re-loads each child by primary key via `_Model::initialize()`, whose build
|
|
163
183
|
**throws** when the row is gone (*"Exactly 1 row was expected to be returned but 0 were"*),
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
| [Cart Bundle Submission & the bundleUuid Identity Contract](features/cart-bundle-submission-and-identity.md) | How cart **bundles** (kits) are turned into `SalesOrderItems` when a cart is submitted or an existing order is edited, and the **identity-field contract** every | src/api/syncSalesOrderItemsFromLocalStorageCartToApi.ts, src/utils/formatSalesOrderBundlesFromApi.ts, src/stores/useCartStoreZu.ts, src/pages/OrderDetails/helpers/formatSalesOrderDataFromLocalStorage.ts, src/pages/OrderDetails/view/components/OrderItems.tsx |
|
|
7
7
|
| [Cart Notification Emails — duplicate prevention](features/cart-notification-emails.md) | On the cart "Notifications" section a user can add CC email addresses to an order. | src/pages/Cart/CartPage.tsx, src/pages/Cart/view/cartForm/CartForm.tsx, src/stores/useEmailOptionsStore.ts, src/stores/useCartSalesQuoteZu.ts, src/pages/Cart/viewModel/FIELDS/*/*/*/CARTPAGE.ts |
|
|
8
8
|
| [Cart Page — config-driven form architecture (current state + planned refactor)](features/cart-page-config-architecture.md) | The Cart page (`src/pages/Cart/`) is the most config-heavy page in `toga2-commerce`. | src/pages/Cart/CartPage.tsx, src/pages/Cart/view/cartForm/CartForm.tsx, src/pages/Cart/view/cartForm/CartFormSection.tsx, src/pages/Cart/view/cartForm/CartFormRenderer.tsx, src/pages/Cart/view/EditCart.tsx, src/pages/Cart/view/EditOrder.tsx, src/pages/Cart/viewModel/useEditOrderOrEditCartViewModel.ts, src/pages/Cart/viewModel/FIELDS/*/*/*/CARTPAGE.ts, src/hooks/useAssignClientFields.ts |
|
|
9
|
+
| [Category Tile Order (AssortmentItems.sortOrder) — merchandising a storefront category](features/category-tile-sort-order.md) | **"Move item X to the front of category Y" is a DATA change, not a code change.** The order of item tiles on a storefront category page is driven by exactly one | src/pages/Filter/api/FilterApi.ts, src/pages/Filter/viewModel/useFilterViewModel.ts, api2/Component/Api/V2/V2.php, toga2-supply/src/pages/Items/api/itemsApi.ts |
|
|
9
10
|
| [Client Fields — per-tenant / language / role content & config](features/client-fields.md) | Almost no user-facing text, field layout, or page config is hard-coded in `toga2-commerce`. | src/pages/Account/view/MySettingsView.tsx, src/contexts/helpers/getLoginSettings.ts, src/pages/Account/viewModel/useAccountViewModel.ts, src/fieldsConfig/index.ts, src/fieldsConfig/getClientLoginFields.ts, src/fieldsConfig/clientFields/COMPASS.json, src/fieldsConfig/clientFields/COMPASSCANADA.json, src/fieldsConfig/clientFields/QUAD.json, src/pages/Cart/api/CartApi.ts, src/hooks/useAuthenticationFlow.ts, src/contexts/AuthContext.tsx, src/pages/Login/viewModel/useLoginPageViewModel.ts, src/hooks/useAssignClientFields.ts, src/hooks/useDynamicConditionalFieldOptions.ts, src/stores/useFieldsStore.ts, src/components/BaseDetailField/BaseDetailField.tsx, src/components/NavIcons/NavIconItem.tsx, src/components/Submenus/AlertSubmenu.tsx, src/components/Submenus/types.ts, src/pages/Account/AccountPage.tsx, src/pages/Account/view/MyOrdersView.tsx, src/pages/GetSupport/GetSupportPage.tsx, src/pages/GetSupport/viewModel/useGetSupportViewModel.ts, src/queries/queries.ts, src/App.tsx, src/pages/Filter/FilterPage.tsx, src/pages/Filter/viewModel/FIELDS/COMPASS/ENGLISH/USER/FILTERPAGEFIELDS.json |
|
|
10
11
|
| [Config-Driven Expedited Shipping Gating (Cart)](features/expedited-shipping-gating.md) | On the toga2-commerce **Cart** page, expedited shipping options (**"2nd Day EOB"** and **"Next Day Air"**) are only offered in the *Shipping Method* dropdown wh | toga2-commerce/src/pages/Cart/helpers/shippingOptionGates.ts, toga2-commerce/src/pages/Cart/viewModel/FIELDS/shared/shippingOptionGates.ts, toga2-commerce/src/pages/Cart/view/cartForm/CartForm.tsx, toga2-commerce/src/pages/Cart/CartPage.tsx |
|
|
11
12
|
| [Filter / Search-Results Page & the Two Search Entry Points](features/filter-search-results-page.md) | The storefront has **two distinct search entry points that render the same card component through completely different code paths and different FIELDS files**. | src/pages/Filter/FilterPage.tsx, src/pages/Filter/viewModel/useFilterViewModel.ts, src/pages/Filter/viewModel/FIELDS/COMPASS/ENGLISH/USER/FILTERPAGEFIELDS.json, src/pages/Filter/viewModel/FIELDS/COMPASSCANADA/FRENCH/USER/FILTERPAGEFIELDS.json, src/pages/Filter/viewModel/FIELDS/QUAD/ENGLISH/BUYER/FILTERPAGEFIELDS.json, src/components/Header/Header.tsx, src/pages/Home/view/components/BundlesSection.tsx, src/pages/Home/viewModel/FIELDS/COMPASS/ENGLISH/USER/HOMEPAGEFIELDS.json, src/components/Cards/BundleViewCard.tsx, src/utils/renderBadge.tsx, src/hooks/useAssignClientFields.ts |
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Category Tile Order (AssortmentItems.sortOrder) — merchandising a storefront category
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: toga2-commerce
|
|
5
|
+
project: TOGa Commerce
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-08-11
|
|
10
|
+
owners: [bala]
|
|
11
|
+
files:
|
|
12
|
+
- src/pages/Filter/api/FilterApi.ts
|
|
13
|
+
- src/pages/Filter/viewModel/useFilterViewModel.ts
|
|
14
|
+
- api2/Component/Api/V2/V2.php
|
|
15
|
+
- toga2-supply/src/pages/Items/api/itemsApi.ts
|
|
16
|
+
related:
|
|
17
|
+
- filter-search-results-page.md
|
|
18
|
+
- ../architecture.md
|
|
19
|
+
- ../../api2/features/v2-rest-query-contract.md
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Summary
|
|
23
|
+
|
|
24
|
+
**"Move item X to the front of category Y" is a DATA change, not a code change.** The order of
|
|
25
|
+
item tiles on a storefront category page is driven by exactly one column —
|
|
26
|
+
**`Client_<Client>.AssortmentItems.sortOrder`, ascending** — and nothing else. There is no
|
|
27
|
+
merchandising UI, no per-tenant config key, and no client-side re-sort to override.
|
|
28
|
+
|
|
29
|
+
The trap is that the obvious one-row `UPDATE` **does not work**: in MySQL `ORDER BY … ASC`,
|
|
30
|
+
`NULL` sorts **before** every number, and these columns are normally all `NULL`. Setting only the
|
|
31
|
+
target item to `1` leaves the still-`NULL` siblings ahead of it — the opposite of the request. You
|
|
32
|
+
must give **every active item in that assortment** an explicit `sortOrder`.
|
|
33
|
+
|
|
34
|
+
## How it works
|
|
35
|
+
|
|
36
|
+
1. **Category browse** is the `/filter` page with a `category` query param and no `search` text.
|
|
37
|
+
`useFilterViewModel.ts` runs the `["assortmentItems", categoryUuid, currentPage]` query, which
|
|
38
|
+
calls `fetchAssortmentItems()` in `src/pages/Filter/api/FilterApi.ts`.
|
|
39
|
+
2. That request joins `Items → AssortmentItems → Assortments` (plus `Personas_Items → Personas`
|
|
40
|
+
for non-admins), filters to the requested assortment uuid with `Items.isActive = 1` and
|
|
41
|
+
`Items.catalogId = 1`, pages at `recordsPerPage: 12`, and sorts with exactly:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
sort: ["AssortmentItems.sortOrder"]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
3. **api2 treats a bare (unprefixed) sort field as ASC.** (`-` = DESC, `+` = ASC — see
|
|
48
|
+
[v2-rest-query-contract](../../api2/features/v2-rest-query-contract.md).)
|
|
49
|
+
4. **The frontend never re-sorts.** The view model does a straight
|
|
50
|
+
`setSortedItems(assortmentItems.data.items)` — despite the `sortedItems` name, no sorting
|
|
51
|
+
happens there. **The API's row order is the final on-screen order.**
|
|
52
|
+
|
|
53
|
+
So the only lever is the column. Ties (equal or all-`NULL` values) fall back to whatever MySQL
|
|
54
|
+
returns, which is not a documented or stable order.
|
|
55
|
+
|
|
56
|
+
## Making the change (the procedure)
|
|
57
|
+
|
|
58
|
+
Assign an explicit `sortOrder` to **every active item** in the assortment — the two pinned ones,
|
|
59
|
+
then the rest. Pattern (`<assortmentId>` from `Assortments`, item ids from `Items`):
|
|
60
|
+
|
|
61
|
+
```sql
|
|
62
|
+
# 1. pin the intended leaders
|
|
63
|
+
UPDATE AssortmentItems
|
|
64
|
+
SET sortOrder = 1
|
|
65
|
+
WHERE
|
|
66
|
+
assortmentId = <assortmentId> AND
|
|
67
|
+
itemId = <firstItemId>;
|
|
68
|
+
|
|
69
|
+
UPDATE AssortmentItems
|
|
70
|
+
SET sortOrder = 2
|
|
71
|
+
WHERE
|
|
72
|
+
assortmentId = <assortmentId> AND
|
|
73
|
+
itemId = <secondItemId>;
|
|
74
|
+
|
|
75
|
+
# 2. every remaining ACTIVE item must get a value, or a NULL row jumps to the front
|
|
76
|
+
UPDATE AssortmentItems ai
|
|
77
|
+
INNER JOIN Items i ON i.id = ai.itemId
|
|
78
|
+
SET ai.sortOrder = 10
|
|
79
|
+
WHERE
|
|
80
|
+
ai.assortmentId = <assortmentId> AND
|
|
81
|
+
ai.sortOrder IS NULL AND
|
|
82
|
+
i.isActive = 1;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Verify with the read the storefront actually performs — ordered, not just spot-checked:
|
|
86
|
+
|
|
87
|
+
```sql
|
|
88
|
+
SELECT
|
|
89
|
+
ai.id,
|
|
90
|
+
ai.itemId,
|
|
91
|
+
ai.sortOrder,
|
|
92
|
+
i.itemNumber,
|
|
93
|
+
i.isActive
|
|
94
|
+
FROM AssortmentItems ai
|
|
95
|
+
INNER JOIN Items i ON i.id = ai.itemId
|
|
96
|
+
WHERE ai.assortmentId = <assortmentId>
|
|
97
|
+
ORDER BY ai.sortOrder ASC;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Recommended, not required:** park **inactive** rows at a high value (e.g. `100`) as well. They
|
|
101
|
+
are filtered out today by `Items.isActive = 1`, so they cost nothing now — but if someone
|
|
102
|
+
reactivates one later it comes back with `sortOrder = NULL` and silently takes first position.
|
|
103
|
+
|
|
104
|
+
## Gotchas
|
|
105
|
+
|
|
106
|
+
- **`NULL` sorts FIRST in ASC.** The single-row `UPDATE` that "obviously" pins an item produces the
|
|
107
|
+
opposite result while looking correct in isolation. Always set the whole active set.
|
|
108
|
+
- **Duplicate `AssortmentItems` rows exist and make order non-deterministic.** api2's LIST query
|
|
109
|
+
selects `SELECT SQL_CALC_FOUND_ROWS DISTINCT <table>.<primaryKey>` (`V2.php:3884`), so two
|
|
110
|
+
`AssortmentItems` rows for the same `itemId` collapse to **one visible tile** — which is why
|
|
111
|
+
nobody notices the duplicate. But if the duplicates carry **different** `sortOrder` values, the
|
|
112
|
+
`ORDER BY` has two candidate values for one output row and the position is unpredictable. When
|
|
113
|
+
duplicates exist, give them the **same** value or delete the extras. Check first:
|
|
114
|
+
|
|
115
|
+
```sql
|
|
116
|
+
SELECT itemId, COUNT(*) AS rowCount
|
|
117
|
+
FROM AssortmentItems
|
|
118
|
+
WHERE assortmentId = <assortmentId>
|
|
119
|
+
GROUP BY itemId
|
|
120
|
+
HAVING rowCount > 1;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- **⚠ Editing an item's assortments in TOGa Supply WIPES `sortOrder`.** See Known open items —
|
|
124
|
+
any ordering you set is one supply edit away from being erased. Re-verify order after anyone
|
|
125
|
+
edits that item in supply.
|
|
126
|
+
- **A refresh will NOT show the change.** The storefront persists its whole React Query cache to
|
|
127
|
+
`localStorage["commerce"]` with a 24h `staleTime`, so a warm browser replays the cached
|
|
128
|
+
response and the (correct) data fix looks like it failed — then gets "re-fixed". The reliable
|
|
129
|
+
check is **log out and back in** (logout removes the `commerce` key), or
|
|
130
|
+
`localStorage.removeItem('commerce')`; otherwise it appears within 24h. See
|
|
131
|
+
[architecture](../architecture.md) gotchas.
|
|
132
|
+
- **This is data, so it does not ride a deploy.** No build, no release notes — which also means no
|
|
133
|
+
audit trail. Record the assortment id and the values you set in the ticket.
|
|
134
|
+
|
|
135
|
+
## Known open items
|
|
136
|
+
|
|
137
|
+
- **⚠ TOGa Supply resets `sortOrder` to `NULL` on any item-assortment edit — unfixed, no ticket
|
|
138
|
+
filed yet.** In `toga2-supply/src/pages/Items/api/itemsApi.ts`, `updateItemAssortments()`
|
|
139
|
+
(L645) reads the item's existing rows via `getAssortmentItems()` (L434), which requests only
|
|
140
|
+
`["assortment.name", "assortment.uuid", "uuid"]` — **never `sortOrder`** — then `DELETE`s every
|
|
141
|
+
row and `POST`s new ones whose payload carries only `item.uuid` + `assortment.uuid`. The
|
|
142
|
+
merchandising order is therefore silently destroyed and cannot be restored, because the old
|
|
143
|
+
values were never read. A fix must select `sortOrder`, and either preserve it on the re-POST or
|
|
144
|
+
stop the delete-then-recreate in favor of diffing.
|
|
145
|
+
- **Same function: the re-POSTs are never awaited.** `updateItemAssortments()` builds
|
|
146
|
+
`addPromises` and returns without `await Promise.all(addPromises)` (the `DELETE`s above it *are*
|
|
147
|
+
awaited). Failures surface as unhandled rejections and the caller cannot know the writes landed.
|
|
148
|
+
Fire-and-forget `POST`s racing an awaited `DELETE` burst is also the most likely origin of the
|
|
149
|
+
duplicate rows described in Gotchas. (Related: parallel deletes on a collection can 500 the
|
|
150
|
+
response of a concurrent read — see
|
|
151
|
+
[v2-rest-query-contract](../../api2/features/v2-rest-query-contract.md).)
|
|
152
|
+
- **Compass USA "Docking Station" reorder — SQL delivered, NOT executed.** See
|
|
153
|
+
[Compass USA profile](../../../clients/compass-usa/profile.md).
|
|
154
|
+
|
|
155
|
+
## Change history
|
|
156
|
+
- 2026-08-11 — Initial doc, from a read-only prod investigation of a Compass USA request to move
|
|
157
|
+
one item to the front of a category. Recorded that tile order comes solely from
|
|
158
|
+
`AssortmentItems.sortOrder ASC` (`FilterApi.ts:56`) with no client-side re-sort in
|
|
159
|
+
`useFilterViewModel.ts`; the **`NULL`-sorts-first** trap that makes a single-row `UPDATE`
|
|
160
|
+
backfire (the real assortment had `sortOrder = NULL` on all 16 rows); api2's
|
|
161
|
+
`DISTINCT <primaryKey>` LIST select (`V2.php:3884`) hiding duplicate join rows while making
|
|
162
|
+
`ORDER BY` non-deterministic when duplicates disagree; and that toga2-supply's
|
|
163
|
+
`updateItemAssortments()` wipes `sortOrder` (and never awaits its re-POSTs), making any fix
|
|
164
|
+
non-durable. (bala)
|
|
@@ -7,7 +7,7 @@ client: shared
|
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
9
|
updated: 2026-07-28
|
|
10
|
-
owners: ["tcox"]
|
|
10
|
+
owners: ["tcox", "bala"]
|
|
11
11
|
files:
|
|
12
12
|
- src/pages/Filter/FilterPage.tsx
|
|
13
13
|
- src/pages/Filter/viewModel/useFilterViewModel.ts
|
|
@@ -24,6 +24,7 @@ related:
|
|
|
24
24
|
- 2.0/apps/toga2-commerce/architecture.md
|
|
25
25
|
- 2.0/apps/toga2-commerce/features/client-fields.md
|
|
26
26
|
- 2.0/apps/toga2-commerce/features/multi-tenant-theming.md
|
|
27
|
+
- 2.0/apps/toga2-commerce/features/category-tile-sort-order.md
|
|
27
28
|
---
|
|
28
29
|
|
|
29
30
|
## Summary
|
|
@@ -53,6 +54,10 @@ bug (see Change history).
|
|
|
53
54
|
tenant × language × role (see [client-fields](client-fields.md) for the resolver). `FilterPage`
|
|
54
55
|
`renderBundles` maps each result to a `BundleViewCard`.
|
|
55
56
|
|
|
57
|
+
> **Third mode, same page:** with a `category` param and **no** `search` text, `/filter` is the
|
|
58
|
+
> category *browse* page and runs a different query (`fetchAssortmentItems`) whose row order is
|
|
59
|
+
> data-driven — see [category tile sort order](category-tile-sort-order.md).
|
|
60
|
+
|
|
56
61
|
### Home search → in-place filter
|
|
57
62
|
|
|
58
63
|
The Home page's own lower search bar never leaves `/home`. `BundlesSection.tsx` reads
|
package/knowledge/INDEX.md
CHANGED
|
@@ -29,7 +29,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
29
29
|
- **talos** (TOGa IQ) — 7 doc(s) → [2.0/apps/talos/INDEX.md](2.0/apps/talos/INDEX.md)
|
|
30
30
|
- **voice-to-voice** (TOGa Voice) — 4 doc(s) → [2.0/apps/voice-to-voice/INDEX.md](2.0/apps/voice-to-voice/INDEX.md)
|
|
31
31
|
- **ai-bdr** (AI-BDR) — 9 doc(s) → [2.0/apps/ai-bdr/INDEX.md](2.0/apps/ai-bdr/INDEX.md)
|
|
32
|
-
- **toga2-commerce** (TOGa Commerce) —
|
|
32
|
+
- **toga2-commerce** (TOGa Commerce) — 13 doc(s) → [2.0/apps/toga2-commerce/INDEX.md](2.0/apps/toga2-commerce/INDEX.md)
|
|
33
33
|
- **toga25-supply** (TOGa 2.5 Supply) — 11 doc(s) → [2.0/apps/toga25-supply/INDEX.md](2.0/apps/toga25-supply/INDEX.md)
|
|
34
34
|
- **toga-blox** (TOGa Blox) — 8 doc(s) → [2.0/apps/toga-blox/INDEX.md](2.0/apps/toga-blox/INDEX.md)
|
|
35
35
|
- **bdr** (BDR) — 0 doc(s) → [2.0/apps/bdr/INDEX.md](2.0/apps/bdr/INDEX.md)
|
|
@@ -17,7 +17,7 @@ project: _Underscore
|
|
|
17
17
|
client: compass-usa
|
|
18
18
|
type: profile
|
|
19
19
|
status: active
|
|
20
|
-
updated: 2026-08-
|
|
20
|
+
updated: 2026-08-11
|
|
21
21
|
owners: [jcardinal, bala, tcox, apeterson, dfranks]
|
|
22
22
|
files: []
|
|
23
23
|
related:
|
|
@@ -32,6 +32,7 @@ related:
|
|
|
32
32
|
- workflows/odp-duplicate-po-line-cleanup.md
|
|
33
33
|
- ../../2.0/apps/worker2/features/compass-vip-support-importer.md
|
|
34
34
|
- ../../2.0/apps/toga2-commerce/features/expedited-shipping-gating.md
|
|
35
|
+
- ../../2.0/apps/toga2-commerce/features/category-tile-sort-order.md
|
|
35
36
|
- ../../2.0/apps/toga2-commerce/features/cart-bundle-submission-and-identity.md
|
|
36
37
|
- ../../2.0/apps/_underscore/features/item-fulfillment-stage-lifecycle-and-order-status.md
|
|
37
38
|
---
|
|
@@ -61,6 +62,17 @@ separate, related client (see its own profile).
|
|
|
61
62
|
**Known data issue:** many Compass MacBooks are categorized `APPLE LAPTOP` /
|
|
62
63
|
`MAC & ACCESSORIES`, not `COMPUTERS`, so those kits do **not** qualify for expedited — a
|
|
63
64
|
catalog-data normalization matter, not a code gap.
|
|
65
|
+
- **Category tile order is data, not code** — `Client_Compass.AssortmentItems.sortOrder ASC` is the
|
|
66
|
+
only lever; see
|
|
67
|
+
[Category Tile Order](../../2.0/apps/toga2-commerce/features/category-tile-sort-order.md) for the
|
|
68
|
+
`NULL`-sorts-first trap and the procedure.
|
|
69
|
+
**⚠ Pending prod data change (2026-08-11, delivered but NOT executed):** for
|
|
70
|
+
`Assortments.id = 9` ("Docking Station", all 16 rows had `sortOrder = NULL`), pin
|
|
71
|
+
`itemId 2712` / `9X3V1UT` → `1` and `itemId 2812` / `AW5M5UT-1` → `2`, and give the remaining
|
|
72
|
+
active rows an explicit value. Handed off for a DBA / the TOGa UI to run because session DB
|
|
73
|
+
access was read-only. Also outstanding for that assortment: park the 13 inactive rows at a high
|
|
74
|
+
`sortOrder`, and remove the duplicate `AssortmentItems` row `id 2982` (duplicate of `2981`, same
|
|
75
|
+
`itemId 2712`). Confirm whether this was applied before re-diagnosing tile order for Compass.
|
|
64
76
|
- **Cross-kit bundle corruption (edit-order):** a `toga2-commerce` submit bug attributed kit
|
|
65
77
|
line items and shared fees/warranties to the wrong kit; 55 Compass orders / 298 line items are
|
|
66
78
|
corrupted in `Client_Compass.SalesOrderItems` (Canada and Quad: zero). The code fix is
|
package/package.json
CHANGED