toga-ai 1.0.759 → 1.0.760

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 @@ project: _Underscore
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-09-02
9
+ updated: 2026-09-03
10
10
  owners: [bala, apeterson, jcardinal]
11
11
  files:
12
12
  - _underscore/Model/Client/TableView.php
@@ -28,6 +28,7 @@ related:
28
28
  - ../../../../clients/compass-canada/features/item-fulfillment-tableviews.md
29
29
  - ./acl-permission-chain.md
30
30
  - ../../toga25-supply/features/transfer-orders-page.md
31
+ - ../../toga25-supply/features/record-modals-and-nested-tables.md
31
32
  ---
32
33
 
33
34
  ## Summary
@@ -134,6 +135,36 @@ For NYCHH both hops are **100% populated** (PO items 1129/1129, VendorItems 2414
134
135
  **INNER** — no empty-grid risk (third failure mode above). Verify FK population per tenant first: a
135
136
  tenant with sparse `vendorItemId` would need LEFT OUTER or would empty the grid.
136
137
 
138
+ ### A dropped FILTER-ONLY join must be re-added when a row-filter still targets that table
139
+
140
+ The rebase above **dropped** the old SalesOrders→bridge→PurchaseOrders chain (join ids 123/124/141)
141
+ because those joins showed **no column** — they only filtered rows. But a filter-only join is still
142
+ needed if something still filters on that table. NYCHH's Inventory "Items by Customer POs" grouping
143
+ drills into `items-for-purchase-orders` with an `additionalDataSlug` that binds a
144
+ `(PurchaseOrders.uuid:eq:...)` where clause (see
145
+ [record-modals-and-nested-tables](../../toga25-supply/features/record-modals-and-nested-tables.md),
146
+ Pattern 5, and
147
+ [tableview-apiwhereclause-row-filtering](../../api2/features/tableview-apiwhereclause-row-filtering.md)).
148
+ After the rebase the view no longer joined PurchaseOrders, so that filter failed with **error
149
+ 3L-2492**.
150
+
151
+ Fix (confirmed working NYCHH 2026-09-03): **INSERT one filter-only `TableViewJoins` row** on the
152
+ `items-for-purchase-orders` view re-adding a real PurchaseOrders join — no column hangs off it:
153
+
154
+ - `joinRecordId = 17` (PurchaseOrders), `joinOnRecordFieldId = 81` (`PurchaseOrders.id`) as onA,
155
+ `parentRecordFieldId = 90` (`PurchaseOrderItems.purchaseOrderId`) as onB.
156
+ - `type INNER` — `purchaseOrderId` is always populated on PO items, so no empty-grid risk (third mode
157
+ above). `sortOrder 7` (after the existing 1–6).
158
+ - **No ACL row needed** if PurchaseOrders already has read grants for the caller's roles: NYCHH's
159
+ record 17 already had Base(1)/Developer(2)/API(3), so the ACL-INNER-JOIN joins query keeps it.
160
+ - Idempotent: key to the view by `TableViews.slug` (id-agnostic) with a fixed uuid and a `NOT EXISTS`
161
+ guard on `(tableViewId, joinRecordId=17)`. Core ids 17/81/90 verified stable/identical across prod
162
+ and client-sandbox.
163
+
164
+ **Both env states were verified rebased** (prod AND client-sandbox: view 16 at base recordId 18 with
165
+ no PurchaseOrders join) — the earlier "rebase is prod-only, not on client-sandbox" note is now stale.
166
+ Applied to client-sandbox then prod (Client_Nychh).
167
+
137
168
  Core ids for this conversion (verified prod 2026-09-02, identical across clients/envs): **Records** —
138
169
  sales-order-items 15, purchase-order-items 18, vendor-items 19, items 21; item-level SO/PO bridges
139
170
  289 (downstream) / 290 (upstream). **RecordFields** — `PurchaseOrderItems.quantity` 94,
@@ -316,6 +347,13 @@ Core-level reference ids used (identical across all clients and environments): *
316
347
 
317
348
  ## Change history
318
349
 
350
+ - 2026-09-03 — Added the **filter-only join counterpart** to the PO-items rebase: dropping a
351
+ column-less join that only *filtered* rows (SalesOrders→bridge→PurchaseOrders, ids 123/124/141)
352
+ breaks any row-filter still targeting that table. NYCHH's `items-for-purchase-orders`
353
+ `(PurchaseOrders.uuid:eq:...)` filter errored **3L-2492** post-rebase; fix is one INNER filter-only
354
+ PurchaseOrders join (joinRecordId 17, onA `PurchaseOrders.id` 81, onB `PurchaseOrderItems.purchaseOrderId`
355
+ 90, sortOrder 7, no column, no new ACL). Confirmed working; both prod and client-sandbox verified
356
+ rebased (the prior "prod-only" note is stale). (jcardinal)
319
357
  - 2026-09-02 — Documented the **sales-order-item → purchase-order-item view conversion**: it needs an
320
358
  extra **VendorItems** hop because `PurchaseOrderItems` has no `itemId` (catalog reached via
321
359
  `vendorItemId → VendorItems (record 19) → itemId → Items`), unlike `SalesOrderItems` which joins
@@ -6,8 +6,8 @@ project: TOGa 2.5 Supply
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-09-02
10
- owners: [apeterson, tcox]
9
+ updated: 2026-09-03
10
+ owners: [apeterson, tcox, jcardinal]
11
11
  files:
12
12
  - toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/hooks/usePurchaseOrderDetails.ts
13
13
  - toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/useSalesOrderRecordModalLayoutModel.tsx
@@ -127,6 +127,18 @@ level. Each level fetches its own meta + data and renders a `GenericTableLayout`
127
127
 
128
128
  `additionalData` is produced per-level by callbacks (the WHERE-filter shape from Pattern 4). Each
129
129
  level runs its own `useServerTableUrlState` and strips its own slug key, isolating URL state.
130
+
131
+ > **The FE APPENDS `.uuid` to a swap level's `additionalDataSlug` itself — so the stored surface
132
+ > value must be the BARE table name (`PurchaseOrders`), never `<Table>.uuid`.** The grouping config
133
+ > lives on `Core.SurfaceElements.config` (`inventory-list-groupings`, e.g. element key `posByItems`,
134
+ > in `$.levels[N].additionalDataSlug`). If you store `PurchaseOrders.uuid` there, the FE produces a
135
+ > **doubled** where clause `(PurchaseOrders.uuid.uuid:like:...)` and the filter never binds. Fix the
136
+ > stored value to just `PurchaseOrders` (JSON_SET keyed by `Surfaces.slug` + `config.key`, guarded to
137
+ > the stale value so it is re-runnable — id/uuid-agnostic because ids differ per env). Confirmed on
138
+ > NYCHH 2026-09-03: this Core row is all-client (no NYCHH SurfaceOverride), and its old
139
+ > `SalesOrders.uuid` was already wrong for a child view named `items-for-purchase-orders`. Sibling
140
+ > element `itemsByPOs` (view `purchase-orders_items`) still carries the stale `SalesOrders.uuid` —
141
+ > likely the same bug, not yet fixed.
130
142
  A page-level `pageMeta` (from `useFetchPageMeta`) flows down for field-label overrides. The page
131
143
  view model builds `TableLevel[]` arrays, picks the active one via a URL param, and passes `levels`
132
144
  to `GenericNestedTables` with `key={activeGrouping.key}` to force remount and avoid stale state.
@@ -274,6 +286,12 @@ Scaffold per the `ItemRecordModalLayout` pattern (`src/layout/ItemRecordModalLay
274
286
  [Transfer Orders page](transfer-orders-page.md).
275
287
 
276
288
  ## Change history
289
+ - 2026-09-03 — Documented that the FE **appends `.uuid`** to a `GenericNestedTables` swap level's
290
+ `additionalDataSlug`, so the stored `Core.SurfaceElements.config` value must be the **bare table
291
+ name** (`PurchaseOrders`), not `<Table>.uuid` — a `.uuid` in the stored value produces a doubled
292
+ `(PurchaseOrders.uuid.uuid:like:...)` where clause and the filter never binds. Found fixing the
293
+ NYCHH Inventory "Group: Items by Customer POs" grouping (`inventory-list-groupings`, element
294
+ `posByItems`); sibling `itemsByPOs` still stale. (jcardinal)
277
295
  - 2026-09-02 — Fixed the approve/deny modal's Submit/Cancel row being cut off by a long "Reason for
278
296
  Request" (found in testing by Skyler; approach agreed with David — grow the height a little, scroll
279
297
  when it is very long). The single-action dialog is now taller but viewport-capped, and its action row
@@ -18,7 +18,7 @@ project: _Underscore
18
18
  client: nychh
19
19
  type: profile
20
20
  status: active
21
- updated: 2026-09-02
21
+ updated: 2026-09-03
22
22
  owners: ["jcardinal", "apeterson", "bala", "akhokhani"]
23
23
  files:
24
24
  - dbchanges2/Client_Nychh/2026-09-02a - TransferOrderNetsuitePushInterceptor.sql
@@ -97,15 +97,32 @@ table views. Client-specific DB change-sets live in `dbchanges2/Client_Nychh/`.
97
97
  items 1129/1129, VendorItems 2414/2414) so both stay INNER. Seeds Developer-role record grants for
98
98
  records 18 and 19 (both had only Base+API) plus Developer read on `PurchaseOrderItems.quantity`
99
99
  (field 94); roles resolved by name, uuid-keyed, idempotent. Mechanism:
100
- [tableview-joins](../../2.0/apps/_underscore/features/tableview-joins.md). 🚨 **Applied to PROD
101
- only so far** (view 16 rebased, chain returns 1131 rows) — **NOT run on client-sandbox** (still the
102
- old sales-order-items version); the parent 2026-08-31a went to prod + client-sandbox, this one is
103
- prod-only. **OPEN:** the parent `purchase-orders` view filters to vendor 172 (`apiWhereClause
100
+ [tableview-joins](../../2.0/apps/_underscore/features/tableview-joins.md). **Applied to prod AND
101
+ client-sandbox** — both verified rebased 2026-09-03 (view 16 at base recordId 18, no PurchaseOrders
102
+ join). An earlier note here said this rebase was prod-only / not on client-sandbox; that is **stale**
103
+ — client-sandbox is also rebased. **OPEN:** the parent `purchase-orders` view filters to vendor 172
104
+ (`apiWhereClause
104
105
  (vendorId:eq:172)`); this item view has no `apiWhereClause`, so it lists items for all POs — left
105
106
  unfiltered (mirrors prior state), flagged as a decision for the dev. A "3L-2250" error reported
106
107
  right after this deploy was **unrelated** — prod `Logs.Issue` reference **3L** is a Prudential ASN
107
108
  error (`Client_Prudential.AdvanceShippingNoticeUnits` doesn't exist); the suffix is the occurrence
108
109
  count (3L, occurrence 2250).
110
+ - **"Group: Items by Customer POs" grouping fixed to drill into PO items (2026-09-03).** After the
111
+ `items-for-purchase-orders` view was rebased to PO-items, the Inventory groupings surface
112
+ (`inventory-list-groupings`, element `posByItems`) was broken. Two fixes, both applied to
113
+ client-sandbox then prod (confirmed working):
114
+ 1. **Stale filter slug** — the swap level's `additionalDataSlug` was `SalesOrders.uuid`; changed to
115
+ `PurchaseOrders`. The FE **appends `.uuid` itself**, so the stored value must be the bare table
116
+ name — `PurchaseOrders.uuid` produced a doubled `(PurchaseOrders.uuid.uuid:like:...)` clause.
117
+ This config is on `Core.SurfaceElements.config` (all-client, no NYCHH override); JSON_SET keyed by
118
+ `Surfaces.slug` + `config.key`, guarded/re-runnable. Sibling `itemsByPOs` still carries the stale
119
+ `SalesOrders.uuid` — likely the same bug, **not yet fixed**.
120
+ 2. **Missing join** — the `(PurchaseOrders.uuid:eq:...)` filter errored **3L-2492** because the
121
+ rebase dropped the old SalesOrders→PurchaseOrders filter chain and the view no longer joined
122
+ PurchaseOrders. Added one filter-only INNER `TableViewJoins` row (joinRecordId 17, onA
123
+ `PurchaseOrders.id` 81, onB `PurchaseOrderItems.purchaseOrderId` 90, sortOrder 7, no column). No
124
+ new ACL — record 17 already has Base/Developer/API read. Mechanism:
125
+ [tableview-joins](../../2.0/apps/_underscore/features/tableview-joins.md).
109
126
  - **`inventory_units` table view carries item detail as of 2026-08-18** — Part Number, Manufacturer
110
127
  and Item Description sit directly after Asset Tag, reached through a **chained** Units → Items →
111
128
  Manufacturers join (`dbchanges2/Client_Nychh/2026-08-18 - InventoryUnitsItemColumns.sql`, identical
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.759",
3
+ "version": "1.0.760",
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",