toga-ai 1.0.401 → 1.0.403

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.
@@ -322,21 +322,21 @@ Core record grants + their logic-group expressions all evaluate `all`/`"1"`. The
322
322
 
323
323
  ## Gotchas
324
324
 
325
- - **Per-client surface message overrides silently never apply unless the JWT carries
326
- `id.client.languageId`.** `_Model_Core_Surface::_loadMessages` overlays `Core.Messages.defaultValue`
327
- with `Client_<X>.MessageTranslations` rows **only when `languageId > 0`**, and `Surface.php` resolves
328
- `languageId` **solely** from the JWT `id.client.languageId` claim. But auth (`api2/V2.php`)
329
- historically set only `id.language` (the string code `"en"`) and **never** `id.client.languageId`, so
330
- `languageId` was always `0`, the overlay was skipped, and every per-client surface message override
331
- (e.g. a client-specific disabled-tooltip) fell back to the Core default with **no error**. (There was
332
- an explicit TODO at `V2.php` ~L5738.) **Fix (2026-07-21):** `/auth/login` now embeds
333
- `$id->client->languageId = (int)$language->id` in **both** the configured-language and default-`en`
334
- branches (English gets a real `languageId` too; the overlay keys on `languageId > 0` and falls back
335
- to Core defaults where a client has no `MessageTranslations` row). **CAVEAT only `/auth/login`
336
- was fixed.** The refresh (`V2.php` ~L1227), oauth, api, delegator, encrypted, and public token paths
337
- still don't embed `id.client.languageId`, so **after an access-token refresh (~3600s) `languageId` is
338
- lost** and per-client surface messages revert until those paths are updated too. (This is a **separate
339
- claim** from `id.language`, which drives the data-translation sidecar — see
325
+ - **Per-client surface message overrides silently never apply when `languageId` resolves to `0`.**
326
+ `_Model_Core_Surface::_loadMessages` overlays `Core.Messages.defaultValue` with
327
+ `Client_<X>.MessageTranslations` rows **only when `languageId > 0`**. The JWT carries the language as
328
+ the string code `id.language` (`"en"`) but **not** the numeric `id.client.languageId`, so reading
329
+ `id.client.languageId` alone always yielded `0` — the overlay was skipped and every per-client surface
330
+ message override (e.g. a client-specific disabled-tooltip) fell back to the Core default with **no
331
+ error**. **Fix (2026-07-21):** `Surface.php` now resolves `languageId` via a private
332
+ `_resolveLanguageId($api)` helper (used by both `resolve()` and `metaDebug()`) it prefers
333
+ `id.client.languageId`, and when that is `0` **looks up the client `Languages` row by the
334
+ `id.language` code** (`_Model_Client_Language` load-by-`code`) and uses its id. English resolves to a
335
+ real `languageId` too; a client with no `MessageTranslations` row still falls back to Core defaults.
336
+ This lives entirely in the framework resolver **no auth/JWT change** (an earlier `V2.php`
337
+ token-embed approach was abandoned in favour of the lookup, so it works across **all** token paths,
338
+ including refresh, without each auth flow having to embed the id). (This is a **separate** concern from
339
+ `id.language` driving the data-translation sidecar — see
340
340
  [language-translation-layer](../../api2/features/language-translation-layer.md); do not conflate.)
341
341
  - **A `SurfaceOverrides` row with `attribute='CONFIG'` carrying a RULE value is silently DEAD —
342
342
  encode rules as `VISIBILITY_RULE`/`ENABLED_RULE`, never as `CONFIG`.** `_castOverride` routes the
@@ -427,10 +427,10 @@ Core record grants + their logic-group expressions all evaluate `all`/`"1"`. The
427
427
  `{"type":"poNumberEntered"}` (client-wide, both surfaces) + disabled-tooltip `MessageTranslations`
428
428
  override, and the **Compass/CC** approvals-gate marker enable (`2026-07-21b`) needed so
429
429
  `stepTwoAssigned` doesn't fail open. New gotcha: per-client surface **message** overrides silently
430
- never apply unless the JWT carries `id.client.languageId` (`_loadMessages` overlays
431
- `MessageTranslations` only when `languageId>0`; `Surface.php` reads it solely from that claim, but
432
- auth only set `id.language`) fixed in `api2/V2.php` `/auth/login` (both language branches), with the
433
- caveat that refresh/oauth/api/delegator/encrypted/public paths still lose it after a token refresh.
430
+ never apply when `languageId` resolves to `0` (`_loadMessages` overlays `MessageTranslations` only
431
+ when `languageId>0`; the JWT carries `id.language` code but not `id.client.languageId`) fixed in
432
+ `Surface.php` via a `_resolveLanguageId()` helper that falls back to looking up the client `Languages`
433
+ row by the `id.language` code. Framework-only; no auth/JWT change, so it holds across all token paths.
434
434
  (apeterson)
435
435
  - 2026-07-20 — Clarified the **backend Tier-2 gate reality**: `_resolveTier2State` (Surface.php ~280)
436
436
  dispatches by **action slug** to `resolveSurfaceActionState()` (`TIER2_CAPABILITY_METHOD`), **not**
@@ -3,5 +3,5 @@
3
3
  | Doc | Summary | Files |
4
4
  |-----|---------|-------|
5
5
  | [TOGa Supply (toga2-supply) Architecture](architecture.md) | `toga2-supply` is the **React + Vite frontend** for TOGa Supply — warehouse fulfillment tooling (shipment selection, fulfill & ship against carrier APIs, NetSui | toga2-supply/src/api/toga.ts, toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx |
6
- | [Fulfill & Ship](features/fulfill-and-ship.md) | Fulfill & Ship lets a warehouse user select sales-order line items, enter serials, pick a carrier/method, and in one action: create the Item Fulfillment records | toga2-supply/src/components/ui/Tables/BasicTable/BasicTable.tsx, toga2-supply/src/pages/ShipmentItems/view/forms/ShipmentItemsTable.tsx, toga2-supply/src/pages/ShipmentItems/api/ShipmentItemsApi.ts, toga2-supply/src/pages/ShipmentItems/types.ts, toga2-supply/src/pages/EditShipment/viewModel/FIELDS/RETURNLABELFIELDS.json, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/components/ui/BaseInput/UnitSelect.tsx, toga2-supply/src/pages/EditShipment/view/modals/SerialNumbersModal.tsx, toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/pages/EditShipment/view/components/SelectedShipmentItemsTable.tsx, toga2-supply/src/pages/EditShipment/view/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/src/pages/EditShipment/viewModel/FIELDS/DUMMYUPDATESHIPMENTFIELDS.json, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/tailwind.config.cjs, toga2-supply/src/pages/EditShipment/view/modals/ReturnShippingModal.tsx, toga2-supply/src/styles/index.scss, toga2-supply/src/components/ui/BaseInput/BaseInput.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/EditShipment/viewModel/signatureTypes.ts, toga2-supply/src/pages/EditShipment/view/modals/SelectReturnAddressModal.tsx, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/formatShipmentData.ts, toga2-supply/src/pages/EditShipment/types.ts, toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, toga2-supply/src/pages/Shipments/types.ts, toga2-supply/src/pages/FulfilledShipments/view/FulfilledShipmentsPage.tsx, toga2-supply/src/components/ui/CardTable/CardTable.tsx, toga2-supply/src/components/ui/CardTable/types.ts, toga2-supply/src/assets/pen-line.svg, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
6
+ | [Fulfill & Ship](features/fulfill-and-ship.md) | Fulfill & Ship lets a warehouse user select sales-order line items, enter serials, pick a carrier/method, and in one action: create the Item Fulfillment records | toga2-supply/src/components/ui/Tables/BasicTable/BasicTable.tsx, toga2-supply/src/components/ui/Tables/types.ts, toga2-supply/src/components/ui/GoogleMapsLink.tsx, toga2-supply/src/pages/ShipmentItems/view/forms/ShipmentItemsTable.tsx, toga2-supply/src/pages/ShipmentItems/api/ShipmentItemsApi.ts, toga2-supply/src/pages/ShipmentItems/types.ts, toga2-supply/src/pages/EditShipment/viewModel/FIELDS/RETURNLABELFIELDS.json, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/components/ui/BaseInput/UnitSelect.tsx, toga2-supply/src/pages/EditShipment/view/modals/SerialNumbersModal.tsx, toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/pages/EditShipment/view/components/SelectedShipmentItemsTable.tsx, toga2-supply/src/pages/EditShipment/view/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/src/pages/EditShipment/viewModel/FIELDS/DUMMYUPDATESHIPMENTFIELDS.json, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/tailwind.config.cjs, toga2-supply/src/pages/EditShipment/view/modals/ReturnShippingModal.tsx, toga2-supply/src/styles/index.scss, toga2-supply/src/components/ui/BaseInput/BaseInput.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/EditShipment/viewModel/signatureTypes.ts, toga2-supply/src/pages/EditShipment/view/modals/SelectReturnAddressModal.tsx, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/formatShipmentData.ts, toga2-supply/src/pages/EditShipment/types.ts, toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, toga2-supply/src/pages/Shipments/types.ts, toga2-supply/src/pages/FulfilledShipments/view/FulfilledShipmentsPage.tsx, toga2-supply/src/components/ui/CardTable/CardTable.tsx, toga2-supply/src/components/ui/CardTable/types.ts, toga2-supply/src/assets/pen-line.svg, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
7
7
  | [AWS Amplify Build & Deploy (non-prod environments)](workflows/amplify-build-and-deploy.md) | How `toga2-supply` (React + Vite) builds and deploys on **AWS Amplify**. | toga2-supply/amplify.yml, toga2-supply/.gitattributes, toga2-supply/.github/workflows/sync-stage-environments.yml, toga2-supply/.env.qc-security |
@@ -10,6 +10,8 @@ updated: 2026-07-21
10
10
  owners: [mhammontree]
11
11
  files:
12
12
  - toga2-supply/src/components/ui/Tables/BasicTable/BasicTable.tsx
13
+ - toga2-supply/src/components/ui/Tables/types.ts
14
+ - toga2-supply/src/components/ui/GoogleMapsLink.tsx
13
15
  - toga2-supply/src/pages/ShipmentItems/view/forms/ShipmentItemsTable.tsx
14
16
  - toga2-supply/src/pages/ShipmentItems/api/ShipmentItemsApi.ts
15
17
  - toga2-supply/src/pages/ShipmentItems/types.ts
@@ -242,6 +244,17 @@ A field changed from its saved value shows a **mint-600 (`#2CB224`) border**; it
242
244
  for a user-meaningful prefill (e.g. the warehouse-address prefill) must pass `{ shouldDirty: true }`
243
245
  or RHF reports the field clean and the border never appears (see the RHF `isDirty` gotcha below).
244
246
 
247
+ ### BasicTable click-to-select rows — `onRowClick` (2026-07-21)
248
+
249
+ `BasicTable` now accepts an optional **`onRowClick?: (row) => void`** (`components/ui/Tables/types.ts`,
250
+ `components/ui/Tables/BasicTable/BasicTable.tsx`) — a reusable click-to-select-row pattern for any
251
+ `BasicTable`. **The handler IGNORES clicks whose target is inside an interactive element**
252
+ (`input,button,a,select,textarea,label`), so checkboxes / inputs / buttons keep their own behavior; a
253
+ click anywhere ELSE on the row fires `onRowClick`. First consumer: Select Items
254
+ (`ShipmentItemsTable.tsx`) — clicking a row toggles its checkbox. Requirements for that use: rows must
255
+ carry a **`uuid`** and **disabled rows are skipped**. Reuse this for any `BasicTable` that wants
256
+ row-level selection rather than only the checkbox hit area.
257
+
245
258
  ## Signature Type — 4-level enum (2026-07)
246
259
 
247
260
  Signature moved from a **boolean `requiresSignature`** to a **4-level `signatureType` enum**:
@@ -289,6 +302,27 @@ existing IF), `fulfillShipment` + `generateReturnLabel` (label), `saveShipmentTo
289
302
  (push-back). New pieces needed: the punch-out entry carrying an IF id, and a **label-only mode**
290
303
  (skip the create step). This is a separate feature/ticket — recorded as planned direction, not done.
291
304
 
305
+ ## Planned direction — persist package dimension + volume Units of Measure (design, 2026-07-21)
306
+
307
+ **Design decision recorded for future work (not implemented this session).** Today the package
308
+ dimension in./cm selector is **visual-only** and `TrackingNumbers` stores `length`/`width`/`height`
309
+ with **no unit**. The plan is to persist the package **DIMENSION** unit (for L/W/H) and the **VOLUME**
310
+ unit on the tracking record.
311
+
312
+ - **Recommended design = ZERO new tables, only columns.** REUSE the existing client **`Measures`**
313
+ table + **`_Model_Client_Measure`** model (already referenced by `Items.defaultMeasureId`): add a
314
+ **`measureType` ENUM** (LENGTH / VOLUME / WEIGHT / COUNT — per Jeff the types are enumerators, so
315
+ **no separate `MeasureTypes` table**) plus a **`conversionFactorToBase`** column, and add
316
+ **`dimensionMeasureId` / `volumeMeasureId`** FK columns on **`TrackingNumbers`**.
317
+ - **Carrier constraint drives the conversion factor.** FedEx/UPS ship APIs accept only **IN/CM**
318
+ dimension units and **LB/KG** weight units, so the chosen measure must map/convert to the carrier
319
+ enum — hence `conversionFactorToBase`. **Volume is NOT sent to carriers** (dimensional weight is
320
+ derived from L/W/H).
321
+ - **Alternative (documented for opt-in):** two dedicated new tables instead of reusing `Measures`.
322
+ - Spans `_underscore` (Measure/TrackingNumber models), `dbchanges2`, and `api2`; full plan + the
323
+ deployment order live in external working files (`package_units_of_measure_plan.md`,
324
+ `TRUE-79191_deployment_order.md`) — not mirrored into the KB.
325
+
292
326
  ## Sources — meeting notes / decision origins
293
327
 
294
328
  Fulfill & Ship meeting transcripts and notes live in the **Internal Knowledgebase MCP connector**
@@ -312,6 +346,25 @@ the call 403s and returns no label.
312
346
 
313
347
  ## Gotchas / known issues
314
348
 
349
+ - **⚠ The shared `GoogleMapsLink` mapped the RECIPIENT, not the address.** The shared
350
+ `components/ui/GoogleMapsLink.tsx` built its query from `[addressee, line1, line2, city, zip]`,
351
+ which had two bugs: (a) it included the **`addressee` (recipient name)**, so Google surfaced the
352
+ *person* instead of the location; (b) it read **`line1`** but the shipment address object exposes
353
+ the street as **`street`** (not `line1`), so the street was missing. Fix: map the **physical address
354
+ ONLY** — `street || line1`, line2, city, `state.name`, zip; **exclude the addressee**. Two more
355
+ bugs fixed in the same component: an **always-true empty-part filter** (`!= null || != undefined` —
356
+ a value is always either not-null or not-undefined, so nothing was ever filtered), and a
357
+ **double-encoding bug** — it did `replace(/\s+/g,"+")` and *then* `encodeURIComponent`, so the `+`
358
+ was itself encoded to literal `%2B` and Maps got broken queries. Encode once. Separately, the Edit
359
+ Return Label modal's "Google Maps" link (`ReturnShippingModal.tsx`) had **no `onClick` handler at
360
+ all** — wired it to open the current return address.
361
+ - **⚠ A viewport-relative `max-w-[NNvw]` truncation cap can itself force horizontal overflow on a WIDE
362
+ table.** The CSS-truncation pattern (`truncate max-w-[NNvw]` + native `title` — see the
363
+ `ExpandableCellContent` gotcha below) caps one column at `NN%` of the viewport, but on a
364
+ **many-column** table that capped column PLUS all the other columns can exceed the viewport width and
365
+ add a horizontal scrollbar. **Tune the `vw` per table by column count:** Select Items (13 columns)
366
+ uses `max-w-[20vw]`; Update Info (8 columns) keeps `max-w-[30vw]`. The truncation mechanism itself is
367
+ unchanged. (`ShipmentItemsTable.tsx`.)
315
368
  - **⚠ The item-image tables hardcoded the placeholder and never requested the image.** The Select
316
369
  Items (`ShipmentItemsTable`), Update Info, and Add-Serial (`SelectedShipmentItemsTable`) tables
317
370
  rendered `imageUrl={placeholderImage}` as a **constant**, so a real item image could never appear.
@@ -618,6 +671,17 @@ not the base `_Model_Client_ItemFulfillment`. Tested with GroWrk; UPS support wa
618
671
  for Compass and is not yet in prod.
619
672
 
620
673
  ## Change history
674
+ - 2026-07-21 — TRUE-79191 (commit `651e9d9d0`, toga2-supply UI fixes + UoM design): fixed the shared
675
+ **`GoogleMapsLink`** mapping the recipient instead of the address (excluded `addressee`; read
676
+ `street || line1` not `line1`; killed an always-true empty-part filter and a `replace`+`encodeURIComponent`
677
+ **double-encoding** bug) and wired the Edit Return Label modal's previously dead "Google Maps" link.
678
+ Added **`BasicTable.onRowClick`** — a reusable click-to-select-row capability that ignores clicks on
679
+ interactive children (`input,button,a,select,textarea,label`); first used on Select Items to toggle a
680
+ row's checkbox. Documented the **`max-w-[NNvw]` truncation-cap causing horizontal overflow** on wide
681
+ tables (tune the vw per column count: 13-col Select Items `20vw`, 8-col Update Info `30vw`). Recorded
682
+ the **package Units-of-Measure design** (persist dimension + volume units on `TrackingNumbers` by
683
+ reusing the `Measures` table + `measureType` enum + `conversionFactorToBase`; zero new tables;
684
+ carriers accept only IN/CM + LB/KG) as a planned direction — implementation not started. (mhammontree)
621
685
  - 2026-07-21 — TRUE-79191 (commit `dc900ea4e`, toga2-supply item-image + table polish): fixed the
622
686
  **item image never rendering** — the Select Items / Update Info / Add-Serial tables hardcoded
623
687
  `imageUrl={placeholderImage}` and never requested the image; now request the two `_underscore` Item
@@ -0,0 +1,62 @@
1
+ ---
2
+ type: session
3
+ slug: true-79191-fulfill-ship
4
+ title: TRUE-79191 Fulfill & Ship — review fixes, deployment order, UoM plan
5
+ author: mhammontree
6
+ repos: [toga2-supply, _underscore, api2, dbchanges2]
7
+ framework: "2.0"
8
+ client: shared
9
+ status: active
10
+ created: 2026-07-21
11
+ updated: 2026-07-21
12
+ ---
13
+
14
+ # Session: true-79191-fulfill-ship
15
+ **Date:** 2026-07-21
16
+ **Project/Repo:** toga2-supply (2.0), with _underscore / api2 / dbchanges2 backend
17
+ **Task:** TRUE-79191 Fulfill & Ship — apply David/Jeff review fixes to the Fulfill & Ship UI, produce the deployment order, and design a package units-of-measure change.
18
+
19
+ ---
20
+
21
+ ## What WORKED
22
+ <!-- All UI fixes below were verified by the developer in the browser this session -->
23
+ - Google Maps links fixed and verified. `GoogleMapsLink.tsx` now maps the physical address (`street||line1`, line2, city, `state.name`, zip) and EXCLUDES the addressee; the Edit Return Label modal's "Google Maps" span was wired with an `onClick`. Both open the correct location. (commit 651e9d9d0)
24
+ - Select Items horizontal scrollbar gone. Description truncation cap lowered per-table: Select Items (13 cols) `max-w-[20vw]`, Update Info (8 cols) keeps `max-w-[30vw]`. CSS `truncate` + `title` tooltip preserved. (651e9d9d0)
25
+ - Select Items row-click selects the row. Added `onRowClick` to `BasicTable` (ignores clicks on `input,button,a,select,textarea,label`); ShipmentItemsTable rows carry `uuid`, disabled rows skipped; the quantity input and checkbox still behave normally. (651e9d9d0)
26
+ - Item images display with placeholder fallback (verified: item with image shows it, items without show the placeholder). Uses computed `_underscore` Item fields `item._imageUrl` (Items.imageId→Images.sourceUrl) and `item._thumbnailImageUrl` (ItemImages default), rendered `_imageUrl || _thumbnailImageUrl || placeholder`. (commit dc900ea4e)
27
+ - Earlier this session, all committed + verified on TRUE-79191: SKU/UPC display fix (skuNumber/upcCode field-selectors), mint-green dirty-field border, red Delete Shipment button, reference-field hint text, responsive description truncation, table header/alignment + sticky-border fixes.
28
+ - Local test data seeded in Client_Growrk (SKU/UPC/Dell manufacturer on items 139/276; test image on item 139). DB-only, not in any repo.
29
+
30
+ ## What did NOT work — DO NOT RETRY THESE
31
+ - Saving a shipment returned `EO-1` "There is no field called 'needsReturnLabel' in the '_Model_Client_TrackingNumber' model." Root cause was a **git branch mismatch across repos** (_underscore was on a branch whose generated `Model/Client/TrackingNumber.php` lacked the field). DO NOT chase this as opcache (local php.ini has opcache DISABLED — `;zend_extension=opcache` — so files reload per request, no Apache restart needed) and DO NOT re-apply the migrations (the DB column, Core RecordField, and client AclFieldPermission were all already applied). Fix = put all fulfill/ship repos on the same branch (TRUE-79191).
32
+ - Hard-deleting duplicate item 2742 (merging into primary item 276) failed: `Cannot delete or update a parent row: ItemFulfillmentItemUnits_unitId FK` — item 2742's unit (serial FQ25WL3) is tied to a fulfillment record, and 276 already has its own FQ25WL3 unit. DO NOT DELETE 2742. Resolution used: repoint 2742's 8 SalesOrderItems to 276, NULL 2742's manufacturer to free the (catalog1, Dell, LATITUDE) unique slot, set 276 to Dell; 2742 left as an unreferenced stub (fulfillment history preserved).
33
+
34
+ ## Not tried yet (candidates for next session)
35
+ - Implement the package Units of Measure change (see plan) — NOT started; gated on Jeff's opt-in on the design.
36
+ - Promote the Growrk-only bridge-ACL migration (`Client_Growrk/2026-07-13a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql`) to a generic `Client/` fan-out migration so ALL clients get the tracking-number bridge AclLogicGroups (records 317-322) — needed for a multi-client rollout (otherwise 403 EZ-1 per client). Documented in the deployment order.
37
+
38
+ ## Current file state
39
+ | File | Status | Notes |
40
+ |------|--------|-------|
41
+ | toga2-supply (branch TRUE-79191) | committed & (merged to production earlier) | 5 session commits: 80724c1c2, 853b82e09, f041cfe57, dc900ea4e, 651e9d9d0 |
42
+ | toga2-supply/.env, .env.development, package-lock.json | modified, intentionally UNSTAGED | pre-existing local changes — never commit (.env is secrets/local) |
43
+ | _underscore, api2, dbchanges2 (branch TRUE-79191) | committed/pushed (partly merged to _production) | TRUE-79191 backend + DB migrations; unchanged this session (referenced only) |
44
+ | c:\WWW\TRUE-79191_deployment_order.md | created (external, not a repo) | Deploy order (DB→backend→frontend) + all-clients section; share to ClickUp |
45
+ | c:\WWW\package_units_of_measure_plan.md | created (external) | UoM design for Jeff; updated to enum-for-types (zero new tables recommended) |
46
+ | Client_Growrk DB (local) | test data only | items 139/276 SKU/UPC/Dell + item 139 test image; revert SQL was provided in chat |
47
+
48
+ ## Decisions made
49
+ - **Item image source:** render `item._imageUrl || item._thumbnailImageUrl || placeholder` — covers `Items.imageId` (single primary image) OR `ItemImages` (default thumbnail), else placeholder. Rejected: hardcoding placeholder (the pre-existing bug) or a single source.
50
+ - **Responsive truncation:** CSS `truncate` + a per-table viewport-relative `max-w-[NNvw]` cap (tuned by column count) + native `title` tooltip. Rejected: fixed char-count truncation (ExpandableCellContent) — not width-responsive and truncates early.
51
+ - **Google Maps query:** map the address only, never the addressee. Rejected: including the recipient name (caused Google to surface the person).
52
+ - **BasicTable row selection:** an `onRowClick` prop that ignores interactive descendants, rather than per-cell handlers. Reusable across tables.
53
+ - **Units of Measure (design, per Jeff):** measurement *types* are an ENUM (`measureType` LENGTH/VOLUME/WEIGHT/COUNT) — NO separate types table. Recommended to REUSE the existing client `Measures` table (already used by `Items.defaultMeasureId`) + add `conversionFactorToBase`, and add `dimensionMeasureId`/`volumeMeasureId` FKs on `TrackingNumbers` → **zero new tables**. Alternative (two dedicated new UoM tables) documented for opt-in. Carriers accept only IN/CM (dimensions) and LB/KG (weight), so the chosen measure must map/convert to the carrier enum (hence the conversion factor); volume is not sent to carriers.
54
+
55
+ ## Blockers
56
+ - none blocking code. The UoM implementation is gated on Jeff opting in to the design (which table strategy; is volume stored or derived; include weight unit too; core vs client seeding).
57
+
58
+ ## Exact next step
59
+ > Get Jeff's decision on `c:\WWW\package_units_of_measure_plan.md` (reuse `Measures` + `measureType` enum vs two new tables; volume stored vs derived; include weight UoM; core vs client), and whether the UoM work rides TRUE-79191 or becomes a new ticket. Then implement following the `needsReturnLabel` full-stack pattern (dbchanges2 migrations → `_underscore` Measure/TrackingNumber models → api2 field-selectors → toga2-supply UnitSelect wiring + Pending Shipments display). Separately, the deployment team runs `c:\WWW\TRUE-79191_deployment_order.md` — flag the FedEx production-endpoint config (beta.ini used sandbox) + api2 FPDF `composer install`, and the Client/ fan-out of the bridge-ACL migration for all clients.
60
+
61
+ ---
62
+ _Saved by /session-save on 2026-07-21_
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.401",
3
+ "version": "1.0.403",
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",