toga-ai 1.0.555 → 1.0.556
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.
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: session
|
|
3
|
+
slug: elite-supply-fe
|
|
4
|
+
title: Elite modal polish + ROOT CAUSE of platform /tracking-numbers 500 (labelPdfFile schema drift) — Shipments/Invoices blocked on backend column migration
|
|
5
|
+
author: tcox
|
|
6
|
+
repos: [toga2-supply, api2, _underscore]
|
|
7
|
+
framework: "2.0"
|
|
8
|
+
client: elite
|
|
9
|
+
status: active
|
|
10
|
+
created: 2026-08-11
|
|
11
|
+
updated: 2026-08-11
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Session: elite-supply-fe
|
|
15
|
+
**Date:** 2026-08-11
|
|
16
|
+
**Project/Repo:** toga2-supply (2.0) — read-only investigation in api2 + _underscore
|
|
17
|
+
**Task:** Elite order-details modal polish (Type row, $ symbols, Shipments/Invoices sections, orphan-SR empty state), inventory nested-view rename to backend's `inventory_units`, two `_beta` merge resolutions — and root-causing the platform-wide `/tracking-numbers` 500 to a model↔schema drift (`labelPdfFile`) that blocks Shipments/Invoices everywhere until backend ships a column migration.
|
|
18
|
+
|
|
19
|
+
> Continues session 2026-08-10-elite-supply-fe-tcox. Work now lives on **`_beta`** (user merged TRUE-80644 into it; earlier "local _production only" rule superseded by the user's own merges/commits).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What WORKED
|
|
24
|
+
- **PLATFORM ROOT CAUSE — /tracking-numbers (and /invoices) 500 whenever rows match:** `_Model_Client_TrackingNumber.labelPdfFile` and `_Model_Client_Invoice.invoicePdfFile` are `FIELD_STORAGE` fields added 2024-10-16 (`ffe72b61`, rgirish97, "Adding the fedex shipment api call") — but the columns exist in **no schema in any environment** (verified via information_schema on both dev-sandbox and prod). dbchanges2 only has the Core RecordFields insert (`2024-11b - item-fulfillments.sql`, field 1183). V2 row hydration lazy-selects STORAGE fields per returned row at depth 1 → 1054 unknown column → api2 `Controller/Index.php` catch-all (~line 364) mislabels ANY escaped Throwable as **EO-2 "A required database could not be reached"** (real exception goes to Sentry). Empty result = no hydration = 200 — which is why it was invisible for 10 months and why Elite (first client to return tracking rows) hit it. Sandbox unblock: `ALTER TABLE TrackingNumbers ADD COLUMN labelPdfFile LONGBLOB NULL;` + `ALTER TABLE Invoices ADD COLUMN invoicePdfFile LONGBLOB NULL;` in Client_Elite. Reported to backend.
|
|
25
|
+
- **Type row + $ symbols:** new `FIELDS/ELITE/BASEFIELDS.json` (full DEFAULTFIELDS copy per COMPASS pattern) with `salesOrderType.name` in fetchOrderDetails, a Type row in ORDERDETAILS (all Elite orders read "Drop Ship"), and `settings.currencyCharacter: "$"` (the symbol chain is `orderDetails.currency.symbol → fields.settings.currencyCharacter → ""`; only COMPASS files ever defined it).
|
|
26
|
+
- **Orphan-SR empty state:** resolver query exposes `isFetched`/`isError`; when settled with no SalesOrder uuid the effect nulls orderDetails → modal's existing `!orderDetails` Toaster path with ELITE label "No order details are available for this service request." Correctly shows on SR100004/100005/100007/100009/100010 (truly order-less post-merge data).
|
|
27
|
+
- **Deterministic resolver:** SR100001 links to TWO SalesOrders (SA100000 + SA100003); `getSalesOrderUuidForServiceRequest` now fetches `uuid,number` and sorts client-side by number → always SA100000.
|
|
28
|
+
- **Null-safety:** `response?.status` / `response?.error?.code` in getShipments + getOrderDetails — `togaApiRequest` returns null on any 5xx (axios throws on >=500), so the old `response.status` crashed with "Cannot read properties of null (reading 'status')".
|
|
29
|
+
- **Double-unwrap fix:** removed the `showInvoicesAndShipments` flag + hook-level unwrap — the merged `_beta` code unwraps in OrderDetailsModal (`invoiceData?.invoices` / `shipmentsData?.shipments`), so the hook must store the wrapper objects like every host.
|
|
30
|
+
- **ELITE getShipments hardening:** ASN tracking query skipped for ELITE (`AdvanceShippingNoticeUnits` table doesn't exist in Client_Elite; 0 ASN rows anyway) — without the skip it 500s and wipes already-fetched tracking numbers.
|
|
31
|
+
- **inventory_units rename (backend request):** Elite group option updated in DUMMYGROUPOPTIONS.ts — `nestedTableSlug`/`urlKeys.key`/`checkKey`/`tableDisplayData.nestedTable.tableSlug` → `inventory_units`, `nestedPrimaryRecordSlug` → `Items`. Verified view exists (Client_Elite.TableViews id 21, Units record). Extended the useFetchData primary-fetch guard to also null `"Items"` (else the expand param would collapse the primary items table to one row).
|
|
32
|
+
- **Export button off** for Elite Service Requests (`BASE.json exportButton.isEnabled: false`; gate at OrdersPage.tsx ~228).
|
|
33
|
+
- **Toaster centering (user chose this over a custom panel):** shared `Toaster.tsx` message span gets `flex-1 text-center` ONLY when message-only (no icon, no clearMessage/hasClearText). All other call sites pass clearMessage (3-child layout, untouched) or sit in shrink-to-fit wrappers (PrimaryTable "Something went wrong") where flex-1 can't expand — provably no visual change elsewhere.
|
|
34
|
+
- **Two `_beta` merge resolutions (TRUE-80644):** #1 — took `_beta`'s GLOBAL `ItemFulfillments_TrackingNumbers` join (deleted our ELITE ternary: keeping it would regress other hosts to the broken `ItemFulfillmentPackages` join) + kept our ASN-skip gate structure with `_beta`'s `.error?.code` ApiError style. #2 — combined both sides into `response?.error?.code`.
|
|
35
|
+
- **CodeRabbit fixes (guardrail-safe variants):** InventoryPage `?? defaultOption` for URL group uuid (was `.find(...)!` render crash); InventoryRouter redirect preserves query string; OrdersPage state re-sync effect for pageTitle/tableSlug after host-store hydration (with bail-out so other hosts get zero extra renders); useOrdersPageViewModel `?.` on admin/superuser branches (crash-safety only — did NOT change the dead `fieldMapping.compass` fallback).
|
|
36
|
+
- **Column-headers investigation (config, reverted by user as out-of-scope):** headers fall back to raw TableViewField slugs when no `label-singular`; joined columns read the CONTEXT-NESTED path `settings.fields[rec][field][ctxRec][ctxField]` (TableView.php sets contextTable/contextField for every joined column) so label rows need `contextRecordFieldId` per join. Full mapping produced: 566/574→ctx 1595, 679→ctx 2087, 203→ctx 192, 48/175/58→ctx 190, 28→ctx 43, 2766→flat. Blocked by Page.php:824 (ctx-190 rows would re-fatal inventory meta) + PageRecords missing Tickets & Service request types on `sales-orders-listing`.
|
|
37
|
+
- **Demo seed on SA100000 (SO id 258):** fulfillment `DEMO-IF-SA100000` (stage 3 Shipped) + tracking `9400111899560001234567` (USPS, method 1) & `794658209999` (FedEx, method 4) + invoice `DEMO-INV-100001` (OPEN, 1350.00 total / 675.00 due). Logs_Elite.Api confirmed the full modal pipeline 200s for orders without data.
|
|
38
|
+
|
|
39
|
+
## What did NOT work — DO NOT RETRY THESE
|
|
40
|
+
- **Context-free ClientRecordFieldSettings label rows** — land in the flat `settings.fields[rec][field]` path which the FE only reads for base-record columns; every joined column (8 of 9 on service-requests) reads the context-nested path. Headers unchanged. User reverted the rows.
|
|
41
|
+
- **`sort: ["number"]` as an API option on the resolver** — with the ServiceRequests join, `number` is ambiguous (both tables have it) → 500 → resolver null → EVERY SR showed "No order details". Client-side sort instead.
|
|
42
|
+
- **Hook-level invoices/shipments unwrap (`showInvoicesAndShipments`)** — after the `_beta` merge the modal already unwraps (`invoiceData?.invoices`); the flag double-unwrapped (`array.invoices` = undefined) and hid both sections FOR ELITE ONLY while data was correct.
|
|
43
|
+
- **NULL-data theories for the tracking 500** — `shippingMethodId` (user set methods 1/4 — still 500), `status` NULL, ACL record perms/field perms/record expressions (all present; expressions are literal `1`), missing bridge tables (all 11 exist), InherentRecordChildren (none for record 62). The column drift was the cause.
|
|
44
|
+
- **`DESCRIBE Databases` unquoted** — reserved word; needs backticks.
|
|
45
|
+
- **Trusting EO-2's "database could not be reached" text** — it's api2's catch-all label for ANY escaped Throwable during request processing (Index.php ~364); the real exception is in Sentry. Also 5xx responses do NOT appear in Logs_Elite.Api (fatals skip response logging).
|
|
46
|
+
- **Custom ELITE empty-state panel** (centered navy card + info icon) — worked, but user preferred the original Toaster design; replaced by the conditional centering fix in shared Toaster.tsx.
|
|
47
|
+
|
|
48
|
+
## Not tried yet (candidates for next session)
|
|
49
|
+
- **Backend column migration** (dbchanges2, all Client_* schemas, all envs): `TrackingNumbers.labelPdfFile` + `Invoices.invoicePdfFile` (or drop the fields from the models) — THE blocker for Shipments/Invoices sections everywhere. Sandbox ALTERs offered to user; unconfirmed whether run.
|
|
50
|
+
- Verify Shipments + Invoices render on SR100001 (`http://elite.togasupply:5173/?uuid=cfc6ea32-dcfa-46c0-bf1b-f40733117a0e&service-requests-modal=records-view`) once columns exist.
|
|
51
|
+
- Column-header labels: needs Page.php:824 isset guard → PageRecords adds (Tickets 8? + Service request types on page 2 `sales-orders-listing` — Core change, all clients) → context-scoped label rows per the mapping above (dbchanges2).
|
|
52
|
+
- Provider field in Order Details card — blocked on product definition (no provider on SalesOrders/ServiceRequests; PO vendor is multi-valued and mostly unlinked).
|
|
53
|
+
- Verify inventory_units nested expand on beta (backend's new view).
|
|
54
|
+
- Four-client regression pass (NYCHH/ENDEAVORHEALTH/COMPASS/COMPASSCANADA) before PR; user handles branching/publish.
|
|
55
|
+
- /capture: EO-2 signature doc + labelPdfFile drift + context-scoped label mechanism are all durable KB material.
|
|
56
|
+
|
|
57
|
+
## Current file state
|
|
58
|
+
| File | Status | Notes |
|
|
59
|
+
|------|--------|-------|
|
|
60
|
+
| src/pages/Orders/view/OrderView/viewModel/FIELDS/ELITE/BASEFIELDS.json | committed on _beta (via TRUE-80644 merges) | full per-host modal fields: Type row, $ currency, sections flags, ELITE no-details label; showInvoicesAndShipments REMOVED |
|
|
61
|
+
| src/pages/Orders/view/OrderView/viewModel/useOrderDetailsViewModel.ts | committed + merged | BASEFIELDS_ELITE import; orphan-state effect (isFetched/isError); unwrap branch removed; teammate's item-thumbnail work merged in |
|
|
62
|
+
| src/pages/Orders/api/OrdersApi.ts | merge #2 resolved in working tree — needs `git add` + merge commit | deterministic resolver; ELITE ASN skip; null-safe `response?.error?.code`; global ItemFulfillments_TrackingNumbers join (from _beta) |
|
|
63
|
+
| src/components/ui/Toaster.tsx | modified, uncommitted | message-only toasters center via conditional flex-1 text-center |
|
|
64
|
+
| src/pages/Orders/view/OrderView/components/OrderViewModalContent.tsx | modified (restored original Toaster call) | custom ELITE panel reverted per user |
|
|
65
|
+
| src/pages/Inventory/viewModel/FIELDS/DUMMYGROUPOPTIONS.ts | committed | ELITE option renamed to inventory_units / Items |
|
|
66
|
+
| src/components/ui/Tables/hooks/useFetchData.tsx | committed | primary-fetch guard extended to "Items" |
|
|
67
|
+
| src/pages/Orders/viewModel/FIELDS/ELITE/BASE.json | committed | exportButton.isEnabled false |
|
|
68
|
+
| src/pages/Orders/OrdersPage.tsx, InventoryPage.tsx, InventoryRouter.tsx, useOrdersPageViewModel.ts | committed | CodeRabbit fixes |
|
|
69
|
+
| dev-sandbox Client_Elite (data, user-run) | kept | SA100000 seed (fulfillment/tracking/invoice); tracking methods set; label rows REVERTED; ALTER TABLE columns offered — unconfirmed |
|
|
70
|
+
|
|
71
|
+
## Decisions made
|
|
72
|
+
- **Merge policy:** adopt `_beta`'s global fulfillment-join fix over our ELITE ternary (identical for Elite; keeps other hosts on the fixed join); combine null-safety + ApiError style as `response?.error?.code`.
|
|
73
|
+
- **Resolver determinism client-side** (not API `sort`) — avoids API sort-qualification semantics entirely.
|
|
74
|
+
- **Toaster fix in the shared component, conditioned on message-only** — user preferred original design; condition provably no-ops all other call sites. Rejected: custom ELITE panel (built then reverted), unconditional restyle (cross-host visual risk).
|
|
75
|
+
- **`fieldMapping.compass` dead fallback kept dead** (CodeRabbit wanted `.COMPASS`) — a live default would silently give unmapped hosts COMPASS's approvals config; `?.` crash-safety only.
|
|
76
|
+
- **Orphan-SR = designed empty state** via existing `!orderDetails` path with ELITE-worded label (option 1 from the deferred design question; product can still override).
|
|
77
|
+
|
|
78
|
+
## Blockers
|
|
79
|
+
- **labelPdfFile / invoicePdfFile column migration (backend)** — Shipments/Invoices sections cannot render anywhere until shipped (or sandbox ALTERs run for demo).
|
|
80
|
+
- Page.php:824 isset guard + PageRecords additions — pretty column headers.
|
|
81
|
+
- Product definition of "Provider" for the Order Details card.
|
|
82
|
+
|
|
83
|
+
## Exact next step
|
|
84
|
+
> Run (or confirm) the two sandbox ALTERs in dev-sandbox Client_Elite (`TrackingNumbers ADD labelPdfFile LONGBLOB NULL`, `Invoices ADD invoicePdfFile LONGBLOB NULL`), reload `http://elite.togasupply:5173/?uuid=cfc6ea32-dcfa-46c0-bf1b-f40733117a0e&service-requests-modal=records-view`, and verify the Shipments (USPS + FedEx) and Invoices (DEMO-INV-100001) cards render. Then finish the pending merge: `git add src/pages/Orders/api/OrdersApi.ts && git commit` on `_beta`, and commit Toaster.tsx + OrderViewModalContent.tsx.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
_Saved by /session-save on 2026-08-11_
|
package/package.json
CHANGED