toga-ai 1.0.181 → 1.0.183
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.
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
| [Worker (1.0 Framework) Architecture](architecture.md) | `worker` is the legacy (**1.0** `App_` framework) **background-job tier**. | worker/index.php, worker/_/app/framework.php, worker/crons/, worker/schedules/, worker/ebs/cron.worker.php, worker/.ebextensions/035_cron.worker.config |
|
|
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
|
-
| [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/reconcile_netsuite_totals.php, test/@dave/analyze_netsuite_forecast_diff.php, test/@dave/trueup_sales.php, test/@dave/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, worker/crons/toga2/forecast2/common_import_sales_from_netsuite.php |
|
|
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/reconcile_netsuite_totals.php, test/@dave/analyze_netsuite_forecast_diff.php, test/@dave/trueup_sales.php, test/@dave/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 |
|
|
9
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 |
|
|
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,7 +6,7 @@ project: Worker
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-06-
|
|
9
|
+
updated: 2026-06-24
|
|
10
10
|
owners: [dfranks]
|
|
11
11
|
files:
|
|
12
12
|
- test/@dave/reconcile_netsuite_totals.php
|
|
@@ -18,6 +18,8 @@ files:
|
|
|
18
18
|
- test/@dave/probe_missing_oo_timing.php
|
|
19
19
|
- test/@dave/probe_missing_oo_createdby.php
|
|
20
20
|
- test/@dave/probe_drift_so_dates.php
|
|
21
|
+
- test/@dave/probe_profit_invoices.php
|
|
22
|
+
- test/@dave/probe_profit_gap.php
|
|
21
23
|
- worker/crons/toga2/forecast2/common_import_sales_from_netsuite.php
|
|
22
24
|
related:
|
|
23
25
|
- ../architecture.md
|
|
@@ -35,9 +37,14 @@ by reconciling a chosen tranDate range directly against NetSuite.
|
|
|
35
37
|
|
|
36
38
|
## Key files / entry points
|
|
37
39
|
|
|
38
|
-
- `reconcile_netsuite_totals.php [from] [to]` — category grand totals NS vs Forecast2
|
|
39
|
-
Sales Profit, Open Orders, Opportunities) with deltas. Read-only. Connects explicitly to
|
|
40
|
-
**prod core2 reader**; NetSuite via SuiteQL SUMs.
|
|
40
|
+
- `reconcile_netsuite_totals.php [from] [to] [--verbose]` — category grand totals NS vs Forecast2
|
|
41
|
+
(Sales, Sales Profit, Open Orders, Opportunities) with deltas. Read-only. Connects explicitly to
|
|
42
|
+
the **prod core2 reader**; NetSuite via SuiteQL SUMs. `--verbose` additionally prints the
|
|
43
|
+
per-transaction presence diffs (Sales `salesPerTransactionDiff()` + Open Orders
|
|
44
|
+
`openOrderPerOrderDiff()`), each under a large `#`-banner heading with a date column in every
|
|
45
|
+
bucket. The diffs are **gated** because they materialize every transaction/order in the window
|
|
46
|
+
into PHP arrays and OOM on multi-year windows — default is summary-only; positional `[from] [to]`
|
|
47
|
+
work alongside the flag.
|
|
41
48
|
- `analyze_netsuite_forecast_diff.php [from] [to]` — decomposes the delta **per transaction** into
|
|
42
49
|
NS_ONLY (missing from FC), FC_ONLY (stale/extra), DRIFT (value differs). Read-only.
|
|
43
50
|
- `trueup_sales.php --from --to [--chunk-days N] [--prod] [--dry-run]` — makes `Forecast.Sales`
|
|
@@ -49,6 +56,11 @@ by reconciling a chosen tranDate range directly against NetSuite.
|
|
|
49
56
|
~4,000 opps in ~13s to a $0 delta.
|
|
50
57
|
- `probe_sales_gap_direct.php` / `probe_open_orders_gap.php` — read-only NS-vs-FC2 revenue
|
|
51
58
|
breakdowns by type+month using **direct prod mysqli** (demonstrate the sandbox-dev bypass below).
|
|
59
|
+
- `probe_profit_gap.php` — read-only: attributes a Sales **profit** delta **by transaction type**
|
|
60
|
+
and measures the actual contribution of the `tl.iscogs='F'` filter (see the COGS gotcha below).
|
|
61
|
+
- `probe_profit_invoices.php` — read-only per-invoice profit localizer: lists drifted invoices
|
|
62
|
+
(`id` / `tranid` / `tranDate` / NS profit / FC profit / delta) over a tranDate window. Bootstraps
|
|
63
|
+
worker2's `_Component_Api_Netsuite` adapter + a direct prod core2 `Forecast` reader.
|
|
52
64
|
|
|
53
65
|
## How it works
|
|
54
66
|
|
|
@@ -88,6 +100,36 @@ None — Forecast2 is a single shared dataset.
|
|
|
88
100
|
|
|
89
101
|
## Gotchas / known issues
|
|
90
102
|
|
|
103
|
+
- **An audit must apply the sync's own inclusion rules or it manufactures phantom deltas.**
|
|
104
|
+
`reconcile`'s NetSuite Sales SUM/diff originally had **no transaction-status filter**, but the
|
|
105
|
+
sync (`trueup_sales` / `common_import_sales_from_netsuite.php`) deliberately **excludes** Invoice
|
|
106
|
+
*Voided*/*Rejected*, CashSale *"Unapproved Payment"*, and CreditMemo *Voided*. So the audit counted
|
|
107
|
+
rows the sync would never store → a **permanent phantom gap no true-up could ever close** (a single
|
|
108
|
+
Unapproved-Payment cash sale, $23.76, internalId 7184894, drove it). Fix: add a status filter
|
|
109
|
+
matching the sync to **both** Sales SUM queries and the per-transaction diff —
|
|
110
|
+
`BUILTIN.DF(t.status) NOT LIKE '%Unapproved Payment' / '%Voided' / '%Rejected'` (the display value
|
|
111
|
+
ends with the status name). Closed the revenue delta to `$0`. Generalize: when an audit reports a
|
|
112
|
+
delta no trueup closes, first check the audit applies the sync's exact inclusion filters.
|
|
113
|
+
- **Don't blame a profit delta on COGS lines without measuring it.** Adding `tl.iscogs='F'` to the
|
|
114
|
+
audit's profit SUM (to match the sync's line set) changed the profit number by **exactly $0.00** in
|
|
115
|
+
the tested window — COGS postings were **not** the cause of the profit gap. The filter is kept for
|
|
116
|
+
definitional consistency with the sync (which filters `iscogs='F'`), but it was not the fix.
|
|
117
|
+
`probe_profit_gap.php` measures the iscogs contribution directly so the next investigator doesn't
|
|
118
|
+
repeat the wrong hypothesis.
|
|
119
|
+
- **A Sales PROFIT-only gap (revenue matches, profit off) is a LINE-STRUCTURE mismatch, not value
|
|
120
|
+
drift — localize then window.** Production `Forecast.Sales` carries stale lines NetSuite no longer
|
|
121
|
+
returns *plus* is missing some, so the per-invoice profit SUM differs while revenue ties out.
|
|
122
|
+
`trueup_sales` surfaces this as **inserted>0 + deleted>0 with updated=0** (it reconciles by
|
|
123
|
+
`(type, txnId, lineNumber)`; a changed lineNumber is delete+insert, not update). **Key:**
|
|
124
|
+
`trueup_sales` *does* correct profit, but **only within its `--from/--to` tranDate window** — the
|
|
125
|
+
delta persists if the drifted transactions fall outside the window trued up. Diagnostic ladder:
|
|
126
|
+
(a) `reconcile` summary shows a profit delta with revenue at `$0`; (b) `probe_profit_gap.php`
|
|
127
|
+
attributes the delta to a transaction **type** (was 100% invoices); (c) `probe_profit_invoices.php`
|
|
128
|
+
lists the specific drifted invoices with tranDate; (d) run `trueup_sales --from/--to` over **that
|
|
129
|
+
exact window** with `--prod`. Resolved example: 23 invoices dated 2026-05-07/08 carried $1,277.37;
|
|
130
|
+
`trueup_sales --prod` over 2026-05-07..2026-05-08 applied 12 inserts + 35 deletes → `$0`. ⚠
|
|
131
|
+
`--prod` must be passed or trueup writes to the **laptop sandbox `db_forecast2`** (and that repoint
|
|
132
|
+
also drives which `Forecast.Items` lookup loads).
|
|
91
133
|
- **NVL the cost in NS profit SUMs.** `reconcile`/`analyze` compute NS profit as
|
|
92
134
|
`SUM(-foreignamount + NVL(costestimate,0))`. Without `NVL`, ShipItem lines (NULL cost) drop from
|
|
93
135
|
the SUM and NS profit is understated, producing a **fake FC-over-NS "gap"** ($663K across 2025).
|
|
@@ -169,6 +211,13 @@ None — Forecast2 is a single shared dataset.
|
|
|
169
211
|
|
|
170
212
|
## Change history
|
|
171
213
|
|
|
214
|
+
- 2026-06-24 — **Sales audit correctness pass.** Fixed a phantom Sales delta: `reconcile`'s NS Sales
|
|
215
|
+
SUM/diff now applies the sync's status exclusions (Unapproved Payment / Voided / Rejected) so it can't
|
|
216
|
+
count rows the sync never stores (closed revenue delta to $0). Added a Sales per-transaction presence
|
|
217
|
+
diff and gated both diffs behind `--verbose` (they OOM on wide windows). Documented that a profit-only
|
|
218
|
+
gap is a line-structure mismatch fixed by `trueup_sales` **only within its tranDate window**
|
|
219
|
+
(localize-then-window ladder), and that `tl.iscogs='F'` contributed exactly $0.00 — COGS was not the
|
|
220
|
+
cause. Added `probe_profit_invoices.php` + `probe_profit_gap.php`. (dfranks)
|
|
172
221
|
- 2026-06-23 — **Framed open-orders drift as three distinct categories** mapping to
|
|
173
222
|
`trueup_open_orders`'s Insert/Update/Delete buckets — whole-order-missing (dominant by $),
|
|
174
223
|
line-level value drift (largest by count), and stale FC rows (smallest) — correcting the common
|
|
@@ -6,7 +6,7 @@ project: Forwarder
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-06-
|
|
9
|
+
updated: 2026-06-24
|
|
10
10
|
owners: ["jcardinal"]
|
|
11
11
|
files:
|
|
12
12
|
- forward/design/index.php
|
|
@@ -83,9 +83,21 @@ auto-deploy ("live in a few minutes").
|
|
|
83
83
|
regenerates the stub.
|
|
84
84
|
- **Remove = unlist only** — sets a `hidden` flag in `project.json`; files are **never
|
|
85
85
|
deleted** (explicit owner decision).
|
|
86
|
+
- **Edit version metadata** (`apiEditVersion`) — an "Edit" button on each version row opens
|
|
87
|
+
a modal pre-filled with the version's label, author ("your name"), and notes. Saving
|
|
88
|
+
commits an **updated `project.json` only** — the version id and the hosted `vN/index.html`
|
|
89
|
+
are unchanged, and the redirect stub does not depend on this metadata, so **no stub
|
|
90
|
+
rebuild**. Reuses the existing `isValidVersionId` guard and `postField` length caps (notes
|
|
91
|
+
cap 2000).
|
|
92
|
+
- **Copy URL** — a button on each project card copies the project's main live URL
|
|
93
|
+
(`https://demo.togatech.com/<project>`) to the clipboard via `navigator.clipboard`, with a
|
|
94
|
+
brief "Copied ✓" confirmation.
|
|
86
95
|
- **Copy Claude Design prompt** — one-click copy of the standard self-contained-HTML export
|
|
87
96
|
prompt (the same prompt documented in [static-demo-hosting](static-demo-hosting.md)).
|
|
88
97
|
|
|
98
|
+
The full action set is: `list`, `create-project`, `upload`, `adopt`, `set-latest`,
|
|
99
|
+
`toggle-version`, `edit-version`, `toggle-project` (plus `bootstrap`).
|
|
100
|
+
|
|
89
101
|
### Naming & validation
|
|
90
102
|
|
|
91
103
|
- Folder names auto-normalized to **lowercase kebab-case**, validated against a kebab regex
|
|
@@ -141,6 +153,11 @@ None — internal/shared design-team tool.
|
|
|
141
153
|
`/vN` versioning with a `project.json` manifest + auto-generated latest-pointer stub,
|
|
142
154
|
adopt/unlist actions, `/design` route. Fixed the >1 MB Contents-API empty-content bug
|
|
143
155
|
(raw media type) and the tracked-token leak (env/`.config.php`). (jcardinal)
|
|
156
|
+
- 2026-06-24 — Added **edit-version** (`apiEditVersion`): an Edit button + modal to revise a
|
|
157
|
+
version's label/author/notes, committing `project.json` only (no stub rebuild; reuses
|
|
158
|
+
`isValidVersionId` + length caps). Added a **Copy URL** button on each project card
|
|
159
|
+
(`navigator.clipboard` → `https://demo.togatech.com/<project>`). Both additive; no new
|
|
160
|
+
security surface. (jcardinal)
|
|
144
161
|
|
|
145
162
|
## Related docs
|
|
146
163
|
|
package/package.json
CHANGED