toga-ai 1.0.683 → 1.0.684
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.
|
@@ -92,6 +92,43 @@ response that walks that collection can 500. Two defences, both cheap:
|
|
|
92
92
|
The fragility itself is **unfixed** — any depth ≥ 2 response is exposed. Lowering depth removes
|
|
93
93
|
*your* exposure, not the defect.
|
|
94
94
|
|
|
95
|
+
### ⚠ `calcDepth` defaults to **1** — a calculated field one FK hop out comes back NULL, silently
|
|
96
|
+
|
|
97
|
+
`calcDepth` bounds how deep `FIELD_SQL` **calculated** fields are evaluated, independently of
|
|
98
|
+
`depth`. At the default of **1** only the requested record's own calculated fields resolve; a
|
|
99
|
+
calculated field on a record reached through an FK returns **`null` with no message** — no `EV-8`,
|
|
100
|
+
no warning, a 200 that merely looks like empty data.
|
|
101
|
+
|
|
102
|
+
Worked example: `_Model_Client_Location` exposes
|
|
103
|
+
`_addressLine1/_addressLine2/_addressCity/_addressState/_addressZip` as `FIELD_SQL`. Requested from
|
|
104
|
+
a record that only *points at* a Location (`GET /v2/transfer-orders/{uuid}` with the location
|
|
105
|
+
expanded), they need **`calcDepth: 2`**. Rule of thumb: **raise `calcDepth` by one for every FK hop
|
|
106
|
+
between the requested record and the calculated field's model**, and suspect it first whenever a
|
|
107
|
+
calculated field is null on a nested object but correct when that object is fetched directly.
|
|
108
|
+
Definition of the fields themselves:
|
|
109
|
+
[FIELD_SQL calculated fields](../../_underscore/features/calculated-sql-fields.md).
|
|
110
|
+
|
|
111
|
+
### What nests by default is `InherentRecordChildren` — everything else needs the nested ROUTE
|
|
112
|
+
|
|
113
|
+
A record's one-to-many children arrive inside the record response **only** if `Core.
|
|
114
|
+
InherentRecordChildren` declares them. `sales-orders` (record 14) has **seven**; plenty of records
|
|
115
|
+
have **none** — `transfer-orders` (312) had **zero** as of 2026-08-28, so `transferOrderItems` never
|
|
116
|
+
appears in the record payload no matter what `fields`/`depth` ask for. The client must call the
|
|
117
|
+
**nested route** instead:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
GET /v2/transfer-orders/{uuid}/transfer-order-items
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- **The JSON key of an inherent child is the camelCase of the child ROUTE**, not of the table or the
|
|
124
|
+
model (`V2.php` ~L6310, via `_String::CASE_KEBAB` → `CASE_CAMEL`). `transfer-order-items` →
|
|
125
|
+
`transferOrderItems`.
|
|
126
|
+
- **Adding an `InherentRecordChildren` row is a breaking-shape change, not a feature flag.** It
|
|
127
|
+
alters the default response for **every** existing caller of that route — including 1.0 importers
|
|
128
|
+
and NetSuite sync — so the blast radius has to be surveyed first. The transfer-order build
|
|
129
|
+
deliberately declined to add one and named the child route in the consuming surface's config
|
|
130
|
+
instead. See [Transfer Orders page](../../toga25-supply/features/transfer-orders-page.md).
|
|
131
|
+
|
|
95
132
|
### ⚠ `join` / `ojoin` drive the WHERE/filter — NOT the response shape
|
|
96
133
|
|
|
97
134
|
**`join` and `ojoin` change which rows come back, not what the JSON looks like.** The response
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| [Column Visibility (URL-driven show/hide columns)](features/column-visibility.md) | A "Columns" header button that opens a modal listing every column from the table meta, lets the user show/hide columns, adjusts the table live, and persists the | toga25-supply/src/components/ColumnVisibilityModal/, toga25-supply/src/pages/SalesOrders/SalesOrders.tsx, toga25-supply/src/pages/SalesOrders/viewModel/useSalesOrdersPageViewModel.tsx, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrdersTableData.tsx |
|
|
10
10
|
| [Force Logout on Deployment (useDeploymentGuard)](features/force-logout-on-deployment.md) | On large deployments the backend bumps the Core parameter `META_LAST_REFRESH_DATETIME`. | toga25-supply/src/hooks/useDeploymentGuard.tsx, toga25-supply/src/App.tsx |
|
|
11
11
|
| [Meta-Driven Page & Table Setup](features/meta-driven-table-data.md) | A page in this app is **meta-driven end to end**: the page view model fetches *page meta* (labels, sections, ACL) and *table meta* (the columns/fields + table s | toga25-supply/src/pages/SalesOrders/viewModel/useSalesOrdersPageViewModel.tsx, toga25-supply/src/pages/TransferOrders/viewModel/useTransferOrdersPageViewModel.tsx, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrdersTableState.ts, toga25-supply/src/hooks/useTablePageMeta.ts, toga-blox-npm/dist/hooks/useFetchPageMeta.d.ts, toga-blox-npm/dist/hooks/useFetchTablePageMeta.d.ts, toga-blox-npm/dist/hooks/useAssignTableFieldLabels.d.ts, toga-blox-npm/dist/components/Table/hooks/useTableData.d.ts |
|
|
12
|
-
| [Record Modals & Nested Tables](features/record-modals-and-nested-tables.md) | The repo's family of modal + nested-table patterns layered over toga-blox `TableRecordModal` and `PrimaryTable*Layout`. | toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/hooks/usePurchaseOrderDetails.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/useSalesOrderRecordModalLayoutModel.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/FIELDS/apiFields.json, toga25-supply/src/pages/SalesOrders/helpers/surfaceBundleToTenantFields.ts, toga25-supply/src/layout/PrimaryTableServerLayout/PrimaryTableServerLayout.tsx, toga25-supply/src/layout/PrimaryTableServerLayout/types.ts, toga25-supply/src/layout/ItemRecordModalLayout/, toga25-supply/src/layout/SalesOrderRecordModalLayout/, toga25-supply/src/layout/SalesOrderItemsTableLayout/, toga25-supply/src/layout/ItemFulfillmentModal/, toga25-supply/src/layout/GenericNestedTables/GenericNestedTables.tsx, toga25-supply/src/layout/GenericNestedTables/GenericTableLayout.tsx, toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx, toga25-supply/src/pages/Inventory/viewModel/FIELDS/DEFAULT/inventoryGroupings.json, toga25-supply/src/hooks/useTableCellInteractions.ts, toga25-supply/src/hooks/useServerTableUrlState.ts, toga25-supply/src/layout/RecordApprovalModal/helpers/handleFormatApprovalWorkflowPayload.ts, toga25-supply/src/layout/RecordApprovalModal/api/approvalDecisionsApi.ts |
|
|
12
|
+
| [Record Modals & Nested Tables](features/record-modals-and-nested-tables.md) | The repo's family of modal + nested-table patterns layered over toga-blox `TableRecordModal` and `PrimaryTable*Layout`. | toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/hooks/usePurchaseOrderDetails.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/useSalesOrderRecordModalLayoutModel.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/FIELDS/apiFields.json, toga25-supply/src/pages/SalesOrders/helpers/surfaceBundleToTenantFields.ts, toga25-supply/src/layout/PrimaryTableServerLayout/PrimaryTableServerLayout.tsx, toga25-supply/src/layout/PrimaryTableServerLayout/types.ts, toga25-supply/src/layout/ItemRecordModalLayout/, toga25-supply/src/layout/SalesOrderRecordModalLayout/, toga25-supply/src/layout/SalesOrderItemsTableLayout/, toga25-supply/src/layout/ItemFulfillmentModal/, toga25-supply/src/layout/GenericNestedTables/GenericNestedTables.tsx, toga25-supply/src/layout/GenericNestedTables/GenericTableLayout.tsx, toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx, toga25-supply/src/pages/Inventory/viewModel/FIELDS/DEFAULT/inventoryGroupings.json, toga25-supply/src/pages/TransferOrders/view/TransferOrderRecordModalLayout/TransferOrderRecordModalLayout.tsx, toga25-supply/src/hooks/useTableCellInteractions.ts, toga25-supply/src/hooks/useServerTableUrlState.ts, toga25-supply/src/layout/RecordApprovalModal/helpers/handleFormatApprovalWorkflowPayload.ts, toga25-supply/src/layout/RecordApprovalModal/api/approvalDecisionsApi.ts |
|
|
13
13
|
| [Side navigation & default route — an empty nav renders a BLANK PAGE and gets reported as "cannot log in"](features/side-navigation-and-default-route.md) | The 2.5 side nav is **100% backend-driven** by the `navigation` surface bundle, and the same list also decides **which routes exist** and **where `/` lands**. | toga25-supply/src/routes.tsx, toga25-supply/src/layout/AppLayout/viewModel/useAppLayoutViewModel.ts, api2/Component/Api/V2/V2.php, _underscore/Model/Core/Surface.php |
|
|
14
14
|
| [SSO redirect & public-vs-user session gating (useAuthenticationFlow)](features/sso-redirect-and-session-gating.md) | How 2.5 Supply decides, on every navigation, whether an anonymous visitor should be bounced to their client's SSO IdP instead of the local `/login` form. | toga25-supply/src/hooks/useAuthenticationFlow.ts, toga25-supply/src/routes.tsx, toga25-supply/src/contexts/AuthContext.tsx, toga25-supply/src/api/api.ts |
|
|
15
15
|
| [Surface Frontend (DB-driven UI consumption, src/surface/)](features/surface-frontend.md) | The frontend consumer of the platform-wide Surface layer — DB-driven UI config fetched from `GET /v2/surfaces/meta?slug=<slug>` instead of statically-imported J | toga25-supply/src/App.tsx, toga25-supply/src/surface/evaluateSurfaceRule.ts, toga25-supply/src/layout/RecordApprovalModal/, toga25-supply/src/contexts/AuthContext.tsx, toga25-supply/src/surface/applyColSpan.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/sectionRenderers.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getVisibleSections.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/layoutComponents/SalesOrderApprovalSummaryGrid.tsx, toga25-supply/src/surface/useFetchSurfaceMeta.ts, toga25-supply/src/pages/SalesOrders/helpers/surfaceBundleToTenantFields.ts, toga25-supply/src/pages/ServiceRequests/view/ServiceRequestRecordModalLayout/ServiceRequestRecordModalLayout.tsx, toga25-supply/src/pages/ServiceRequests/view/ServiceRequestRecordModalLayout/view/ServiceRequestsView.tsx, toga25-supply/src/pages/ServiceRequests/view/ServiceRequestRecordModalLayout/viewModel/useServiceRequestRecordModalLayoutModel.tsx, toga25-supply/src/pages/ServiceRequests/view/ServiceRequestRecordModalLayout/viewModel/FIELDS/apiFields.json, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderTopBar.tsx, toga25-supply/src/pages/SalesOrders/helpers/buildPatchedTenantFields.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/viewModel/useSalesOrderRecordModalLayoutModel.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/SalesOrderView.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/layoutComponents/SalesOrderSummaryGrid.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getDetailSections.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderNotesSection.tsx, toga25-supply/src/pages/SalesOrders/helpers/cleanOrder.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/AdminNotesSection.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/getAdminNotes.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/helpers/index.ts, toga25-supply/src/surface/evaluateSurfaceRule.ts, toga25-supply/src/surface/resolveElementState.ts, toga25-supply/src/pages/SalesOrders/helpers/evaluateEnableRule.ts, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrderRowRecordState.ts, toga25-supply/src/surface/actionRegistry.ts, toga25-supply/src/surface/componentRegistry.tsx, toga25-supply/src/surface/SurfaceActionBar.tsx, toga25-supply/src/surface/SurfaceSection.tsx, toga25-supply/src/surface/resolve.ts, toga25-supply/src/surface/types.ts, toga25-supply/src/surface/index.ts, toga25-supply/src/pages/Login/LoginPage.tsx, toga25-supply/src/pages/SalesOrders/SalesOrders.tsx, toga25-supply/src/pages/SalesOrders/view/SurfaceRowActions.tsx, toga25-supply/src/pages/SalesOrders/hooks/useSalesOrderVip.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/view/sections/SalesOrderTopBar.tsx, toga25-supply/src/pages/Items/ItemsPage.tsx, toga25-supply/src/pages/Items/viewModel/useItemsPageViewModel.tsx, toga25-supply/src/pages/VendorItems/VendorItemsPage.tsx, toga25-supply/src/pages/VendorItems/viewModel/useVendorItemsPageViewModel.tsx, toga25-supply/src/pages/Inventory/Inventory.tsx, toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx, toga25-supply/src/pages/Inventory/viewModel/FIELDS/index.ts, toga25-supply/src/fieldsConfig/index.ts, toga25-supply/src/layout/ItemRecordModalLayout/helpers/surfaceBundleToItemFields.ts, toga25-supply/src/layout/ItemRecordModalLayout/helpers/index.ts, toga25-supply/src/layout/ItemRecordModalLayout/viewModel/useItemRecordModalViewModel.tsx, toga25-supply/src/layout/ItemRecordModalLayout/ItemRecordModalLayout.tsx, toga25-supply/src/layout/ItemRecordModalLayout/components/ItemRecordView.tsx, toga25-supply/src/surface/useStatusColors.ts, toga25-supply/src/surface/SurfaceHeader.tsx, toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/helpers/surfaceBundlesToDecisionFields.ts, toga25-supply/src/pages/SalesOrders/view/SalesOrderApprovalModalsLayout/viewModel/useApprovalModalViewModel.tsx |
|
|
@@ -6,7 +6,7 @@ project: TOGa 2.5 Supply
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-08-
|
|
9
|
+
updated: 2026-08-28
|
|
10
10
|
owners: [apeterson]
|
|
11
11
|
files:
|
|
12
12
|
- toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/hooks/usePurchaseOrderDetails.ts
|
|
@@ -23,6 +23,7 @@ files:
|
|
|
23
23
|
- toga25-supply/src/layout/GenericNestedTables/GenericTableLayout.tsx
|
|
24
24
|
- toga25-supply/src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx
|
|
25
25
|
- toga25-supply/src/pages/Inventory/viewModel/FIELDS/DEFAULT/inventoryGroupings.json
|
|
26
|
+
- toga25-supply/src/pages/TransferOrders/view/TransferOrderRecordModalLayout/TransferOrderRecordModalLayout.tsx
|
|
26
27
|
- toga25-supply/src/hooks/useTableCellInteractions.ts
|
|
27
28
|
- toga25-supply/src/hooks/useServerTableUrlState.ts
|
|
28
29
|
- toga25-supply/src/layout/RecordApprovalModal/helpers/handleFormatApprovalWorkflowPayload.ts
|
|
@@ -31,6 +32,8 @@ related:
|
|
|
31
32
|
- ../architecture.md
|
|
32
33
|
- meta-driven-table-data.md
|
|
33
34
|
- ../../api2/features/tableview-field-metadata.md
|
|
35
|
+
- transfer-orders-page.md
|
|
36
|
+
- ../../api2/features/v2-rest-query-contract.md
|
|
34
37
|
---
|
|
35
38
|
|
|
36
39
|
## What it is
|
|
@@ -235,7 +238,25 @@ Scaffold per the `ItemRecordModalLayout` pattern (`src/layout/ItemRecordModalLay
|
|
|
235
238
|
join is not feasible for a list, so that column needs the backend field (promote `_purchaseOrders`
|
|
236
239
|
to base `_Model_Client_SalesOrder`) or be hidden for Quad. **Not addressed** — open follow-up.
|
|
237
240
|
|
|
241
|
+
- **ONE `TableRecordModal` must own every state — loading, error and loaded.** Rendering a second
|
|
242
|
+
`TableRecordModal` for the loaded state puts a **different element type at the same position in the
|
|
243
|
+
tree**, so React unmounts the first and mounts the second: the CSS keyframe restarts and the user
|
|
244
|
+
sees the slide-up animation replay the moment the data arrives. Keep a single modal element and
|
|
245
|
+
switch only its **children** on the fetch state. Same defect and same fix on the ServiceRequest and
|
|
246
|
+
Transfer Order modals.
|
|
247
|
+
- **A record's child rows may need a SECOND request.** Children nest inside the record response only
|
|
248
|
+
when `Core.InherentRecordChildren` declares them — `sales-orders` does, `transfer-orders` does
|
|
249
|
+
**not**. When they do not, fetch the nested route (`/{record}/{uuid}/{child-route}`) and read the
|
|
250
|
+
child route from the surface's `config.childRoute` rather than hardcoding it. See
|
|
251
|
+
[v2-rest-query-contract](../../api2/features/v2-rest-query-contract.md) and
|
|
252
|
+
[Transfer Orders page](transfer-orders-page.md).
|
|
253
|
+
|
|
238
254
|
## Change history
|
|
255
|
+
- 2026-08-28 — Added two modal rules confirmed on the Transfer Orders build: **one
|
|
256
|
+
`TableRecordModal` owns loading/error/loaded** (a second one at the same tree position swaps
|
|
257
|
+
element types and replays the slide-up animation), and a record whose children are **not** declared
|
|
258
|
+
in `InherentRecordChildren` needs a **second** request to the nested child route, with the route
|
|
259
|
+
read from the surface `config.childRoute`. (apeterson)
|
|
239
260
|
- 2026-08-21 — Fixed Quad SO record-modal 400 (`EV-8 _purchaseOrders`): the modal fetch requested
|
|
240
261
|
the Compass-only `_purchaseOrders` calc field for all tenants, but it exists only on the Compass
|
|
241
262
|
model — Quad has no such field, and the missing field failed the whole modal fetch. Split PO-number
|
package/package.json
CHANGED