toga-ai 1.0.337 → 1.0.339

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.
@@ -6,7 +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
- | [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/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/useAssignClientFields.ts, src/hooks/useDynamicConditionalFieldOptions.ts, src/stores/useFieldsStore.ts, src/components/BaseDetailField/BaseDetailField.tsx |
9
+ | [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/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 |
10
10
  | [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
11
  | [Multi-Tenant Resolution & Theming](features/multi-tenant-theming.md) | `toga2-commerce` serves multiple clients from one codebase. | src/themeConfig/themes.json, src/themeConfig/ThemeContext.tsx, src/themeConfig/types.ts, src/components/ThemeSwitcher/ThemeSwitcher.tsx, src/components/AuthLayout/AuthLayout.tsx, src/api/axiosInstance.ts, src/contexts/AuthContext.tsx, tailwind.config.js |
12
12
  | [AWS Amplify Build & Deploy (non-prod environments)](workflows/amplify-build-and-deploy.md) | How `toga2-commerce` (React + Vite, "commerce2-react") builds and deploys on **AWS Amplify**. | toga2-commerce/amplify.yml, toga2-commerce/.gitattributes, toga2-commerce/package.json, toga2-commerce/.github/workflows/sync-stage-environments.yml |
@@ -6,7 +6,7 @@ project: TOGa Commerce
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-07-10
9
+ updated: 2026-07-14
10
10
  owners: ["apeterson", "tcox"]
11
11
  files:
12
12
  - src/fieldsConfig/index.ts
@@ -15,6 +15,9 @@ files:
15
15
  - src/fieldsConfig/clientFields/COMPASSCANADA.json
16
16
  - src/fieldsConfig/clientFields/QUAD.json
17
17
  - src/pages/Cart/api/CartApi.ts
18
+ - src/hooks/useAuthenticationFlow.ts
19
+ - src/contexts/AuthContext.tsx
20
+ - src/pages/Login/viewModel/useLoginPageViewModel.ts
18
21
  - src/hooks/useAssignClientFields.ts
19
22
  - src/hooks/useDynamicConditionalFieldOptions.ts
20
23
  - src/stores/useFieldsStore.ts
@@ -53,7 +56,11 @@ resolved per tenant, per language, and per role**. There are **two layers**:
53
56
  QUAD are `false`.
54
57
  - `userApiFields` — the allow-list of user columns fetched at login; importantly it includes the
55
58
  tenant's **role flags**: COMPASS/COMPASSCANADA carry `_isAdmin`, `_isSupervisor`, `_isSuperAdmin`;
56
- QUAD carries `_isGlobalAdmin`, `_isItShopper`, `_isBuyer`. All include `_personaIds`.
59
+ QUAD carries `_isGlobalAdmin`, `_isItShopper`, `_isBuyer`. All include `_personaIds`. This key is
60
+ now the **single source** for every auth-flow user fetch: `AuthContext.tsx`,
61
+ `useLoginPageViewModel.ts`, and `useAuthenticationFlow.ts` (the SAML post-auth fetch) all resolve
62
+ it via `getClientLoginFields(host).userApiFields` — there is no longer any hardcoded copy of the
63
+ user field list anywhere in the app (see the `useAuthenticationFlow` note below).
57
64
  - `fetchUsersApiFields` — the allow-list of user columns fetched by the **view-as user search**
58
65
  (`fetchUsers()` in `src/pages/Cart/api/CartApi.ts`, driven from `NavIconList.tsx`). Distinct from
59
66
  `userApiFields` (which is the login fetch). COMPASS/COMPASSCANADA use the 14-field default list;
@@ -79,6 +86,23 @@ touching Cart code.
79
86
  same hardcoded QUAD-vs-default field-list pattern and is a candidate for the identical config
80
87
  treatment in a future ticket.
81
88
 
89
+ ### `userApiFields` and the SAML post-auth fetch (`useAuthenticationFlow`)
90
+
91
+ `src/hooks/useAuthenticationFlow.ts` no longer hardcodes the user field list for the SAML post-auth
92
+ user fetch. It previously carried an `if (hostNameCode === "QUAD") […] else […]` branch whose two
93
+ lists were **exact element-for-element duplicates** (same order) of the `userApiFields` already in
94
+ `COMPASS.json` / `COMPASSCANADA.json` / `QUAD.json`. It now resolves the list via
95
+ `getClientLoginFields(hostNameCode).userApiFields` — no JSON changes were needed. This is the same
96
+ "config, not `if (client === …)` branches" centralization as the `fetchUsersApiFields`/C6 refactor
97
+ above (sibling ticket TRUE-80015 did the identical treatment for `fetchUsers()` in `CartApi.ts`;
98
+ `useAuthenticationFlow` was TRUE-80017). With this change, `useAuthenticationFlow` was the **last
99
+ remaining hardcoded duplicate** of the user field list — `AuthContext.tsx` and
100
+ `useLoginPageViewModel.ts` already consumed config — so all user-field lists in the app now flow
101
+ through `getClientLoginFields`. Behavior-identical for all tenants, `tsc` clean.
102
+
103
+ Note: **COMPASSCANADA** previously fell into the generic `else` branch and now resolves to its own
104
+ `COMPASSCANADA.json` (currently identical content to COMPASS — a future divergence point).
105
+
82
106
  ## Layer B — the per-page FIELDS registry
83
107
 
84
108
  `src/fieldsConfig/index.ts` (~1100 lines) imports every page's per-tenant field constants (which
@@ -219,4 +243,10 @@ Common field attributes: `uuid`, `label`, `valueKey` (path into the data object)
219
243
  QUAD = 8-field), replacing the `if (fieldKey === "QUAD")` branch with a config lookup (C6). Noted
220
244
  the deliberate QUAD `supervisorUser.*` omission and the `fetchUser()` follow-up candidate. Refactor
221
245
  only, no behavior change; `tsc --noEmit` clean. (tcox)
246
+ - 2026-07-14 — Removed the last hardcoded user-field list: `useAuthenticationFlow.ts` (SAML post-auth
247
+ fetch) now reads `getClientLoginFields(hostNameCode).userApiFields` instead of an
248
+ `if (hostNameCode === "QUAD") … else …` duplicate of the JSON lists (TRUE-80017; sibling of the
249
+ TRUE-80015 `fetchUsers` refactor). All user-field lists now flow through config;
250
+ COMPASSCANADA now resolves its own JSON rather than the generic `else`. Behavior-identical, `tsc`
251
+ clean. (tcox)
222
252
  </content>
@@ -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/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/view/modals/ReturnShippingModal.tsx, toga2-supply/src/components/ui/BaseInput/BaseInput.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.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/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/view/modals/ReturnShippingModal.tsx, toga2-supply/src/components/ui/BaseInput/BaseInput.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, 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 |
@@ -18,6 +18,7 @@ files:
18
18
  - toga2-supply/src/pages/EditShipment/view/modals/ReturnShippingModal.tsx
19
19
  - toga2-supply/src/components/ui/BaseInput/BaseInput.tsx
20
20
  - toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts
21
+ - toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/formatShipmentData.ts
21
22
  - toga2-supply/src/pages/EditShipment/types.ts
22
23
  - toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx
23
24
  - toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx
@@ -96,16 +97,20 @@ The New Shipment / Edit Shipment form is **config-driven**: fields come from
96
97
  `viewModel/FIELDS/DUMMYUPDATESHIPMENTFIELDS.json`, are rendered by
97
98
  `view/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx` through the shared
98
99
  `EditShipmentForm.tsx`, and the individual inputs are `components/ui/BaseInput/BaseInput.tsx`
99
- (text/currency) plus react-select (State/Country). To change field layout, labels,
100
- required-ness, or ordering, edit the **config JSON**, not the component.
100
+ (text/currency) plus react-select (Carrier/State/Country/Signature Type). To change field
101
+ layout, labels, required-ness, or ordering, edit the **config JSON**, not the component.
102
+ **Every react-select field's form value is the whole option OBJECT `{uuid, name}`, never a
103
+ bare string** — see the gotcha below before wiring a new select field.
101
104
 
102
105
  - **Create vs Edit are distinct entry points (decision — kept, not merged).** Select Items →
103
106
  Next = create a **New Shipment**; the pending-shipments pencil = **edit** an existing draft.
104
107
  They are deliberately NOT merged and there is no auto-load from Select Items, because a Sales
105
108
  Order can have **multiple** shipments (partial fulfillment — Select Items shows
106
109
  Ordered/Fulfilled/Committed per line), so "the saved shipment" is not singular and auto-loading
107
- would be ambiguous. Page title now signals the mode: create = **"New Shipment"**, edit =
108
- **"Edit Shipment"** (create previously mis-titled "Update Info").
110
+ would be ambiguous. Page title signals the mode: create = **"Update Info"**, edit =
111
+ **"Edit Shipment"**. (Title history: create was "Update Info" → briefly changed to
112
+ "New Shipment" → **reverted to "Update Info" 2026-07-14 (David flagged "New Shipment" as
113
+ wrong)**. If you're re-deriving the "right" create title, David's call is "Update Info".)
109
114
  - **Fulfillment Location is READ-ONLY (decision — Eric, Exec Dir Services Ops, authoritative).**
110
115
  Sourced from the Sales Order's location and shown display-only; the value must **not** change
111
116
  in the tool — any change happens back at the SO. Implemented as `getAddress` fetching
@@ -256,6 +261,20 @@ the call 403s and returns no label.
256
261
  `valueKey "addressee"` — the same key as the Address name — so both wrote to `addressee` and the
257
262
  form showed the same value twice (e.g. "Eric" in both). Rebound Attention to `"attention"`. When a
258
263
  config-driven field mirrors another field's value, suspect a duplicated `valueKey`.
264
+ - **Config-driven react-select values are the whole option OBJECT `{uuid, name}`, not a bare
265
+ string — string comparisons silently fail to persist.** `BaseInput`'s `onChange` calls
266
+ `field.onChange({uuid, name})` and its value resolution reads `field.value.uuid`; this is the
267
+ repo-wide shape for every select field (carrier/state/shippingMethod — e.g. `data.carrier.uuid`).
268
+ So **any code mapping a select value into a payload MUST read `data.<field>.uuid`**, and **any
269
+ rehydrate/reset MUST set the option OBJECT** (not a string) or the select renders blank on reopen.
270
+ *The Signature Type bug (2026-07):* the mapping compared `data.signatureType === "Required"` (object
271
+ vs string) → always `false` → `requiresSignature` stayed `undefined` → dropped from the PUT payload
272
+ → never saved; and rehydrate set a bare string so the select showed blank when the shipment was
273
+ reopened. Fix: map on `data.signatureType?.uuid` (the `?.` tolerates the plain-string `useForm`
274
+ default) in **both** `formatShipmentData.ts` and `updateShipment` (`UpdateShipmentApi.ts`), and
275
+ rehydrate `signatureType` in `EditShipmentForm.tsx` to the option object `{uuid, name}` derived from
276
+ `trackingNumber.requiresSignature` (`true`→`{uuid:"Required",name:"Required"}`, `false`→Not Required,
277
+ `null`→None Specified). Reusable checklist for any NEW select field in these forms.
259
278
  - **The `/shipments` list is PER-SALES-ORDER (open product decision, Eric to decide).**
260
279
  `getShipments` filters by `SalesOrders.c_netsuiteInternalSalesOrderId = <internalId>`, so
261
280
  `/shipments` with no `internalId` shows the empty state — the tool is a per-SO **punch-out**
@@ -283,8 +302,9 @@ the call 403s and returns no label.
283
302
  - **Responsiveness (phase 2/3 — explicitly NOT in original scope per the 2026-02-27 Process Review
284
303
  and 2026-05-20 Dev Sync).** David Mancol's Figma annotation **is** the spec: reduce the in-box
285
304
  column count by 1 on narrower screens; flexible gaps that scale with screen size (min 2px, max
286
- 50px); may explore stacking. Owners: David Mancol (design) + Alexandra Peterson (phase 2/3). Not
287
- yet implemented.
305
+ 50px); may explore stacking. Owners: David Mancol (design) + Alexandra Peterson (phase 2/3).
306
+ **Partly landed 2026-07-14:** the flexible-gap part of the spec now ships as a CSS
307
+ `clamp(2px,1vw,50px)` on the row gaps; column-count reduction and stacking are still open.
288
308
  - **Reference 1/2 value wiring** — fields render but values aren't sourced/persisted; see the form
289
309
  section (SO# vs internal id, PO# in NetSuite) before wiring.
290
310
  - **Global-vs-per-SO Shipments list** — pending Eric's model decision; see the gotcha above.
@@ -325,6 +345,14 @@ not the base `_Model_Client_ItemFulfillment`. Tested with GroWrk; UPS support wa
325
345
  for Compass and is not yet in prod.
326
346
 
327
347
  ## Change history
348
+ - 2026-07-14 — TRUE-79191 (commit `724d17c1a`): fixed **Signature Type** not saving/rehydrating —
349
+ documented the reusable **whole-object react-select** convention (`{uuid,name}`; map on `.uuid`,
350
+ rehydrate the object) as a gotcha; the string comparison `data.signatureType === "Required"`
351
+ silently dropped `requiresSignature` from the PUT. Corrected the create-mode **page title back to
352
+ "Update Info"** (David reverted the earlier "New Shipment"). Noted the flexible-gap part of David's
353
+ responsiveness spec now ships as `clamp(2px,1vw,50px)`. (Logo swap to TOGA Technology branding and
354
+ the Reference 1/2 placeholder-hint text were cosmetic — no doc change; Ref 1/2 semantics already
355
+ recorded.) (mhammontree)
328
356
  - 2026-07-14 — TRUE-79191 (Figma-alignment pass on the config-driven New/Edit Shipment form):
329
357
  fixed the **Attention** field writing to `addressee` (rebound to `attention`); Figma layout
330
358
  (inline left address labels, residential checkbox below Country, carrier section as two vertical
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.337",
3
+ "version": "1.0.339",
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",