toga-ai 1.0.660 → 1.0.662
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.
- package/knowledge/1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md +48 -0
- package/knowledge/2.0/apps/_underscore/INDEX.md +1 -1
- package/knowledge/2.0/apps/_underscore/features/recursive-item-fulfillments.md +19 -0
- package/knowledge/2.0/apps/_underscore/features/tracking-number-bridges.md +38 -9
- package/knowledge/2.0/apps/toga-blox/INDEX.md +1 -0
- package/knowledge/2.0/apps/toga-blox/workflows/dynamic-publish-pipeline.md +1 -0
- package/knowledge/2.0/apps/toga-blox/workflows/landing-a-large-feature-branch.md +80 -0
- package/knowledge/INDEX.md +1 -1
- package/knowledge/clients/quad/profile.md +18 -8
- package/package.json +1 -1
|
@@ -190,6 +190,40 @@ See the [tracking-number bridge doc](../../../2.0/apps/_underscore/features/trac
|
|
|
190
190
|
0 of their fulfillments resolve an upstream sales order). `/units` writes and all three
|
|
191
191
|
tracking-bridge models have **no** interceptor, and **DELETE fires none**.
|
|
192
192
|
|
|
193
|
+
### Single-tracking-number fan-out to items (318) and units (319) — corrected 2026-08-26
|
|
194
|
+
|
|
195
|
+
The earlier "maintains all three bridges" claim was **only true for 317 (header)**: in prod
|
|
196
|
+
`Client_Quad` had **0** rows in 318 and only partial 319. A NetSuite item fulfillment carries
|
|
197
|
+
**exactly one** tracking number, and item (318) + unit (319) tracking are meant to **mirror** that
|
|
198
|
+
single header number. Two bugs sat in the `if ($cntTrackingNumbers == 1)` branch of
|
|
199
|
+
`syncItemFulfillmentFromNetsuite`:
|
|
200
|
+
|
|
201
|
+
- **318 (item) was NEVER written** — the item-level bridge went unpopulated, so any fulfillment
|
|
202
|
+
TableView reading 318 showed a blank Tracking #/Carrier column (the Quad live bug).
|
|
203
|
+
- **319 (unit) received only the LAST item's units.**
|
|
204
|
+
`$lookupItemFulfillmentItemUnitsByNetsuite…AssignementId` (and the sibling existing-unit-tracking
|
|
205
|
+
lookup) was **rebuilt/reset per item inside the item loop** but **consumed once after the loop** —
|
|
206
|
+
so only the final processed item's units got tracking; serialized units on earlier items were
|
|
207
|
+
silently skipped (e.g. `Client_Quad` IF 1688 / SO 287406, whose one unit sat on the first item and
|
|
208
|
+
got none). Same lesson as the sparse-client `TypeError` above: a per-item structure consumed
|
|
209
|
+
outside its loop must not be reset inside it.
|
|
210
|
+
|
|
211
|
+
**Fix (2026-08-26, `library` only, `php -l` clean):** after confirming exactly one tracking number,
|
|
212
|
+
**re-GET the IF's items+units** with their current 318/319 tracking (each `App_Api_Toga2::send` is
|
|
213
|
+
its own committed api2 request, so the re-fetch sees everything just synced), then **fan the one
|
|
214
|
+
tracking number to every item and every serialized unit** — idempotent (skip if already linked) and
|
|
215
|
+
**pruning any stale tracking whose number ≠ the current NetSuite one**. Behavior change: the old
|
|
216
|
+
code deleted **all** unit tracking whenever NetSuite sent 0 or >1 numbers; the new code only prunes
|
|
217
|
+
non-matching tracking **within the single-number case** (single-number is the norm for NetSuite).
|
|
218
|
+
Leftover: the now-unused
|
|
219
|
+
`$lookupExistingItemFulfillmentItemUnitTrackingNumbersByItemFulfillmentItemUnitUuidAndTrackingNumberUuid`
|
|
220
|
+
lookup (~L4423, 4446-4453) is harmless dead code, left in place to avoid a whitespace-fragile edit
|
|
221
|
+
(minor future cleanup). Quad's historical rows were backfilled separately (single-TN IFs only) — see
|
|
222
|
+
the [Quad profile](../../../clients/quad/profile.md) and the
|
|
223
|
+
[tracking-number bridge doc](../../../2.0/apps/_underscore/features/tracking-number-bridges.md).
|
|
224
|
+
Design rationale for putting this at the source writer rather than a 317 interceptor lives on the
|
|
225
|
+
[recursive item fulfillments doc](../../../2.0/apps/_underscore/features/recursive-item-fulfillments.md).
|
|
226
|
+
|
|
193
227
|
### Custom field contract (hardcoded in `common_sync_togasupply.php`)
|
|
194
228
|
|
|
195
229
|
The engine requests these `c_` fields by literal name per route — every synced client must have
|
|
@@ -431,6 +465,20 @@ Parameters are stored **per client DB** but accessed **through the TOGa2 API**,
|
|
|
431
465
|
|
|
432
466
|
## Change history
|
|
433
467
|
|
|
468
|
+
- 2026-08-26 — Corrected the IF full-reconcile tracking claim and **fixed two bugs** in
|
|
469
|
+
`syncItemFulfillmentFromNetsuite`'s single-tracking-number branch: **318 (item) was never written**
|
|
470
|
+
(`Client_Quad` had 0 rows → blank Tracking # column) and **319 (unit) received only the last
|
|
471
|
+
processed item's units** (a per-item lookup was rebuilt inside the item loop but consumed once
|
|
472
|
+
after it — `Client_Quad` IF 1688/SO 287406). It now re-GETs the IF's items+units and **fans the one
|
|
473
|
+
NetSuite tracking number to every item + serialized unit**, idempotent + pruning non-matching
|
|
474
|
+
tracking; the old delete-all-on-0-or->1 behavior is narrowed to prune-non-matching within the
|
|
475
|
+
single-number case. `library`-only deploy. Quad's historical rows backfilled by two
|
|
476
|
+
`dbchanges2/Client_Quad/2026-08-26a/b` migrations (single-TN IFs only; ~120 multi-TN IFs excluded)
|
|
477
|
+
— see the [Quad profile](../../../clients/quad/profile.md) and
|
|
478
|
+
[tracking-number bridges](../../../2.0/apps/_underscore/features/tracking-number-bridges.md).
|
|
479
|
+
Design rationale (source writer vs. a 317 interceptor) on the
|
|
480
|
+
[recursive item fulfillments doc](../../../2.0/apps/_underscore/features/recursive-item-fulfillments.md).
|
|
481
|
+
(jcardinal)
|
|
434
482
|
- 2026-08-18 — Recorded the **next poison-order variant** that re-froze Compass USA's SALES_ORDERS
|
|
435
483
|
section on SO **14106** right after the 2026-08-17 fix let the sync advance past SO 7447. This one
|
|
436
484
|
is 2.0-side: the api2 `PUT /sales-orders` → `postPut` → `renumberLineNumbers()` **single-UPDATE**
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
| [Table-View Hyperlink Columns (meta → ACL → computed URL → render)](features/tableview-hyperlink-columns.md) | Any 2.0 table-view column can render its value as a clickable link instead of plain text. | _underscore/Model/Client/TableView.php, _underscore/Model/Client/TrackingNumber.php, api2/Component/Api/V2/V2.php, toga2-supply/src/api/toga.ts, toga2-supply/src/components/ui/Tables/PrimaryTable/helperFunctions/formatTableData.tsx, toga2-supply/src/components/ui/Tables/PrimaryTable/helperFunctions/convertData.tsx, toga2-supply/src/components/ui/Tables/hooks/useDataTableState.tsx, dbchanges2/Client/2026-07-20 - TrackingNumberHyperlinkAndFieldPermission.sql |
|
|
46
46
|
| [TableView joins (TableViewJoins → SQL) — aliasing, chained multi-hop joins, ACL](features/tableview-joins.md) | `Client_*.TableViewJoins` rows are what let a table view show a column from a table other than its base record. | _underscore/Model/Client/TableView.php, dbchanges2/Client/2026-08-11a - ServiceRequestsInventoryUnitsTableViews.sql, dbchanges2/Client_Elite/2026-08-18 - InventoryUnitsItemColumns.sql, dbchanges2/Client_Nychh/2026-08-18 - InventoryUnitsItemColumns.sql |
|
|
47
47
|
| [TogaIQ Gateway Client (_Component_Api_Togaiq) — AI generate/translate from 2.0](features/togaiq-gateway-client.md) | `_Component_Api_Togaiq` is the 2.0 framework's client for the **TogaIQ** (Talos) AI gateway. | _underscore/Component/Api/Togaiq/Togaiq.php, _underscore/ApiRequest.php |
|
|
48
|
-
| [Tracking-Number Bridge Migration (ASN / Item Fulfillment / Item Receipt)](features/tracking-number-bridges.md) | Shipment tracking numbers used to live as **scalar FK columns** (`trackingNumberId`, `returnTrackingNumberId`) directly on the lowest-level "unit"/"item" tables | api2/Component/Api/V2/V2.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillmentItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Prudential/AdvanceShippingNotice.php, _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Trait/Netsuite/ItemFulfillment.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Core/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Client_Prudential/2026-06-15 - ItemFulfillmentTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Quad/2026-06-18a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Nychh/2026-06-19b - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Growrk/2026-07-13a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Nychh/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql, dbchanges2/Client_Quad/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql, dbchanges2/Client_Elite/2026-08-17 - FulfillmentTableViews.sql |
|
|
48
|
+
| [Tracking-Number Bridge Migration (ASN / Item Fulfillment / Item Receipt)](features/tracking-number-bridges.md) | Shipment tracking numbers used to live as **scalar FK columns** (`trackingNumberId`, `returnTrackingNumberId`) directly on the lowest-level "unit"/"item" tables | api2/Component/Api/V2/V2.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillmentItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Prudential/AdvanceShippingNotice.php, _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Trait/Netsuite/ItemFulfillment.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Core/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Client_Prudential/2026-06-15 - ItemFulfillmentTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Quad/2026-06-18a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Nychh/2026-06-19b - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Growrk/2026-07-13a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Nychh/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql, dbchanges2/Client_Quad/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql, dbchanges2/Client_Elite/2026-08-17 - FulfillmentTableViews.sql, dbchanges2/Client_Quad/2026-08-26a - BackfillQuadUnitLevelTrackingSingleTn.sql, dbchanges2/Client_Quad/2026-08-26b - BackfillQuadItemLevelTrackingSingleTn.sql |
|
|
49
49
|
| [Units for Items for Purchase Orders — Data Structure](features/units-for-items-for-purchase-orders.md) | Describes how unit (serialized inventory) data is linked to sales-order and purchase-order line items behind the `units-for-items-for-purchase-orders` TableView | _underscore/Model/Client/ServiceRequest.php, dbchanges2/Client/2026-08-11a - ServiceRequestsInventoryUnitsTableViews.sql |
|
|
50
50
|
| [USPS DPV Deliverability Verdict (is this address actually insurable/shippable?)](features/usps-dpv-deliverability.md) | **USPS returning HTTP 200 with a populated address is NOT evidence that the address is deliverable.** The authoritative signal is USPS's **DPV (Delivery Point V | _underscore/Component/Library/Carriers/Usps/Usps.php, _underscore/Model/Client/Address.php, _underscore/Model/Rate/Entitlement.php |
|
|
51
51
|
| [Refreshing a Local Dev Database from Beta (dev-sandbox)](workflows/local-db-refresh-from-beta.md) | How to reset a local 2.0 dev database from the **beta / dev-sandbox** environment: dump each schema (`Core`, `Client_<Id>`, `Logs_<Id>`, …) from the beta host, | api2/Config/, _underscore/Loader.php, _underscore/Model/Client/BundleTranslation.php, api2/Component/Api/V2/V2.php, toga25-supply/sync_compasscanada_schema.sql |
|
|
@@ -155,12 +155,31 @@ inheritance. Verified against prod `Client_Compass` chains (≥3 levels deep).
|
|
|
155
155
|
an IF while the item walk is empty/broken would **DELETE the adopted IF's legitimate line items**.
|
|
156
156
|
Requires a CTO design review before implementing adoption semantics. The 2026-07-02 broken-bridge
|
|
157
157
|
guard prevents the duplicate cascade for this failure mode without needing adoption.
|
|
158
|
+
- **Source-side IF tracking population belongs in the NetSuite sync writer, not a 317 interceptor
|
|
159
|
+
(design decision, CTO-reviewed 2026-08-26).** For NetSuite-integrated clients the fix that
|
|
160
|
+
populates item/unit tracking (318/319) from a fulfillment's single header tracking number lives in
|
|
161
|
+
the **source writer** `App_Api_Toga2::syncItemFulfillmentFromNetsuite` (see the
|
|
162
|
+
[per-client sync doc](../../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md)) —
|
|
163
|
+
**not** an `_underscore` payload interceptor on `ItemFulfillments_TrackingNumbers` (317). An
|
|
164
|
+
interceptor fires **per row** as tracking is attached, so it cannot know at insertion time whether
|
|
165
|
+
the shipment is single- or multi-package, and it would **fight this engine**:
|
|
166
|
+
`reconcileUpstreamUnits`/`reconcileUpstreamPackages` own upstream 319 with delete-stale logic. The
|
|
167
|
+
source writer knows NetSuite's one tracking number and the full item/unit set up front, and this
|
|
168
|
+
recursive engine then mirrors it upstream. A 317-interceptor approach was prototyped and
|
|
169
|
+
**abandoned**.
|
|
158
170
|
- **Out of scope:** NetSuite sync of upstream IFs; transfer-order fulfillments
|
|
159
171
|
(`transferOrderId`) are skipped.
|
|
160
172
|
- **Performance:** every child write re-runs a full upstream walk (read-heavy, but each
|
|
161
173
|
upstream record is written at most once — idempotent). Fine for normal fulfillment sizes.
|
|
162
174
|
|
|
163
175
|
## Change history
|
|
176
|
+
- 2026-08-26 — Recorded the **design decision** (CTO-reviewed) that source-side IF tracking
|
|
177
|
+
population for NetSuite clients belongs in `App_Api_Toga2::syncItemFulfillmentFromNetsuite`, not a
|
|
178
|
+
317 (`ItemFulfillments_TrackingNumbers`) payload interceptor: a per-row interceptor cannot tell
|
|
179
|
+
single- vs multi-package at insert time and would fight this engine's upstream 319 delete-stale
|
|
180
|
+
reconcile. Prototyped interceptor abandoned. Source-side fix + Quad backfill live on the
|
|
181
|
+
[per-client sync doc](../../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md).
|
|
182
|
+
(jcardinal)
|
|
164
183
|
- 2026-08-18 — **Bundle scaling now discriminates on distinct downstream items, not SOI lines
|
|
165
184
|
(CTO-approved "Option B").** `reconcileUpstreamLevel`'s Recipe query takes one ordered-qty
|
|
166
185
|
slot per distinct downstream `itemId` and scales only when `distinctDownstreamItemCount > 1`;
|
|
@@ -27,6 +27,8 @@ files:
|
|
|
27
27
|
- dbchanges2/Client_Nychh/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql
|
|
28
28
|
- dbchanges2/Client_Quad/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql
|
|
29
29
|
- dbchanges2/Client_Elite/2026-08-17 - FulfillmentTableViews.sql
|
|
30
|
+
- dbchanges2/Client_Quad/2026-08-26a - BackfillQuadUnitLevelTrackingSingleTn.sql
|
|
31
|
+
- dbchanges2/Client_Quad/2026-08-26b - BackfillQuadItemLevelTrackingSingleTn.sql
|
|
30
32
|
related:
|
|
31
33
|
- recursive-item-fulfillments.md
|
|
32
34
|
- ../../api2/features/cxml-shipnotice-gateway.md
|
|
@@ -110,9 +112,11 @@ returnTrackingNumber: {...} }]`, and an IFIU's as `itemFulfillmentItemUnitTracki
|
|
|
110
112
|
OUTER unit/tracking chain and tracking via the item-level bridge **318** (`dbchanges2/Client_Nychh/2026-06-19a`,
|
|
111
113
|
`dbchanges2/Client_Quad/2026-06-19a`). NYCHH had no custom columns; Quad preserves three
|
|
112
114
|
Units-level customs (`c_hostIdentifier`/CustomRecordFields 1, `c_pkIdentifier`/2, `macAddress`/rf 1432),
|
|
113
|
-
re-attached to the Units join. **Caveat — record 318
|
|
114
|
-
portability gotcha below), so the re-root
|
|
115
|
-
Outbound Tracking # / Carrier columns
|
|
115
|
+
re-attached to the Units join. **Caveat — record 318 was empty in both client DBs when the views
|
|
116
|
+
were rebuilt** (see the portability gotcha below), so the re-root fixed the "0 records" bug but the
|
|
117
|
+
Outbound Tracking # / Carrier columns stayed blank until item-level tracking was backfilled.
|
|
118
|
+
**Quad's 318 is now populated (2026-08-26 writer fix + backfill — see the resolved gotcha below);
|
|
119
|
+
NYCHH's 318 is still empty.**
|
|
116
120
|
- **Prudential (Client_Prudential):** Dell posts the legacy `advanceShippingNoticeUnits` key with flat
|
|
117
121
|
tracking — a PRE/POST interceptor rewrites it (see the prudential client doc).
|
|
118
122
|
- **NetSuite-integrated clients:** `Trait/Netsuite/ItemFulfillment.php` now reads
|
|
@@ -225,20 +229,34 @@ returnTrackingNumber: {...} }]`, and an IFIU's as `itemFulfillmentItemUnitTracki
|
|
|
225
229
|
| CompassCanada | 169 | 138 | 318 |
|
|
226
230
|
| Elite | **0** | 109 | **319** (fixed 2026-08-17) |
|
|
227
231
|
| Prudential | **0** | 380 | **319** |
|
|
228
|
-
| Quad |
|
|
232
|
+
| Quad | 0 → +5,129¹ | 633 → +779¹ | **318** — writer + backfill **fixed 2026-08-26** |
|
|
229
233
|
| NYCHH | **0** | unit-level | **319** |
|
|
230
234
|
|
|
235
|
+
¹ Quad's 2026-08-26 backfill (single-tracking-number IFs only) added **5,129** item-level (318)
|
|
236
|
+
rows (was 0) and **779** unit-level (319) rows; ~120 multi-tracking-number IFs were deliberately
|
|
237
|
+
excluded. `App_Api_Toga2::syncItemFulfillmentFromNetsuite` now populates both bridges going
|
|
238
|
+
forward by mirroring each NetSuite IF's single header (317) number down to every item + serialized
|
|
239
|
+
unit — so for NetSuite-integrated clients 318 and 319 are meant to **mirror** 317, not diverge.
|
|
240
|
+
|
|
231
241
|
Worked example: copying Compass's **318** join into Elite yields 402 rows with **zero** tracking
|
|
232
242
|
numbers; **319** yields 500 rows with 109 populated. `SELECT COUNT(*)` both bridges in the target
|
|
233
243
|
client DB **before** choosing - the wrong choice produces a structurally-correct view with a
|
|
234
244
|
permanently blank Tracking # / Carrier column, which reads as "the data is missing" rather than
|
|
235
245
|
"the join is wrong."
|
|
236
246
|
|
|
237
|
-
- **
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
247
|
+
- **RESOLVED 2026-08-26 (was a live bug): Quad's Tracking # column — fixed by populating 318, not by
|
|
248
|
+
repointing views.** Quad's two fulfillment views read **318**, but Quad had **0** rows in 318 and
|
|
249
|
+
**633** in 319, so the column was blank. The right fix was **not** the interim "repoint to 319"
|
|
250
|
+
idea: Quad's IFs come from **NetSuite** (`syncItemFulfillmentFromNetsuite`), one tracking number
|
|
251
|
+
per IF, and 318/319 are meant to **mirror** the single 317 header number. The source writer was
|
|
252
|
+
fixed to fan that number to every item (318, previously never written) and every serialized unit
|
|
253
|
+
(319, previously only the last item's units), and Quad's historical rows were backfilled for
|
|
254
|
+
single-tracking-number IFs by `Client_Quad/2026-08-26a - BackfillQuadUnitLevelTrackingSingleTn.sql`
|
|
255
|
+
(319, 779 rows) and `Client_Quad/2026-08-26b - BackfillQuadItemLevelTrackingSingleTn.sql` (318,
|
|
256
|
+
5,129 rows); ~120 multi-tracking-number IFs excluded. See the
|
|
257
|
+
[per-client sync doc](../../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md) for
|
|
258
|
+
the writer fix. This supersedes the older "Quad's tracking lives at 317 (~98%)" note. (Elite's bug
|
|
259
|
+
was a different cause — dead ids — and remains a 319 repoint.)
|
|
242
260
|
|
|
243
261
|
- **The dead-id breakage spans TEN clients, not just Elite (measured 2026-08-17).**
|
|
244
262
|
`item-fulfillments-for-sales-orders` / `item-fulfillments-for-sales-order-items` still carry
|
|
@@ -253,6 +271,17 @@ returnTrackingNumber: {...} }]`, and an IFIU's as `itemFulfillmentItemUnitTracki
|
|
|
253
271
|
for record 41.
|
|
254
272
|
|
|
255
273
|
## Change history
|
|
274
|
+
- 2026-08-26 — **Quad's empty-Tracking-# live bug RESOLVED** — by populating **318**, not repointing
|
|
275
|
+
views to 319. Root: Quad's IFs come from NetSuite (one tracking number per IF) and 318/319 are
|
|
276
|
+
meant to **mirror** the single 317 header number; `App_Api_Toga2::syncItemFulfillmentFromNetsuite`
|
|
277
|
+
was fixed to fan that number to every item (318, previously never written) + serialized unit (319,
|
|
278
|
+
previously only the last item's units — see the
|
|
279
|
+
[per-client sync doc](../../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md)),
|
|
280
|
+
and Quad's history was backfilled for single-tracking-number IFs (`Client_Quad/2026-08-26a` 319
|
|
281
|
+
+779 rows, `2026-08-26b` 318 +5,129 rows; ~120 multi-TN IFs excluded). Updated the 318-vs-319
|
|
282
|
+
table and the NYCHH/Quad view caveat (Quad's 318 now populated; NYCHH's still empty). Design
|
|
283
|
+
rationale (source writer vs. 317 interceptor) captured on the recursive-item-fulfillments doc.
|
|
284
|
+
(jcardinal)
|
|
256
285
|
- 2026-08-20 — Recorded the **`childPolicy` asymmetry across the three ASN tracking bridges** (1437
|
|
257
286
|
`MATCH_CREATE`, 1441/1445 `MATCH`) and the resulting per-API `Apis_RecordFields` provisioning
|
|
258
287
|
requirement for any client posting item- or header-level tracking. Compass Canada had zero override
|
|
@@ -13,3 +13,4 @@
|
|
|
13
13
|
| [Talos AI-Assistant Component (launcher + slide-out chat panel)](features/talos-assistant.md) | `Talos` is a **shared, pure-UI** AI-assistant component in `@agilant/toga-blox`: a header launcher button (`TalosLauncher`) plus a slide-out chat panel (`TalosP | toga-blox/src/components/Talos/TalosLauncher.tsx, toga-blox/src/components/Talos/TalosPanel.tsx, toga-blox/src/components/Talos/TalosMessage.tsx, toga-blox/src/components/Talos/types.ts, toga-blox/src/components/Talos/theme.ts, toga-blox/src/components/Talos/helpers.tsx, toga-blox/src/components/Talos/stub.ts, toga-blox/src/components/Talos/Talos.module.css, toga-blox/src/components/Talos/index.ts, toga-blox/src/components/index.ts |
|
|
14
14
|
| [Toaster — host-token styling contract](features/toaster.md) | The blox `Toaster` is a CSS-Module component whose every visual property reads a `--toaster-*` custom property supplied by the **host app**. | toga-blox/src/components/Toaster/Toaster.module.css, toga-blox/src/components/Toaster/Toaster.tsx, toga-blox/src/components/Toaster/ToasterContext.tsx, toga2-commerce/src/styles/index.css, toga2-commerce/src/components/Toasters/ToasterList.tsx |
|
|
15
15
|
| [Dynamic npm Publish Pipeline (branch → channel)](workflows/dynamic-publish-pipeline.md) | How `@agilant/toga-blox` (checkout folder `toga-blox-npm`, registry repo key `toga-blox`) publishes a per-environment npm **channel** (dist-tag) from a `_<mode> | toga-blox/.github/workflows/publish.yml, toga-blox/package.json, toga-blox/src/utils/getFontAwesomeIcon.tsx |
|
|
16
|
+
| [Landing a Large Long-Lived Feature Branch (merge, never rebase)](workflows/landing-a-large-feature-branch.md) | The procedure for landing a long-lived, very large feature branch (months old, hundreds of commits) into `_production` in `toga-blox-npm`. | toga-blox/package.json, toga-blox/.github/workflows/publish.yml |
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Landing a Large Long-Lived Feature Branch (merge, never rebase)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: toga-blox
|
|
5
|
+
project: TOGa Blox
|
|
6
|
+
client: shared
|
|
7
|
+
type: workflow
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-08-26
|
|
10
|
+
owners: [apeterson]
|
|
11
|
+
files:
|
|
12
|
+
- toga-blox/package.json
|
|
13
|
+
- toga-blox/.github/workflows/publish.yml
|
|
14
|
+
related:
|
|
15
|
+
- ./dynamic-publish-pipeline.md
|
|
16
|
+
- ../architecture.md
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## What it is
|
|
20
|
+
|
|
21
|
+
The procedure for landing a long-lived, very large feature branch (months old, hundreds of
|
|
22
|
+
commits) into `_production` in `toga-blox-npm`. The decision recorded here is **merge
|
|
23
|
+
`_production` into the feature branch — do not rebase.** Use this doc before starting any
|
|
24
|
+
big-branch integration; the recon step is the transferable part.
|
|
25
|
+
|
|
26
|
+
## How it works
|
|
27
|
+
|
|
28
|
+
### 1. Measure the divergence first
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
git rev-list --left-right --count origin/_production...<branch>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Concrete case (2026-08-26): `feature-new-table` was **281 commits ahead / 8 behind**
|
|
35
|
+
`origin/_production`, forked ~3 months earlier, 530 files changed (+46,795 / −14,209).
|
|
36
|
+
|
|
37
|
+
### 2. Preview the conflict surface BEFORE merging
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
git merge-tree $(git merge-base origin/_production <branch>) <branch> origin/_production
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This shows the exact conflicting files without touching the working tree, which turns
|
|
44
|
+
"530 changed files" into an actionable list. In the case above it was only **4 files**:
|
|
45
|
+
|
|
46
|
+
| File | Resolution |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `package-lock.json` | **regenerate**, never hand-merge |
|
|
49
|
+
| a component `index.ts` | added independently on both sides — union the exports |
|
|
50
|
+
| a `utils` file | `_production` held two type fixes — keep them |
|
|
51
|
+
| `.github/workflows/publish.yml` | both sides added publish channels — **keep both sets** |
|
|
52
|
+
|
|
53
|
+
### 3. Merge `_production` into the feature branch, then PR
|
|
54
|
+
|
|
55
|
+
1. `git merge origin/_production` **on the feature branch**.
|
|
56
|
+
2. Resolve the (small, known) conflict set **once**.
|
|
57
|
+
3. Open a normal PR: feature → `_production`.
|
|
58
|
+
|
|
59
|
+
### Why not rebase
|
|
60
|
+
|
|
61
|
+
Rebasing 281 commits onto `_production` replays every commit, forces the **same conflicts to
|
|
62
|
+
be re-resolved repeatedly**, and **force-rewrites an already-pushed shared branch** — which
|
|
63
|
+
the git-workflow rules forbid on a branch others may have pulled. Merging resolves the
|
|
64
|
+
conflict set exactly once and preserves the pushed history.
|
|
65
|
+
|
|
66
|
+
## Gotchas
|
|
67
|
+
|
|
68
|
+
- **Confirm the release version before merging.** The `version` in `package.json` drives what
|
|
69
|
+
the publish workflow releases. The feature branch carried `1.0.322` while `_production` was
|
|
70
|
+
at `1.0.314`, so the merge publishes the *branch's* number. See
|
|
71
|
+
[dynamic-publish-pipeline](./dynamic-publish-pipeline.md) for how CI derives the published
|
|
72
|
+
version from that base.
|
|
73
|
+
- **Do not read a behind-count as staleness** in this repo — much of it is release plumbing
|
|
74
|
+
generated on the release branch and never merged back (see the publish-pipeline doc).
|
|
75
|
+
|
|
76
|
+
## Change history
|
|
77
|
+
- 2026-08-26 — Created. Recorded the merge-not-rebase decision for landing `feature-new-table`
|
|
78
|
+
(281 ahead / 8 behind, 530 files) into `_production`, and the
|
|
79
|
+
`rev-list --left-right --count` → `merge-tree` recon pair that narrowed the conflict surface
|
|
80
|
+
to 4 files before any merge was started. (apeterson)
|
package/knowledge/INDEX.md
CHANGED
|
@@ -31,7 +31,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
31
31
|
- **ai-bdr** (AI-BDR) — 13 doc(s) → [2.0/apps/ai-bdr/INDEX.md](2.0/apps/ai-bdr/INDEX.md)
|
|
32
32
|
- **toga2-commerce** (TOGa Commerce) — 19 doc(s) → [2.0/apps/toga2-commerce/INDEX.md](2.0/apps/toga2-commerce/INDEX.md)
|
|
33
33
|
- **toga25-supply** (TOGa 2.5 Supply) — 12 doc(s) → [2.0/apps/toga25-supply/INDEX.md](2.0/apps/toga25-supply/INDEX.md)
|
|
34
|
-
- **toga-blox** (TOGa Blox) —
|
|
34
|
+
- **toga-blox** (TOGa Blox) — 12 doc(s) → [2.0/apps/toga-blox/INDEX.md](2.0/apps/toga-blox/INDEX.md)
|
|
35
35
|
- **bdr** (BDR) — 0 doc(s) → [2.0/apps/bdr/INDEX.md](2.0/apps/bdr/INDEX.md)
|
|
36
36
|
|
|
37
37
|
## standalone framework
|
|
@@ -11,6 +11,7 @@ apps:
|
|
|
11
11
|
- worker2
|
|
12
12
|
- worker
|
|
13
13
|
- dbchanges2
|
|
14
|
+
- library
|
|
14
15
|
project: _Underscore
|
|
15
16
|
client: quad
|
|
16
17
|
type: profile
|
|
@@ -75,14 +76,23 @@ Client-specific DB change-sets live in `dbchanges2/Client_Quad/`.
|
|
|
75
76
|
client role 1, id-agnostic + NOT-EXISTS-guarded, beta only). Quad exposes surfaces to role 1 only,
|
|
76
77
|
vs Compass's 1/3/4 — revisit if broader roles are needed. See
|
|
77
78
|
[Surface Resolver](../../2.0/apps/_underscore/features/surface-resolver.md).
|
|
78
|
-
- **LIVE BUG
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
319
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
- **RESOLVED 2026-08-26 (was a LIVE BUG found 2026-08-17): Quad's Tracking # column populated by
|
|
80
|
+
backfilling 318, not by repointing views.** Quad's fulfillment views correctly read the
|
|
81
|
+
**item-level bridge 318**, but `Client_Quad` had **0** rows in 318 (and **633** in unit-level
|
|
82
|
+
319), so the column was blank. Root context: Quad's item fulfillments come from **NetSuite** via
|
|
83
|
+
the per-client TOGa Supply sync (`App_Api_Toga2::syncItemFulfillmentFromNetsuite`,
|
|
84
|
+
`worker/crons/sync/toga2/sync_togasupply_quad.php`) — **not** TOGa Supply "Fulfill & Ship" — and a
|
|
85
|
+
NetSuite item fulfillment carries **exactly one** tracking number that item (318) and unit (319)
|
|
86
|
+
tracking are meant to **mirror** off the single header (317). Fixed two ways: (1) the source writer
|
|
87
|
+
now fans that one number to every IF item + serialized unit (see the
|
|
88
|
+
[per-client sync doc](../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md)), so
|
|
89
|
+
new IFs populate 318/319 going forward; (2) historical rows backfilled by two idempotent,
|
|
90
|
+
single-tracking-number-only migrations —
|
|
91
|
+
`dbchanges2/Client_Quad/2026-08-26a - BackfillQuadUnitLevelTrackingSingleTn.sql` (319, 779 rows)
|
|
92
|
+
and `dbchanges2/Client_Quad/2026-08-26b - BackfillQuadItemLevelTrackingSingleTn.sql` (318, 5,129
|
|
93
|
+
rows), both run by the dev. **~120 multi-tracking-number IFs were deliberately excluded** (which
|
|
94
|
+
line/unit shipped under which label is not recorded). This supersedes both the earlier note that
|
|
95
|
+
Quad's tracking "lives at 317 (~98%)" and the interim proposal to repoint views to 319. See
|
|
86
96
|
[Tracking-Number Bridge Migration](../../2.0/apps/_underscore/features/tracking-number-bridges.md).
|
|
87
97
|
- Quad is one of only **two** clients (with Compass) whose fulfillment views are free of the
|
|
88
98
|
dangling `joinRecordId` 41 / `parentRecordFieldId` 211+321 config, because both were migrated to
|
package/package.json
CHANGED