toga-ai 1.0.108 → 1.0.109
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.
|
@@ -40,10 +40,13 @@ second, independently-gated concern in the same handler.
|
|
|
40
40
|
`test/@dave/NetSuite/api-message-queue/` — upload all four `.js` to one File Cabinet folder):
|
|
41
41
|
- `lib_amq_queue.js` — shared module: record-type/field ids, `transmit()`, `findSendableIds()`.
|
|
42
42
|
- `ue_api_msg_queue_enqueue.js` — User Event on the synced source records (Opportunity, …):
|
|
43
|
-
writes one queue row per create/edit/delete
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
writes one queue row per create/edit/delete, then **kicks the scheduled drainer via `N/task`**
|
|
44
|
+
(async, non-blocking). The immediate trigger lives here — see gotchas for why.
|
|
45
|
+
- `ss_amq_drain.js` — Scheduled Script: drains rows (the on-demand kick *and* a cron safety-net).
|
|
46
|
+
Needs **two deployments**: one `Scheduled` (cron) + one `Not Scheduled` (the on-demand slot
|
|
47
|
+
`task.create` submits into).
|
|
48
|
+
- `ue_amq_drain.js` — **RETIRED.** A UE on the queue record can't fire on enqueuer-created rows
|
|
49
|
+
(UE-can't-trigger-UE); undeploy it.
|
|
47
50
|
- The custom record itself: **"API Message Queue"**, internal id **1185**.
|
|
48
51
|
|
|
49
52
|
**worker2 side:**
|
|
@@ -59,12 +62,12 @@ second, independently-gated concern in the same handler.
|
|
|
59
62
|
(`{recordType, internalId, eventType, action}`), `headers`. It maps `record.Type`
|
|
60
63
|
(lowercase) → the camelCase `recordType` worker2 expects (explicit map; e.g.
|
|
61
64
|
`salesorder`→`salesOrder`), and `context.type` → CRUD verb (`create`→POST, `edit`/`xedit`→PUT,
|
|
62
|
-
`delete`→DELETE).
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
endpoint, then **deletes on 2xx** /
|
|
67
|
-
(terminal — never auto-deleted; Jeff's data-loss rule).
|
|
65
|
+
`delete`→DELETE). It then **kicks the drainer**:
|
|
66
|
+
`task.create({taskType:SCHEDULED_SCRIPT, scriptId:'customscript_ss_amq_drain'})` — scriptId only,
|
|
67
|
+
no deployment id. If no on-demand slot is free the kick is skipped and the cron backs it up.
|
|
68
|
+
2. **Drain (NetSuite):** `ss_amq_drain` runs (from the kick or its cron). `transmit()` claims a row
|
|
69
|
+
(`Created`→`Sending`) before the HTTP call, POSTs to the row's endpoint, then **deletes on 2xx** /
|
|
70
|
+
sets `Retry` (+exponential backoff) / `Failed` (terminal — never auto-deleted; Jeff's data-loss rule).
|
|
68
71
|
3. **Ingest (prod):** `webhook.togahub.com/netsuite` → WebhookIngestion **Python Lambda** →
|
|
69
72
|
INSERT `Core.WorkerJobs` + SQS → returns 200 immediately. Fully async; outcome lives in
|
|
70
73
|
`WorkerJobs.isSuccess`/`failureReason`.
|
|
@@ -97,6 +100,16 @@ None — platform-wide Forecast sync.
|
|
|
97
100
|
|
|
98
101
|
## Gotchas / known issues
|
|
99
102
|
|
|
103
|
+
- **A User Event can't trigger another User Event → the immediate trigger lives in the enqueuer.**
|
|
104
|
+
The enqueuer (a UE) creating the queue row does NOT fire any UE on the queue record (only the
|
|
105
|
+
*scheduled* drainer's `submitFields` does). So a drain-UE on the queue record never runs for
|
|
106
|
+
enqueued rows — the enqueuer kicks the drainer itself via `task.create`. (`ue_amq_drain.js` is
|
|
107
|
+
retired for exactly this reason. Evidence: its log only ever showed `xedit`/`Sending`, never `create`.)
|
|
108
|
+
- **`task.create(SCHEDULED_SCRIPT)` needs a `Not Scheduled` deployment.** A `Scheduled` deployment is
|
|
109
|
+
reserved for its recurrence → `NO_DEPLOYMENTS_AVAILABLE`; a `Testing` deployment can't be submitted
|
|
110
|
+
at all. Give `ss_amq_drain` a dedicated `Not Scheduled` deployment as the on-demand slot (add more
|
|
111
|
+
for concurrency) and keep a `Scheduled` one for the cron. Submit by **scriptId only** — the
|
|
112
|
+
deployment id is prefix-doubled (`customdeploycustomdeploy_ss_amq_drain`).
|
|
100
113
|
- **worker2 routes EVERY request to `_Controller_Index::worker()`** — `worker2/_.php` sets
|
|
101
114
|
`DEFAULT_CONTROLLER_METHOD = ['_Controller_Index','worker']`, which short-circuits `_Route`'s
|
|
102
115
|
URI matching. There is no per-URL routing, and `.htaccess` denies direct `.php` files, so you
|
|
@@ -124,13 +137,16 @@ None — platform-wide Forecast sync.
|
|
|
124
137
|
string throws `Object of class stdClass could not be converted to string`. Normalize before
|
|
125
138
|
matching.
|
|
126
139
|
- **Drain dedup** uses a `Sending` claim status: `transmit()` flips `Created`→`Sending` before the
|
|
127
|
-
HTTP call so a concurrent pass skips it
|
|
128
|
-
|
|
129
|
-
`
|
|
130
|
-
every sendable status (`Created`,`Pending`,`Retry`,`Sending`) — omitting `Created` silently
|
|
131
|
-
matches nothing (`candidates:0`).
|
|
140
|
+
HTTP call so a concurrent drainer pass skips it (`Sending` ∉ sendable), narrowing the double-send
|
|
141
|
+
window to the load→claim gap. `findSendableIds` must list every sendable status
|
|
142
|
+
(`Created`,`Pending`,`Retry`,`Sending`) — omitting `Created` silently matches nothing (`candidates:0`).
|
|
132
143
|
|
|
133
144
|
## Change history
|
|
145
|
+
- 2026-06-16 — Trigger correction: the immediate trigger moved INTO the enqueuer (`task.create`
|
|
146
|
+
the drainer) after discovering a UE can't trigger a UE — `ue_amq_drain` retired. `task.create`
|
|
147
|
+
needs a `Not Scheduled` deployment of `ss_amq_drain` (else `NO_DEPLOYMENTS_AVAILABLE`); submit by
|
|
148
|
+
scriptId only (deployment id is prefix-doubled). Fixed an `itemType`-as-object crash in the
|
|
149
|
+
importer. POST/DELETE coded but only PUT (edit) verified live. (dfranks)
|
|
134
150
|
- 2026-06-16 — Built the queue enqueuer/drainer SuiteScripts, the worker2 `/netsuite` router, and
|
|
135
151
|
the `_Worker_Netsuite_Opportunity` Forecast importer (header + items + status), with ClickUp
|
|
136
152
|
parity. Verified opportunity 5483750 imports end-to-end in dev via ngrok. (dfranks)
|
package/package.json
CHANGED