toga-ai 1.0.604 → 1.0.605
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: Worker
|
|
|
6
6
|
client: nycdoe
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-08-
|
|
9
|
+
updated: 2026-08-18
|
|
10
10
|
owners: [mhammontree, sking]
|
|
11
11
|
files:
|
|
12
12
|
- worker/crons/sync/nycdoe/import_asn.php
|
|
@@ -326,7 +326,7 @@ Vendor SFTP ───(legacy_import_asn.php, ser+non-ser)─┘ [UNIQUE ded
|
|
|
326
326
|
counts SO+customerPO pairs rather than distinct SOs.
|
|
327
327
|
|
|
328
328
|
- **⚠ NAMED PATTERN — "Pre-ASN Manual Receipt Mismatch"** (the umbrella condition covering
|
|
329
|
-
this doc's two SO/PO-stamp gotchas below plus a third confirmed instance). Search this
|
|
329
|
+
this doc's two SO/PO-stamp gotchas below plus a third and fourth confirmed instance). Search this
|
|
330
330
|
title, or its informal name **"Shipment Received Notice"** (Mark's nickname — some vendors,
|
|
331
331
|
chiefly Lenovo, effectively send the ASN *after* the goods already arrived).
|
|
332
332
|
- **Common shape:** a manufacturer's physical shipment reaches the warehouse before (or
|
|
@@ -343,6 +343,66 @@ Vendor SFTP ───(legacy_import_asn.php, ser+non-ser)─┘ [UNIQUE ded
|
|
|
343
343
|
`listItemReceiptsCreateFromPurchaseOrder($actualReceiptPO)`) and both are fixed the same
|
|
344
344
|
way (a `dbchanges` data repair repointing the ASN item row's SO/PO ids to wherever the
|
|
345
345
|
receipt actually lives, then letting the `*/5` Stage 5 cron ticket it — no code change).
|
|
346
|
+
- **⚠ FIRST TRIAGE STEP — "is the receipt-bearing PO a `Created From` CHILD of a sales order
|
|
347
|
+
we can stamp?"** (added 2026-08-18). This one question picks the remedy, and the two
|
|
348
|
+
remedies are **not interchangeable**, because Stage 5 resolves receipts **SO-wide only**
|
|
349
|
+
(`listPurchaseOrdersCreatedFromSalesOrder` → receipts per child PO):
|
|
350
|
+
- **PO IS a child of the SO** → a plain data repoint of *both* id columns
|
|
351
|
+
(`netSuiteInternalSalesOrderId` + `netSuiteInternalPurchaseOrderId`) works, and the `*/5`
|
|
352
|
+
Stage 5 cron tickets it itself. (Instances 3 and 4.)
|
|
353
|
+
- **PO is NOT a child** — a manually created PO or a cross-wired stamp, e.g. ASN `26215` —
|
|
354
|
+
→ the SO-wide fan-out can **never** reach it, so a repoint is a **silent no-op** and
|
|
355
|
+
recovery needs the one-off **union-receipt backfill** instead.
|
|
356
|
+
Answer it in one look via NetSuite's **"Related Records"** tab on the SO (it lists the child
|
|
357
|
+
POs and their link type, e.g. `Special Order`), confirmed by the PO's own **"Created From"**
|
|
358
|
+
field. Getting this wrong costs a full apply-and-wait cron cycle before you learn the
|
|
359
|
+
repoint did nothing.
|
|
360
|
+
- **Quick discriminators that rule out neighbouring DOE failure classes** (use these before
|
|
361
|
+
committing to this pattern):
|
|
362
|
+
- A unit with `trackingNumberId` **NOT NULL** was created by the **importer**, not added by
|
|
363
|
+
Stage 5 from NetSuite — i.e. a genuine ASN unit (the inverse of the dedupeKey-drift
|
|
364
|
+
fingerprint further below).
|
|
365
|
+
- A well-formed `serialNumber` + populated `assetTag` + a clean OEM SKU in `partNumber`
|
|
366
|
+
rules **out** the open "Lenovo Off-Layout ASN File" parse bug (whose fingerprint is
|
|
367
|
+
`serialNumber = '1'`, the real serial in `assetTag`, and a product *description* in
|
|
368
|
+
`partNumber`).
|
|
369
|
+
- **NetSuite internal ids are creation-ordered**, so a receipt id can never predate its own
|
|
370
|
+
PO id — that ordering alone can disprove a proposed receipt↔PO pairing.
|
|
371
|
+
- **Confirmed instance 4 — NEW STRUCTURAL VARIANT: duplicate SO cut for a POST-FREEZE GROWTH
|
|
372
|
+
row while the ORIGINAL SO already carried that line** (2026-08-18, ASN `26644`, customer PO
|
|
373
|
+
`WR260175404-RPL`, Lenovo, `ldaCode` `M366M263`). Item `54552` (`DOE-62C5GAR1US`, unit
|
|
374
|
+
`604254`, serial `VKVY4802`, asset `DOE-LN1271004`) sat `installTicketStatus=pending` with
|
|
375
|
+
`togadeskRepairOrderId` NULL since 2026-07-02 — the silent-stranding dead end, no error, no
|
|
376
|
+
alert.
|
|
377
|
+
- Warehouse **force-received** the shipment because Lenovo's ASN had not arrived yet.
|
|
378
|
+
- SO `281110` (internal `7219711`) carried **all three** ASN lines including
|
|
379
|
+
`DOE-62C5GAR1US`, with two child POs, both link type **Special Order**: `167882`
|
|
380
|
+
(internal `7219712`, 7/1/2026) and `167917` (internal `7223073`, 7/2/2026). Goods were
|
|
381
|
+
receipted on PO `167917` / internal `7223073`, **item receipt internal `7223075`**.
|
|
382
|
+
- When the ASN growth row for the touch monitor landed (post-freeze growth correctly
|
|
383
|
+
becoming a fresh item row per business rule 4), the automation cut a **second** SO —
|
|
384
|
+
internal `7245587` / PO `7245588` — and Stage 3 stamped item `54552` with it. That
|
|
385
|
+
duplicate chain was never received and **never can be**: serial `VKVY4802` was already
|
|
386
|
+
consumed by receipt `7223075`. Id ordering confirms it: `7223073 < 7223075 < 7245587`.
|
|
387
|
+
- **Fix (data-only, worked 2026-08-18):** repointed `netSuiteInternalSalesOrderId`
|
|
388
|
+
`7245587 → 7219711` and `netSuiteInternalPurchaseOrderId` `7245588 → 7223073`; the `*/5`
|
|
389
|
+
Stage 5 cron then created the repair order itself. Because the correct chain's PO **is** a
|
|
390
|
+
legitimate `Created From` child of the SO, the plain repoint was the right remedy.
|
|
391
|
+
- **How it differs from its neighbours:** instance 3 (ASN `23522`) was a same-ASN **sibling
|
|
392
|
+
PO**; ASN `26215` had a **manually created** PO that was *not* a child of the stamped SO.
|
|
393
|
+
Here the duplicate arose from the **post-freeze growth rule itself** on an SO that already
|
|
394
|
+
held the line — no manual NetSuite edit involved.
|
|
395
|
+
- **⚠ OUTSTANDING (not done):** the orphaned duplicate chain SO internal `7245587` / PO
|
|
396
|
+
internal `7245588` is unreceived and unused and **should be cancelled in NetSuite**, same
|
|
397
|
+
as the duplicate chain on ASN `26215`. Not blocking the install, which is TOGa Desk-side
|
|
398
|
+
only.
|
|
399
|
+
- **Delivering the repair by hand vs. by `dbchanges`.** Instance 4 was run as a **manual
|
|
400
|
+
one-row `UPDATE` directly against legacy `Core`** — deliberately *not* shipped as a
|
|
401
|
+
`dbchanges` file, diverging from the ASN `26280` / `23522` precedents. Consequence worth
|
|
402
|
+
knowing: when run manually the **derived-table preflight guard is unnecessary** — that
|
|
403
|
+
pattern exists only to work around the `dbchanges` runner's inability to express procedural
|
|
404
|
+
guards. Pinning the before-state values in the `WHERE` clause still gives the
|
|
405
|
+
no-op / no-double-apply safety either way.
|
|
346
406
|
- **Confirmed instance 3 (2026-08-06/07, ASN `23522`, customer PO `S202637409`).** Item
|
|
347
407
|
`51104` (`DOE-63D8MAR3US`, serial `VTV11634`, asset `DOE-LN1262287`) arrived from Lenovo
|
|
348
408
|
and the warehouse receipted *a* unit of that part against sibling PO **#157026** (internal
|
|
@@ -587,6 +647,22 @@ the client's `apps:` scope solely so this monitor loads, and its presence is **n
|
|
|
587
647
|
of the consumer query; `php -l` every touched file.
|
|
588
648
|
|
|
589
649
|
## Change history
|
|
650
|
+
- 2026-08-18 — Repaired stranded ASN `26644` / customer PO `WR260175404-RPL` (**data-only, no code
|
|
651
|
+
in `worker` or `dbchanges`**): item `54552` (`DOE-62C5GAR1US`, unit `604254`, serial `VKVY4802`)
|
|
652
|
+
had been `pending` with a NULL `togadeskRepairOrderId` since 2026-07-02. Repointed
|
|
653
|
+
`netSuiteInternalSalesOrderId` `7245587 → 7219711` and `netSuiteInternalPurchaseOrderId`
|
|
654
|
+
`7245588 → 7223073` and let the `*/5` Stage 5 cron ticket it (confirmed working). Logged this as
|
|
655
|
+
the **fourth** confirmed instance of "Pre-ASN Manual Receipt Mismatch" and a **new structural
|
|
656
|
+
variant**: the duplicate SO was cut for a **post-freeze growth row** while the original SO already
|
|
657
|
+
carried that line (no manual NetSuite edit) — distinct from instance 3's same-ASN sibling PO and
|
|
658
|
+
from ASN `26215`'s non-child manual PO. Added the pattern's **first triage step** ("is the
|
|
659
|
+
receipt-bearing PO a `Created From` child of a stampable SO?" — child ⇒ repoint works, non-child ⇒
|
|
660
|
+
repoint is a silent no-op and the union-receipt backfill is required), the quick discriminators
|
|
661
|
+
that rule out the off-layout parse bug and importer-vs-Stage-5 units, the id-ordering proof, and
|
|
662
|
+
the note that a **manual** SQL run needs no derived-table preflight guard (unlike a `dbchanges`
|
|
663
|
+
file). **Outstanding:** duplicate chain SO `7245587` / PO `7245588` still needs cancelling in
|
|
664
|
+
NetSuite. The durable detection/alerting fix for this stranding class remains **unbuilt**.
|
|
665
|
+
(mhammontree)
|
|
590
666
|
- 2026-08-17 — TRUE-80587: added `Monitor/Nycdoe/ServiceNowEndpointHealth` (worker2 → OneUptime), an
|
|
591
667
|
unauthenticated-GET liveness probe complementing the log-scraping 1.0 `App_SystemMonitor_ServiceNow*`
|
|
592
668
|
monitors, which cannot see a dead endpoint. Token validity is a deliberately accepted coverage gap
|
package/package.json
CHANGED