toga-ai 1.0.300 → 1.0.301
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,6 +6,6 @@
|
|
|
6
6
|
| [Compass MA Sales Order Exception Report](features/compass-ma-sales-order-exception-report.md) | A worker cron that emails operations the "Compass Refresh Exception Report" — Compass `MA%` sales orders whose corresponding Office Depot (ODP) sales order has | worker/crons/toga2/compass/workflow/7_generate_ma_sales_order_exception_report.php |
|
|
7
7
|
| [Compass Partial In-Transit & Delivered Emails (per package)](features/compass-partial-in-transit-delivered-emails.md) | Compass USA and Compass Canada send a **per-package** in-transit email (and a matching delivered email) instead of one email listing the whole order. | worker/crons/toga2/compass/update_salesorder_status_from_odp.php, worker/crons/toga2/compasscanada/workflow/3_update_salesorder_status_from_grand_and_toy.php |
|
|
8
8
|
| [Forecast2 ↔ NetSuite Reconciliation & Trueup Tooling](features/forecast2-netsuite-reconciliation.md) | CLI tools to **audit** and **repair** drift between the production `Forecast` DB (core2) and NetSuite. | test/@dave/checker.php, _underscore/Component/Forecast/SaleImport/SaleImport.php, test/@dave/looper.php, test/@dave/reconcile_netsuite_totals.php, test/@dave/fixer.php, test/@dave/analyze_netsuite_forecast_diff.php, test/@dave/trueup_sales.php, test/@dave/trueup_open_orders.php, test/@dave/loop_trueup_open_orders.php, test/@dave/trueup_opportunities.php, test/@dave/probe_sales_gap_direct.php, test/@dave/probe_missing_oo_timing.php, test/@dave/probe_missing_oo_createdby.php, test/@dave/probe_drift_so_dates.php, test/@dave/probe_profit_invoices.php, test/@dave/probe_profit_gap.php, worker/crons/toga2/forecast2/common_import_sales_from_netsuite.php, worker/crons/toga2/forecast2/periodic_forecast_discrepancy_fix_open_orders.php, worker/crons/toga2/forecast2/import_open_orders.php, worker/schedules/cron.worker.infrastructure.json |
|
|
9
|
-
| [NetSuite → TOGa Supply Per-Client Sync (thin wrappers)](features/netsuite-togasupply-per-client-sync.md) | Syncs NetSuite transactions (sales orders, purchase orders, invoices, item receipts, item fulfillments, inventory adjustments) into each TOGa Supply (2.0) clien | worker/crons/toga2/netsuite/common_sync_togasupply.php, worker/crons/toga2/netsuite/sync_togasupply_canon.php, worker/schedules/cron.worker.sync.json, dbchanges2/_modules/netsuite/2026-04-01 - Parameters.sql |
|
|
9
|
+
| [NetSuite → TOGa Supply Per-Client Sync (thin wrappers)](features/netsuite-togasupply-per-client-sync.md) | Syncs NetSuite transactions (sales orders, purchase orders, invoices, item receipts, item fulfillments, inventory adjustments) into each TOGa Supply (2.0) clien | worker/crons/toga2/netsuite/common_sync_togasupply.php, worker/crons/toga2/netsuite/sync_togasupply_canon.php, worker/schedules/cron.worker.sync.json, dbchanges2/_modules/netsuite/2026-04-01 - Parameters.sql, library/app/api/netsuite/rest.php, library/app/systemmonitor/netsuiteintegration.php |
|
|
10
10
|
| [Prudential: Send Shipments for the Day report (daily cron)](features/send-shipments-for-the-day.md) | Daily cron (9:00 PM) that emails Prudential and Dell stakeholders an Excel report of all devices shipped that day, including tracking number, serial number, emp | worker/crons/notifications/reports/send_shipments_for_the_day.php |
|
|
11
11
|
| [Onboarding a Client to the NetSuite TOGa Supply Sync](workflows/onboarding-client-to-netsuite-togasupply-sync.md) | How to add a new TOGa 2 client to the per-client NetSuite → TOGa Supply importer (`worker/crons/toga2/netsuite/`). | worker/crons/toga2/netsuite/sync_togasupply.php, worker/crons/toga2/netsuite/common_sync_togasupply.php, worker/schedules/cron.worker.sync.json, dbchanges2/_modules/netsuite/2026-04-01 - Parameters.sql |
|
|
@@ -6,13 +6,15 @@ project: Worker
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-
|
|
9
|
+
updated: 2026-07-09
|
|
10
10
|
owners: ["dfranks", "bala"]
|
|
11
11
|
files:
|
|
12
12
|
- worker/crons/toga2/netsuite/common_sync_togasupply.php
|
|
13
13
|
- worker/crons/toga2/netsuite/sync_togasupply_canon.php
|
|
14
14
|
- worker/schedules/cron.worker.sync.json
|
|
15
15
|
- dbchanges2/_modules/netsuite/2026-04-01 - Parameters.sql
|
|
16
|
+
- library/app/api/netsuite/rest.php
|
|
17
|
+
- library/app/systemmonitor/netsuiteintegration.php
|
|
16
18
|
related:
|
|
17
19
|
- ../architecture.md
|
|
18
20
|
- forecast2-netsuite-reconciliation.md
|
|
@@ -128,9 +130,34 @@ Parameters are stored **per client DB** but accessed **through the TOGa2 API**,
|
|
|
128
130
|
older** integration (`syncWithToga`/`syncWithTogadesk`) with its own legacy parameter keys
|
|
129
131
|
(`NETSUITE_LAST_*_INTEGRATION_DATETIME`) — NOT the supply sync. The supply wrapper for AIG
|
|
130
132
|
lives in the `netsuite/` folder. Both key sets coexist harmlessly.
|
|
131
|
-
- **Invoices lag ~24h by design
|
|
132
|
-
(invoices may still be attaching), so `LAST_SYNC_DATETIME_INVOICES`
|
|
133
|
-
by a day. Not a fault.
|
|
133
|
+
- **Invoices lag ~24h by design + are keyed on `lastmodifieddate`:** the invoice section caps its
|
|
134
|
+
upper bound at `now − 86400s` (invoices may still be attaching), so `LAST_SYNC_DATETIME_INVOICES`
|
|
135
|
+
always trails the others by a day. Not a fault. Invoices are also pulled by
|
|
136
|
+
**`lastmodifieddate`, NOT `trandate`** — `App_Api_Netsuite_Rest::listSales()` defaults
|
|
137
|
+
`$dateField='lastmodifieddate'` and the engine calls it without the 4th arg. So a backdated
|
|
138
|
+
`trandate` is irrelevant to whether an invoice imports, and a just-modified invoice still won't
|
|
139
|
+
import until it is >24h old (the upper-bound cap).
|
|
140
|
+
- **A parse error in the shared `library/app/api/netsuite/rest.php` takes down EVERY client at
|
|
141
|
+
once (tier-wide outage).** All wrappers autoload `App_Api_Netsuite_Rest` in the pre-section
|
|
142
|
+
LOOKUPS/setup phase of `common_sync_togasupply.php` (~line 433). Because PHP parses the whole
|
|
143
|
+
file before executing, any fatal parse error in `rest.php` prevents the class from loading and
|
|
144
|
+
crashes **all** clients' sync at the same instant — before any record section runs.
|
|
145
|
+
**Localizing the crash from `Parameters`:** `NETSUITE_EXECUTION_MODE_*` is `<seconds>-IDLE` vs
|
|
146
|
+
`<seconds>-RUNNING`; `startModeIteration()` writes RUNNING at the *start* of a section. If a
|
|
147
|
+
frozen client's mode is stuck **IDLE** (not RUNNING), the script is dying **before** any section
|
|
148
|
+
— i.e. in the LOOKUPS/setup phase (autoload/parse error, or a lookup 403/exception). Stuck
|
|
149
|
+
**RUNNING** means it crashed *inside* that section. And because `SALES_ORDERS` advances its
|
|
150
|
+
watermark to ~now on every completed run (no 24h cap), a SALES_ORDERS watermark frozen for days
|
|
151
|
+
means no run has *completed*, even if the cron is firing. To confirm tier-wide vs per-client:
|
|
152
|
+
compare several clients' watermarks — **all frozen at the same timestamp = shared/upstream cause**
|
|
153
|
+
(e.g. this parse error), not per-client data. When the fix deploys, MODE flips to RUNNING and the
|
|
154
|
+
watermark jumps to ~now on completion (a positive live signal); the sync self-recovers and
|
|
155
|
+
backfills the gap.
|
|
156
|
+
- **Monitoring blind spot — not every client is in the NetSuite sync monitor.**
|
|
157
|
+
`App_SystemMonitor_NetSuiteIntegration` (`library/app/systemmonitor/netsuiteintegration.php`)
|
|
158
|
+
alerts ClickUp when any client's checkpoint is >48h stale, but its `CLIENT_CONFIGURATIONS` list
|
|
159
|
+
(~line 16) **omits Quad, AIG, and Growrk**. Their stalls raise no alert (Quad's 3-day July-2026
|
|
160
|
+
outage went unflagged for that reason). Follow-up: add Quad/AIG/Growrk to `CLIENT_CONFIGURATIONS`.
|
|
134
161
|
- **Seeded-but-stale = stalled sync.** Verify health by reading `LAST_SYNC_DATETIME_*` in each
|
|
135
162
|
`Client_<Id>.Parameters`: a healthy client advances to ~now every 5 min. As of 2026-06-17,
|
|
136
163
|
Quad was seeded but frozen at 2025-04/05 (not advancing) while the other 12 deployed clients
|
|
@@ -151,6 +178,19 @@ Parameters are stored **per client DB** but accessed **through the TOGa2 API**,
|
|
|
151
178
|
|
|
152
179
|
## Change history
|
|
153
180
|
|
|
181
|
+
- 2026-07-09 — **Tier-wide outage (2026-07-06 → 07-09): a dropped brace in shared `rest.php`
|
|
182
|
+
killed every client's sync for 3 days.** A bad merge (`c3caa11a`, "Merge branch '_production'
|
|
183
|
+
into TRUE-79078", 2026-06-24) silently dropped two tokens at the `listLocations()` /
|
|
184
|
+
`listPurchaseOrders()` boundary in `library/app/api/netsuite/rest.php` (~line 1119) during
|
|
185
|
+
conflict resolution — the closing `}` of `listLocations()` and the `/**` opening the
|
|
186
|
+
`listPurchaseOrders()` docblock — leaving `return $out;` immediately followed by a bare
|
|
187
|
+
` * Returns purchase orders...`, a fatal `syntax error, unexpected '*'`. `App_Api_Netsuite_Rest`
|
|
188
|
+
then failed to load entirely, so every client's autoload in the LOOKUPS phase crashed. Shipped to
|
|
189
|
+
prod via automated merge `c85e39e5` at 2026-07-06 16:17 UTC — the exact minute all clients' last
|
|
190
|
+
successful sync ran. Fix: restored the missing `}` and `/**`; verified `php -l` clean. Sync
|
|
191
|
+
self-recovered and backfilled the July 6–9 gap (Quad invoice 313319 / order 281251 / $2,356.22
|
|
192
|
+
imported, all watermarks current). See the new tier-wide-parse-error and monitor-blind-spot
|
|
193
|
+
gotchas above. (bala)
|
|
154
194
|
- 2026-06-30 — The IF section's `syncItemFulfillmentFromNetsuite` (`library/app/api/toga2.php`) now
|
|
155
195
|
imports **all** fulfillment statuses (`['_picked','_packed','_shipped']`, not just shipped),
|
|
156
196
|
stamping/advancing the IF stage from `c_netsuiteInternalItemFulfillmentStatus`. Full mechanics
|
package/package.json
CHANGED