toga-ai 1.0.851 → 1.0.853
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/INDEX.md +1 -0
- package/knowledge/1.0/apps/worker/features/walmart-daily-sales-report.md +76 -0
- package/knowledge/2.0/apps/_underscore/features/core-domains-app-host-registry.md +22 -5
- package/knowledge/2.0/apps/dbchanges2/features/surface-layer-schema.md +11 -1
- package/knowledge/2.0/apps/toga-blox/features/table.md +3 -1
- package/knowledge/2.0/apps/toga-blox/workflows/dynamic-publish-pipeline.md +3 -1
- package/knowledge/2.0/apps/toga-blox/workflows/local-link-into-a-consumer-app.md +2 -2
- package/knowledge/2.0/apps/toga25-supply/features/record-modals-and-nested-tables.md +29 -1
- package/knowledge/INDEX.md +1 -1
- package/knowledge/clients/elite/profile.md +24 -4
- package/knowledge/clients/walmart/profile.md +2 -1
- package/package.json +1 -1
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
| [OneUptime external uptime monitoring for 1.0 workers](features/oneuptime-worker-uptime-monitoring.md) | Per-minute external OneUptime "Incoming Request" heartbeat from every 1.0 worker box (Degraded 3 min / Offline 5 min); open for the heartbeat push, monitor prov |
|
|
17
17
|
| [Prudential: Send Shipments for the Day report (daily cron)](features/send-shipments-for-the-day.md) | Daily 9:00 PM Prudential/Dell cron emailing an Excel of every device shipped today (tracking, serial, XID, FedEx status, vendor); open for the ASN join chain an |
|
|
18
18
|
| [Staples cXML Order Import (SFTP → NetSuite)](features/staples-cxml-order-import.md) | Hourly cron importing Staples cXML POs from SFTP into NetSuite Sales Orders (writes 855 ack back); open for the per-file flow, saved-search-8412 Location resolu |
|
|
19
|
+
| [Walmart Daily Sales Report (send_toga_walmart_report.php)](features/walmart-daily-sales-report.md) | The two Walmart sales workbooks (summary + details) built from `TOGA_Walmart` (in-store) and `TOGA_WalmartEComm` (.COM); open for the pseudo-store 1472 channel |
|
|
19
20
|
| [Diagnosing frozen 1.0 worker cron check-ins (Sentry "missed" flood)](workflows/diagnosing-frozen-cron-checkins.md) | Ordered path to diagnose frozen 1.0 worker cron timestamps + a Sentry `worker1` "missed" flood; open when check-ins stall and you suspect a wedged lock. |
|
|
20
21
|
| [isFulfillable Multi-Client Backfill (all togasupply clients)](workflows/isfulfillable-multi-client-backfill.md) | One-time backfill catching up `Items.isFulfillable` on existing items across all 17 togasupply clients; open when running/re-running it or deciding whether rema |
|
|
21
22
|
| [Deduplicating NetSuite duplicate Items across client DBs (recursive MERGE)](workflows/netsuite-duplicate-items-dedup.md) | Per-client cleanup collapsing duplicate `Items` rows (same `partNumber`) to one canonical via recursive MERGE; open before running it — and read the catalog-bli |
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Walmart Daily Sales Report (send_toga_walmart_report.php)
|
|
3
|
+
framework: "1.0"
|
|
4
|
+
repo: worker
|
|
5
|
+
project: Worker
|
|
6
|
+
client: walmart
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: ["mhammontree"]
|
|
11
|
+
files:
|
|
12
|
+
- worker/crons/notifications/reports/send_toga_walmart_report.php
|
|
13
|
+
- worker/crons/notifications/reports/send_incomm_report.php
|
|
14
|
+
related:
|
|
15
|
+
- ../../../clients/walmart/profile.md
|
|
16
|
+
- ../workflows/tracing-a-worker-cron-run-in-production.md
|
|
17
|
+
- ../../library/features/email-test-mode-and-write-free-sends.md
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
The two Walmart sales workbooks (summary + details) built from `TOGA_Walmart` (in-store) and `TOGA_WalmartEComm` (.COM); open for the pseudo-store 1472 channel trap, the registration-not-sale counting rule, and the unmapped-category hole.
|
|
21
|
+
|
|
22
|
+
## Summary
|
|
23
|
+
|
|
24
|
+
`send_toga_walmart_report.php` emails two Excel workbooks:
|
|
25
|
+
|
|
26
|
+
- `WalmartTOGaSales_<date>.xlsx` — "Stores *" summary tabs (Weekly / Prior Week / YTD), categories in columns.
|
|
27
|
+
- `WalmartTOGaSalesDetails_<date>.xlsx` — item-level tabs, one row per paid sale.
|
|
28
|
+
|
|
29
|
+
Data comes from two databases, unioned: **`TOGA_Walmart`** (in-store) and
|
|
30
|
+
**`TOGA_WalmartEComm`** (online, rendered as a pseudo-store `.COM`). The report reads
|
|
31
|
+
`togaClientId = 6` with database `TOGA_Walmart` — **not** the `TOGA.Clients.id = 7` on the
|
|
32
|
+
[Walmart profile](../../../clients/walmart/profile.md). Both identifiers are live; do not
|
|
33
|
+
"correct" one to the other.
|
|
34
|
+
|
|
35
|
+
## How it works
|
|
36
|
+
|
|
37
|
+
1. `$storeNumberSql` (defined once at the top) is the shared channel-label expression, reused
|
|
38
|
+
by the item-level query and both store-level queries so every tab labels a sale the same way.
|
|
39
|
+
Named constants: `$multiChannelStoreId = 1472`, `$areaNumberNoStoreArea = '998'`,
|
|
40
|
+
`$areaNumberEComm = '999'`.
|
|
41
|
+
2. Store-level tabs: `UNION ALL` of the `TOGA_Walmart` in-store leg and the
|
|
42
|
+
`TOGA_WalmartEComm` `.COM` leg, in both the "get stores" and "get data" queries. The store
|
|
43
|
+
list is scoped to stores that **actually sold in the reporting period**, so the ~29 dormant
|
|
44
|
+
stores stay off the tab.
|
|
45
|
+
3. Item-level tabs: `LEFT OUTER JOIN Stores ON Stores.id = ServiceRequests.storeId`, grouped by
|
|
46
|
+
`$storeNumberSql` (not `Stores.id`).
|
|
47
|
+
4. Rows are bucketed into columns by `$cntCategoryMapping` / `$amountCategoryMapping`.
|
|
48
|
+
|
|
49
|
+
## Gotchas
|
|
50
|
+
|
|
51
|
+
- **`TOGA_Walmart.Stores.id = 1472` is a pseudo-store catch-all, and its own `storeNumber` is
|
|
52
|
+
wrong.** Every non-store sale hangs off id 1472. The real channel lives on
|
|
53
|
+
**`ServiceRequests.storeNumber`**, not `Stores.storeNumber`. Verified in prod: id 1472 carries
|
|
54
|
+
`WB` (219 rows, 2023-06-29 → 2026-09-20), `WM+` (118 rows, ended 2023-09-27), and one NULL
|
|
55
|
+
(2025-02-13) — while `Stores.storeNumber` for id 1472 says `WM+`. Reading the Stores row
|
|
56
|
+
mislabels every current sale. Store 1472 also has no `Addresses` row, so City/State render blank.
|
|
57
|
+
- **Never `INNER JOIN Stores` off `ServiceRequests.storeId`** — `storeId` is nullable and the
|
|
58
|
+
inner join silently deletes paid sales (4 lost since 2026-07-01, incl. the 2026-09-13 sale the
|
|
59
|
+
business flagged missing from `WalmartTOGaSalesDetails_20260915.xlsx`).
|
|
60
|
+
- **The report counts registrations, not sales.** `ServiceRequests` rows are created when a
|
|
61
|
+
customer registers the card, never when Walmart rings it up. The InComm SFTP feed is **never
|
|
62
|
+
imported**: `send_incomm_report.php` only downloads the day's files and emails them as
|
|
63
|
+
attachments — no DB write anywhere. So the report's in-store count is structurally lower than
|
|
64
|
+
the InComm file. Investigated under TRUE-81324; **no importer is being built** because Mike
|
|
65
|
+
confirmed Walmart no longer does in-store sales. Do not re-investigate this gap.
|
|
66
|
+
(InComm product: `TOGA_Walmart.Services` id 43558, SKU 302010001, UPC 643570190193,
|
|
67
|
+
`reportingCategory` 'Support'; FY26-to-date 44 units / $3,996.)
|
|
68
|
+
- **Open defect — unmapped categories vanish from the Stores tabs.** The category mappings cover
|
|
69
|
+
only Phone Repair, Tablet Repair, Set-up, Repair, Support, In-Home, Associate Performed.
|
|
70
|
+
Anything else lands in no column and is excluded from the Total. Verified: `TOGA_WalmartEComm`
|
|
71
|
+
has 181 items / $14,118 YTD with `reportingCategory = '0'` that are invisible on the report;
|
|
72
|
+
`TOGA_Walmart` has 6 such services. Fix for a future ticket: add an "Other" catch-all column.
|
|
73
|
+
|
|
74
|
+
## Change history
|
|
75
|
+
|
|
76
|
+
- 2026-09-21 — Restored the in-store `TOGA_Walmart` leg on the Stores tabs (deleted by 4d8e48803 / TRUE-60157 in 2025-03), switched the item query to `LEFT OUTER JOIN Stores`, and extracted the shared `$storeNumberSql` label expression (TRUE-81324). (mhammontree)
|
|
@@ -6,8 +6,8 @@ project: _Underscore
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
10
|
-
owners: ["bala"]
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: ["bala", "apeterson"]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Model/Core/Domain.php
|
|
13
13
|
- api2/Component/Api/CrossClient/CrossClient.php
|
|
@@ -116,9 +116,26 @@ app-specific lookup it will happily return a commerce domain for a supply link.*
|
|
|
116
116
|
the **client.sandbox** api. Do not infer the environment from the config file's name. Three dev
|
|
117
117
|
laptop configs have **no `[api] _` key at all** (`config.dev-chadwimberly-mactop.ini`,
|
|
118
118
|
`config.dev-markhammontree-laptop.ini`, `config.dev-nkeshavamurthy-laptop.ini`).
|
|
119
|
-
- **Rows can pre-exist without a `dbchanges2` migration.** Elite's rows existed
|
|
120
|
-
|
|
121
|
-
[supply client host-scoping](../../toga2-supply/workflows/client-host-scoping.md)).
|
|
119
|
+
- **Rows can pre-exist without a `dbchanges2` migration.** Many of Elite's rows existed with no
|
|
120
|
+
migration that created them — check the table before writing one (see
|
|
121
|
+
[supply client host-scoping](../../toga2-supply/workflows/client-host-scoping.md)). **But
|
|
122
|
+
"Elite has a row for every environment" was WRONG** — corrected 2026-09-18, see the next gotcha.
|
|
123
|
+
- **⚠ The `Origin` match is EXACT, lowercased — no wildcard, no suffix match — and it runs for only
|
|
124
|
+
FIVE auth types.** `V2.php` ~L584-586 does `$domain->domain = strtolower($origin); $domain->load()`.
|
|
125
|
+
The check is reached only for auth type `public`, `login`, `delegator`, `encrypted` and
|
|
126
|
+
`encrypted-user-uuid` (~L577-582); **`/auth/api` (api + secret) skips it entirely.** That is why a
|
|
127
|
+
client can transact happily for months with no `Domains` row and then fail **EN-6 "domain not
|
|
128
|
+
permitted"** the first time a human logs in through the browser.
|
|
129
|
+
- Concrete: Elite could not log in on dev-sandbox because `http://elite.dev.sandbox.togasupply`
|
|
130
|
+
(the local-TLD, environmentId 2 row that **8 other clients have**) did not exist — only the
|
|
131
|
+
`https://elite.dev.sandbox.togasupply.com` row did. Fixed by a new `Core.Domains` row
|
|
132
|
+
(`dbchanges2/Core/2026-09-18a - EliteDevSandboxDomain.sql`).
|
|
133
|
+
- Noted while fixing, **not corrected**: that existing Elite `https` row carries `environmentId`
|
|
134
|
+
**23** while every sibling client's equivalent row uses **4** — a likely mis-seed, and another
|
|
135
|
+
instance of the environment mis-filing recorded above.
|
|
136
|
+
- Debugging order for EN-6: confirm the auth type is one of the five, then match the **full**
|
|
137
|
+
origin string (scheme included) against `Core.Domains` for that client + environment. Do not
|
|
138
|
+
assume a sibling client's working row proves the host is registered for yours.
|
|
122
139
|
|
|
123
140
|
## Related
|
|
124
141
|
|
|
@@ -6,7 +6,7 @@ project: Database Changes
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-21
|
|
10
10
|
owners: [jcardinal, apeterson, tcox, bala]
|
|
11
11
|
files:
|
|
12
12
|
- dbchanges2/Core/2026-09-15a - ItemCreateDefaultsSurfaceSeed.sql
|
|
@@ -294,6 +294,16 @@ CREATE order is FK-safe (`Messages → Actions → Vocabularies → VocabularyTe
|
|
|
294
294
|
|
|
295
295
|
**So how did prod get the rows?** By hand. **There is no automated executor.** Per `toga25-supply/db-migrations/PLAYBOOK.md` a human runs each `.sql` per environment; and per `SURFACE-FEATURE-RUNBOOK.md` § *"Prod ACL procedure (Section 2 can't cross clusters in prod)"* the operator **resolves the ids on prod-core first, then hand-writes literal `INSERT`s against prod-client**. Those hand-fixes were **never written back to the repo**. The fingerprint is visible in the data: every prod `SurfaceOverride` row for these three tenants is stamped **2026-08-19** (one batch), while the files are dated 07-17 … 08-19.
|
|
296
296
|
|
|
297
|
+
**⚠ `Client_Elite` is drifted too — the earlier "Client_Elite's equivalent overrides are correct"
|
|
298
|
+
line below is about the NYCHH stale-id case ONLY, not about Elite being clean.** Confirmed
|
|
299
|
+
2026-09-21: `Client_Elite` carries hand-applied `IS_VISIBLE` + `CONFIG` override rows on
|
|
300
|
+
`inventory-list-groupings` element **118** that appear in **no** dbchanges2 file. An
|
|
301
|
+
`INSERT ... WHERE NOT EXISTS` against that element **silently no-ops** — it looks like a clean
|
|
302
|
+
re-runnable seed and changes nothing. **Practical rule: `SELECT` the target environment's existing
|
|
303
|
+
override rows for the element FIRST, then author an `UPDATE` when a row already exists** (and keep
|
|
304
|
+
the full config in the value — `CONFIG` replaces, never merges). A committed migration records
|
|
305
|
+
intent, not deployed state.
|
|
306
|
+
|
|
297
307
|
**Explicit developer ruling (2026-08-28): do NOT back-port, reconcile, re-run or modify the stale files.** This is not a deferred cleanup and not a follow-up task — it is closed. The consequences that *are* actionable:
|
|
298
308
|
|
|
299
309
|
1. **Read prod** (`reader1.core` / `reader1.client`) for surface state before writing anything new. A `Client_*` file in the repo is evidence of intent, never of prod reality.
|
|
@@ -6,7 +6,7 @@ project: TOGa Blox
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-21
|
|
10
10
|
owners: [apeterson, tcox, bala]
|
|
11
11
|
files:
|
|
12
12
|
- toga-blox/src/components/Table/hooks/useFetchTablePageMeta.ts
|
|
@@ -17,6 +17,7 @@ files:
|
|
|
17
17
|
- toga-blox/src/components/Table/utils/resolveCellType.tsx
|
|
18
18
|
- toga-blox/src/components/Table/components/cellTypes
|
|
19
19
|
- toga-blox/src/components/Table/components/actionCells
|
|
20
|
+
- toga-blox/src/components/Table/utils/buildActionColumn.ts
|
|
20
21
|
- toga-blox/src/components/Table/components/columnFiltersAndSorts
|
|
21
22
|
- toga-blox/src/components/Table/hooks
|
|
22
23
|
- toga-blox/src/components/Table/themeConfig
|
|
@@ -127,6 +128,7 @@ This exists because an unscoped `GET /{recordRoute}` returns *every* row of a lo
|
|
|
127
128
|
- **Recommended durable fix (not done):** drop the allow-list and append `.uuid` only when the slug does **not** already contain a dot. The same stale allow-list is duplicated in toga2-supply `src/api/toga.ts` — see [table-data additional filters](../../toga2-supply/features/table-data-additional-filters.md).
|
|
128
129
|
- **`isExpandableCell` still clobbers every other rich cell type.** Only `STATUS`/`STATUS_BADGE` are protected today. `URGENCY`, `BOOLEAN`, `CURRENCY`, `DATE`, `AVATAR` and `CLIENT` carry the **same latent defect** — set the flag on one of those fields and the cell degrades to raw truncated text. The fuller fix is inverting the deny-list into an **allowlist** (expandable only for free-text/default cells); deliberately not done yet.
|
|
129
130
|
- **A cell-rendering difference between local and a deployed environment is usually DB data, not code.** `isExpandableCell` is a per-field flag in the **server's table meta**, so the same blox build renders differently against two databases. Diff the branches over the cell-rendering files **first** (`git diff <feature> origin/_sandbox-client -- src/components/Table/...`); if that comes back empty, stop reading code and go look at the table-meta rows.
|
|
131
|
+
- **An action cell with no `onAction` used to be DEAD — the chevron is now a real button (2026-09-21).** `ChevronActionCell` rendered a `<div>` whose `onClick` called `onAction?.(row)`, and no consumer ever supplied `onAction` (toga25-supply's `chevronOnly` column sets only id/position/width/type), so the expand chevron was an indicator that did nothing. Tell-tale: the CSS already carried a `.chevronCell:disabled` rule, which can never match a `div`. It is now a `<button>` with `aria-expanded`, `aria-label` (new `expandLabel`/`collapseLabel` props, defaults "Expand row"/"Collapse row"), `disabled` and `stopPropagation`; `ActionCellContext` gained `onRowClick` so a column with no `onAction` falls back to toggling its own row. **That fallback is deliberately scoped to `type === "CHEVRON"`** — applying it to every action-cell type would make e.g. a `DOWNLOAD` column with no `onAction` start firing the row click. A button also needs an explicit CSS reset (`padding: 0; font: inherit`) plus a `:focus-visible` outline. Shipped in `1.1.10-sandbox-client.170`.
|
|
130
132
|
- `MIN_COLUMN_WIDTH = 120` is the shrink floor only for columns with **no** explicit width.
|
|
131
133
|
- **Never truncate header labels.** `truncateCells` (`.truncateCells .headerCellLabel` in `toga.module.css`) is for **body** values only; it must apply only `white-space: nowrap` to the header (no `overflow:hidden`/`text-overflow:ellipsis`/wrapping) or headers show ellipses. Headers must render in full on one line, never abbreviated, never overlapping.
|
|
132
134
|
- The filter `includes` mode treats comma-separated values as OR.
|
|
@@ -6,7 +6,7 @@ project: TOGa Blox
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: workflow
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-21
|
|
10
10
|
owners: [jcardinal, apeterson, tcox, rgirish]
|
|
11
11
|
files:
|
|
12
12
|
- toga-blox/.github/workflows/publish.yml
|
|
@@ -96,6 +96,8 @@ Dates: the **August 2026** npm change removed 2FA-bypass for *account and packag
|
|
|
96
96
|
## Gotchas
|
|
97
97
|
|
|
98
98
|
- **⚠ There is a STALE UNDERSCORED dist-tag on the registry — `_sandbox-client` (with the underscore) is NOT the channel.** Re-verified 2026-09-02, the registry still carries **both** `_sandbox-client` = `1.0.316-sandbox-client.1` (vestigial, predates the current pipeline; it has **not** moved in over a month) **and** `sandbox-client` = `1.1.2-sandbox-client.142` (the live channel head). Branch `_<mode>` maps to channel `<mode>` with the underscore **stripped** (same convention as `amplify.yml`), so the **branch** `_sandbox-client` tracks the **tag** `sandbox-client`. Asking npm for "the latest `_sandbox-client` tag" literally installs something **141 publishes behind**. Always resolve the head with `npm view @agilant/toga-blox dist-tags` and install the underscore-less name.
|
|
99
|
+
- **⚠ `npm view <pkg> dist-tags.<tag>` can report a STALE tag for minutes after a successful publish — do not conclude "nothing published".** It reads the cached packument. Observed 2026-09-21: `npm view <pkg> time --json` already listed the new version while the same document's `dist-tags` and `time.modified` were still old — different fields, different cache states. Authoritative checks: `npm view --prefer-online @agilant/toga-blox dist-tags`, or straight from the registry: `curl -s "https://registry.npmjs.org/-/package/@agilant%2ftoga-blox/dist-tags"`.
|
|
100
|
+
- **A `TRUE-*` ticket branch never publishes.** The trigger is `on.push.branches: ['_*']` only, so work is invisible to any consumer until it is merged into a `_<mode>` release branch.
|
|
99
101
|
- **Publish before build.** `npm install @agilant/toga-blox@<mode>` fails `ETARGET No matching version` in the app build until this repo has published that channel. GitHub Actions runs the workflow version *on the pushed branch*, so the branch must carry the current `publish.yml`.
|
|
100
102
|
- **`publish.yml` has diverged across branches (2026-07-23).** The dynamic `_*` wildcard trigger lives on `_sandbox-client`, but older/feature branches (e.g. `feature-new-table`) still carry the *old* `publish.yml` that triggers only on `_production/_gamma/_beta`. Because Actions runs the copy on the pushed branch, a new `_<mode>` channel will **not** publish unless the branch you push carries the wildcard-trigger version. When standing up a new channel, merge from a branch that has the dynamic `publish.yml` (or update it first).
|
|
101
103
|
- **Do NOT judge a blox branch's staleness by its behind-count.** `feature-new-table` reports **"0 ahead / 47 behind"** `_sandbox-client` and `git merge-base --is-ancestor` says it is fully contained — which reads as "stale, already merged, wrong base". **It is not.** Those 47 commits are almost entirely `Merge branch 'feature-new-table' into _sandbox-client` and `chore: bump version to 1.0.3xx` — **release plumbing generated ON `_sandbox-client` by the publish flow and never merged back**. The actual source difference is **2 files** (`src/global.css`, `src/index.ts`); the rest of the 334-file diff is `.claude/knowledge/` docs and `publish.yml`. `feature-new-table` is the **active development branch** (tip 2026-08-24, `feat: prefer server-supplied filter options in table meta`) and is the correct base. Verified 2026-08-26. Corollary: the `publish.yml` divergence noted above is a **non-issue for publishing**, because Actions runs the workflow on the **pushed** branch (`_sandbox-client`), which carries the dynamic `_*` trigger.
|
|
@@ -6,7 +6,7 @@ project: TOGa Blox
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: workflow
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-21
|
|
10
10
|
owners: [tcox, apeterson]
|
|
11
11
|
files:
|
|
12
12
|
- toga-blox/package.json
|
|
@@ -190,7 +190,7 @@ So `tsc` can be completely clean while the browser runs **stale** blox code —
|
|
|
190
190
|
|
|
191
191
|
## Gotchas
|
|
192
192
|
|
|
193
|
-
- **Confirm the link actually exists before you trust it — docs and memory go stale.** Verified 2026-08-31: `toga25-supply/node_modules/@agilant/toga-blox` is a **real registry install** pinned exactly at `1.1.1-production.139`, **not** a junction to `toga-blox-npm` (checked with PowerShell `(Get-Item <path>).LinkType` → empty). Its architecture doc still claimed a symlink. On a registry install, editing blox `src` — even rebuilding blox — reaches the app **only** via publish + pin bump ([dynamic-publish-pipeline](./dynamic-publish-pipeline.md)). Check `LinkType` (or `ls -l` / `fsutil reparsepoint query`) first; the symptom of getting this wrong is "my change does nothing" with a perfectly good build.
|
|
193
|
+
- **Confirm the link actually exists before you trust it — docs and memory go stale.** Verified 2026-08-31: `toga25-supply/node_modules/@agilant/toga-blox` is a **real registry install** pinned exactly at `1.1.1-production.139`, **not** a junction to `toga-blox-npm` (checked with PowerShell `(Get-Item <path>).LinkType` → empty). Its architecture doc still claimed a symlink. On a registry install, editing blox `src` — even rebuilding blox — reaches the app **only** via publish + pin bump ([dynamic-publish-pipeline](./dynamic-publish-pipeline.md)). Check `LinkType` (or `ls -l` / `fsutil reparsepoint query`) first; the symptom of getting this wrong is "my change does nothing" with a perfectly good build. **Re-confirmed 2026-09-21 on macOS**, still a real directory (then pinned `1.1.3-production.166`). The full macOS loop: `npm run build && npm run build-css` in `toga-blox-npm`, `npm install --no-save ~/Agilant/toga-blox-npm` in the consumer, then **restart Vite** — it pre-bundles deps, so a browser reload alone never picks the change up. Verify the link with `ls -ld node_modules/@agilant/toga-blox` showing an `->` arrow.
|
|
194
194
|
- **The urgent-case escape hatch is patching the INSTALLED `dist`, and it is ephemeral.** Mirroring the source edit into `node_modules/@agilant/toga-blox/dist/**` gives immediate dev visibility, but the next `npm install` / `npm ci` (and every CI build) wipes it. It is a preview, never a deliverable — the change still has to publish and the consumer still has to bump its pin.
|
|
195
195
|
- **`prebuild` does `rm -rf dist`.** A consumer dev server that requests a chunk mid-rebuild serves a 500 and then recovers on the next compile. It is not a real failure — rebuild, reload.
|
|
196
196
|
- **`.next/dev` is locked per app.** A second `next dev` refuses to start while another instance holds the lock. Kill the first one; do not go hunting for a port conflict.
|
|
@@ -6,7 +6,7 @@ project: TOGa 2.5 Supply
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-21
|
|
10
10
|
owners: [apeterson, tcox, jcardinal, bala]
|
|
11
11
|
files:
|
|
12
12
|
- toga25-supply/src/pages/SalesOrders/view/SalesOrderRecordModalLayout/hooks/usePurchaseOrderDetails.ts
|
|
@@ -101,6 +101,34 @@ A config-driven renderer: declare an array of `TableLevel` objects instead of ha
|
|
|
101
101
|
|
|
102
102
|
> **The FE APPENDS `.uuid` to a swap level's `additionalDataSlug` itself — so the stored surface value must be the BARE table name (`PurchaseOrders`), never `<Table>.uuid`.** The grouping config lives on `Core.SurfaceElements.config` (`inventory-list-groupings`, e.g. element key `posByItems`, in `$.levels[N].additionalDataSlug`). If you store `PurchaseOrders.uuid` there, the FE produces a **doubled** where clause `(PurchaseOrders.uuid.uuid:like:...)` and the filter never binds. Fix the stored value to just `PurchaseOrders` (JSON_SET keyed by `Surfaces.slug` + `config.key`, guarded to the stale value so it is re-runnable — id/uuid-agnostic because ids differ per env). Confirmed on NYCHH 2026-09-03: this Core row is all-client (no NYCHH SurfaceOverride), and its old `SalesOrders.uuid` was already wrong for a child view named `items-for-purchase-orders`. Sibling element `itemsByPOs` (view `purchase-orders_items`) still carries the stale `SalesOrders.uuid` — likely the same bug, not yet fixed.
|
|
103
103
|
|
|
104
|
+
#### Level `role` is the hydration switch — swap vs leaf is a DATA change
|
|
105
|
+
|
|
106
|
+
Inventory's `hydrateLevel` (`src/pages/Inventory/viewModel/useInventoryPageViewModel.tsx`, field
|
|
107
|
+
map in `viewModel/FIELDS/index.ts`) builds each `TableLevel` from the surface config's **`role`**
|
|
108
|
+
enum: `root` | `swap` | `leaf` | `flat`.
|
|
109
|
+
|
|
110
|
+
- **`role: "swap"`** hardcodes the "See units" trigger column (`makeSeeUnitsColumns`) **plus** a
|
|
111
|
+
back-button header.
|
|
112
|
+
- **`role: "leaf"`** is a plain nested table — no trigger, no swap, no row click.
|
|
113
|
+
|
|
114
|
+
So removing a drill-down tier and its trigger button is `swap` → `leaf` in
|
|
115
|
+
`Core.SurfaceElements.config` (or a client `CONFIG` override) — **no frontend change**. Elite's
|
|
116
|
+
"Units by Items" is the reference (see [Elite profile](../../../clients/elite/profile.md)).
|
|
117
|
+
|
|
118
|
+
> **Do NOT hide a swap trigger by dropping `buildSwapTriggerColumns`.** Its absence re-enables the
|
|
119
|
+
> legacy whole-row swap via `getRowHref` (`GenericNestedTables.tsx` ~L37-42) — the row becomes a
|
|
120
|
+
> drill-down again instead of becoming inert.
|
|
121
|
+
|
|
122
|
+
#### A terminal level must not be row-clickable
|
|
123
|
+
|
|
124
|
+
`renderChildLevel` is `undefined` on the last level (`GenericNestedTables.tsx` ~L83-98), so a
|
|
125
|
+
terminal level has **no** `renderModal` and **no** `renderExpandedContent` — yet `GenericTableLayout`
|
|
126
|
+
passed `handleRowClick` to `PrimaryTableServerLayout` unconditionally. Clicking wrote
|
|
127
|
+
`?<slug>=<uuid>` into the URL and refetched the table to open nothing. Fix (`GenericTableLayout.tsx`):
|
|
128
|
+
compute `isRowClickable = !!renderModal || !!renderExpandedContent || !!getRowHref` and pass the
|
|
129
|
+
existing `disableRowClick` prop (Pattern 4) when false — `PrimaryTableServerLayout.tsx` L155 nulls
|
|
130
|
+
`onRowClick`, which also drops the hover/pointer affordance.
|
|
131
|
+
|
|
104
132
|
A page-level `pageMeta` (from `useFetchPageMeta`) flows down for field-label overrides. The page view model builds `TableLevel[]` arrays, picks the active one via a URL param, and passes `levels` to `GenericNestedTables` with `key={activeGrouping.key}` to force remount and avoid stale state.
|
|
105
133
|
|
|
106
134
|
#### Decoupling "drill to child tier" from "open this record" on a swap level
|
package/knowledge/INDEX.md
CHANGED
|
@@ -5,7 +5,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
5
5
|
## 1.0 framework
|
|
6
6
|
|
|
7
7
|
- **library** (Library) _(framework core)_ — 26 doc(s) → [1.0/apps/library/INDEX.md](1.0/apps/library/INDEX.md)
|
|
8
|
-
- **worker** (Worker) —
|
|
8
|
+
- **worker** (Worker) — 37 doc(s) → [1.0/apps/worker/INDEX.md](1.0/apps/worker/INDEX.md)
|
|
9
9
|
- **dbchanges** (Database Changes) _(framework core)_ — 1 doc(s) → [1.0/apps/dbchanges/INDEX.md](1.0/apps/dbchanges/INDEX.md)
|
|
10
10
|
- **worker1.5** (Worker 1.5) — 0 doc(s) → [1.0/apps/worker1.5/INDEX.md](1.0/apps/worker1.5/INDEX.md)
|
|
11
11
|
- **togadesk** (TOGa Desk) — 13 doc(s) → [1.0/apps/togadesk/INDEX.md](1.0/apps/togadesk/INDEX.md)
|
|
@@ -7,6 +7,7 @@ apps:
|
|
|
7
7
|
- library
|
|
8
8
|
- toga2-supply
|
|
9
9
|
- toga25-supply
|
|
10
|
+
- toga-blox
|
|
10
11
|
- dbchanges2
|
|
11
12
|
- _underscore
|
|
12
13
|
- api2
|
|
@@ -16,7 +17,7 @@ project: Worker
|
|
|
16
17
|
client: elite
|
|
17
18
|
type: profile
|
|
18
19
|
status: active
|
|
19
|
-
updated: 2026-09-
|
|
20
|
+
updated: 2026-09-21
|
|
20
21
|
owners: [snaredla, apeterson, tcox, bala, rgirish]
|
|
21
22
|
files:
|
|
22
23
|
- worker2/Worker/Elite.php
|
|
@@ -88,6 +89,21 @@ pendingFulfillment / partiallyFulfilled / fulfilled / shipped / delivered / canc
|
|
|
88
89
|
approval model**, so the Compass status logic does not transfer - see
|
|
89
90
|
[IF stage lifecycle & order status](../../2.0/apps/_underscore/features/item-fulfillment-stage-lifecycle-and-order-status.md).
|
|
90
91
|
|
|
92
|
+
## Supply Inventory grouping — "Units by Items" is two levels, not three (2026-09-21)
|
|
93
|
+
|
|
94
|
+
Elite's `Group: Units by Items` showed a third level plus a **"See units"** trigger column. The
|
|
95
|
+
level depth and its trigger are **data**, not code: `Core.SurfaceElements.config` on
|
|
96
|
+
`inventory-list-groupings` (surface 40, element 118), overridden per client. Changing the level's
|
|
97
|
+
`role` from `"swap"` to `"leaf"` removes both the trigger column and the tier — no frontend change.
|
|
98
|
+
Delivered as a `Client_Elite.SurfaceOverrides` `CONFIG` row
|
|
99
|
+
(`dbchanges2/Client_Elite/2026-09-21a - InventoryUnitsByItemsTwoLevels.sql`).
|
|
100
|
+
|
|
101
|
+
**⚠ Elite already had hand-applied `SurfaceOverrides` rows for element 118 (`IS_VISIBLE` and
|
|
102
|
+
`CONFIG`) that exist in NO dbchanges2 file.** The migration had to be an `UPDATE`; an
|
|
103
|
+
`INSERT ... WHERE NOT EXISTS` silently no-ops. Elite is therefore **not** drift-free — read the
|
|
104
|
+
target environment before authoring any surface override
|
|
105
|
+
([surface-layer-schema](../../2.0/apps/dbchanges2/features/surface-layer-schema.md)).
|
|
106
|
+
|
|
91
107
|
## Shipping rules (confirmed with Elite by Bala, 2026-08-12)
|
|
92
108
|
|
|
93
109
|
Two client rules that constrain every order-creation surface (the desk Service Request modal, the
|
|
@@ -137,9 +153,13 @@ are back to `isActive = 0`, so the push is off in prod again. Separately, four d
|
|
|
137
153
|
test orders **round-tripped into prod `Client_Elite.SalesOrders` 261–266** through the inbound sync
|
|
138
154
|
(the NetSuite account is shared by all environments) — **do not bulk-delete that range.**
|
|
139
155
|
|
|
140
|
-
**Tenant/test-account notes.** `Core.Domains` rows for Elite
|
|
141
|
-
|
|
142
|
-
|
|
156
|
+
**Tenant/test-account notes.** Most `Core.Domains` rows for Elite exist with no dbchanges2 Core
|
|
157
|
+
migration creating them (dev `http://elite.togasupply`, beta, production, sandbox-dev) — but
|
|
158
|
+
**not every environment: the dev-sandbox local-TLD row was missing**, which broke browser login
|
|
159
|
+
with **EN-6 "domain not permitted"** (added by `dbchanges2/Core/2026-09-18a - EliteDevSandboxDomain.sql`,
|
|
160
|
+
stashed not committed — it is a different ticket than TRUE-82109). Details and the exact-match /
|
|
161
|
+
five-auth-types rule: [Core.Domains registry](../../2.0/apps/_underscore/features/core-domains-app-host-registry.md).
|
|
162
|
+
Elite and Elite has **no `ClientAuthentications` row** — supply2 login is
|
|
143
163
|
ordinary password auth. The shared `devteam@togatech.com` test user was seeded into dev-sandbox
|
|
144
164
|
`Client_Elite.Users` (+ `Users_Roles`; Elite roles are 1=Base, 2=Developer, 3=API, 4=Public) from
|
|
145
165
|
`Client_Compass.Users` — see the
|
|
@@ -9,7 +9,7 @@ apps:
|
|
|
9
9
|
client: walmart
|
|
10
10
|
type: client-feature
|
|
11
11
|
status: active
|
|
12
|
-
updated: 2026-09-
|
|
12
|
+
updated: 2026-09-21
|
|
13
13
|
owners: ["mhammontree"]
|
|
14
14
|
files:
|
|
15
15
|
- library/app/client/walmart.php
|
|
@@ -19,6 +19,7 @@ related:
|
|
|
19
19
|
- clients/walmart/features/domain-migration.md
|
|
20
20
|
- clients/walmart/features/registration-route.md
|
|
21
21
|
- clients/walmart/features/customer-email-lifecycle.md
|
|
22
|
+
- 1.0/apps/worker/features/walmart-daily-sales-report.md
|
|
22
23
|
---
|
|
23
24
|
|
|
24
25
|
Walmart B2C tech-services tenant (client id 7); open for its identifiers, key files, and the `requireRegistrationUrl` DB rule.
|
package/package.json
CHANGED