toga-ai 1.0.711 → 1.0.712

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.
@@ -0,0 +1,242 @@
1
+ ---
2
+ type: session
3
+ slug: transfer-orders-id-collision
4
+ title: Transfer Orders Core id collision + blox symlink dev-loop fix
5
+ author: apeterson
6
+ repos: [dbchanges2, toga25-supply, toga-blox, _underscore]
7
+ framework: "2.0"
8
+ client: nychh
9
+ status: active
10
+ created: 2026-08-31
11
+ updated: 2026-08-31
12
+ ---
13
+
14
+ # Session: transfer-orders-id-collision
15
+ **Date:** 2026-08-31
16
+ **Project/Repo:** dbchanges2 + toga25-supply + toga-blox (2.0)
17
+ **Task:** Get the NYCHH Transfer Orders page working on sandbox-client after a reset-from-production, and permanently fix the toga-blox local-symlink dev loop in toga25-supply.
18
+
19
+ ---
20
+
21
+ ## What WORKED
22
+
23
+ - **Published `/capture` round two.** 13 doc updates + 4 regenerated `INDEX.md` pushed as
24
+ `172f85d` `knowledge: capture session updates` on `_main` of `~/toga-tech`, confirmed on
25
+ `origin/_main` (CI stacked `c0fcabc` on top). `validate` passed (32 repos), index rebuilt to
26
+ 454 docs, nothing outside `knowledge/` staged.
27
+
28
+ - **Diagnosed the `TalosLauncher` import error correctly on the second pass.**
29
+ `toga25-supply/node_modules/@agilant/toga-blox` was a REAL DIRECTORY holding published
30
+ `1.1.1-sandbox-client.140`, which contains **zero** files matching `Talos`. The local
31
+ checkout (`1.1.0`, branch `TRUE-80692`) had a perfectly intact export chain:
32
+ `dist/index.js` -> `dist/components/index.js:44` -> `dist/components/Talos/index.js` ->
33
+ `export { default as TalosLauncher }`. Evidence: `ls -la node_modules/@agilant/` showed no
34
+ `->`, and `grep -rl Talos node_modules/@agilant/toga-blox/` returned nothing.
35
+
36
+ - **Created the symlink per the team workflow.** `npm install --no-save
37
+ /Users/alexpeterson/Agilant/toga-blox-npm` from toga25-supply produced
38
+ `toga-blox -> ../../../toga-blox-npm` resolving to `1.1.0`, and left `package.json`
39
+ untouched (git status clean).
40
+
41
+ - **Permanently fixed the Vite dev loop** in `toga25-supply/vite.config.ts`. It now detects the
42
+ symlink with `fs.lstatSync(bloxDir).isSymbolicLink()` and picks opposite `optimizeDeps`
43
+ settings: LINKED -> `exclude: ["@agilant/toga-blox"]` + `include: BLOX_EXTERNALS`;
44
+ PUBLISHED -> `include: ["@agilant/toga-blox"]` (previous behaviour, unchanged). Also added
45
+ `server.fs.allow` for the symlink's real path. Verified from the running dev server: the
46
+ transform now emits
47
+ `import { SideNav, EnvironmentBadge, TalosLauncher, ... } from "/@fs/Users/alexpeterson/Agilant/toga-blox-npm/dist/index.js"`
48
+ and `node_modules/.vite/deps/@agilant_toga-blox.js` is absent.
49
+
50
+ - **Enumerated blox's full external surface** (the `include` list needed once blox is excluded),
51
+ generated from its dist:
52
+ `@fortawesome/{free-solid,pro-light,pro-regular,pro-solid}-svg-icons`,
53
+ `@fortawesome/react-fontawesome`, `@sentry/react`,
54
+ `@tanstack/{react-query,react-table,react-virtual}`, `axios`,
55
+ `class-variance-authority`, `classnames`, `clsx`, `dayjs`, `dayjs/plugin/timezone`,
56
+ `dayjs/plugin/utc`, `framer-motion`, `react-hook-form`, `react-multi-select-component`,
57
+ `react-select`, `tailwind-merge`, `uuid`.
58
+ Regeneration command is in a comment above the list in `vite.config.ts`.
59
+
60
+ - **Root-caused why Transfer Orders did not render on sandbox-client.** The two `Core/` seeds
61
+ had never run there, AND `Core/2026-08-28a` could no longer run as written: production had
62
+ shipped a `sales-order-denial-details` feature into the exact reserved blocks
63
+ (`Surfaces 47`, `SurfaceElements 170-176`, `Messages 227-232`). Sandbox had zero rows
64
+ matching `%transfer%` in Surfaces or Messages.
65
+
66
+ - **Confirmed `Core/2026-08-28b` ran cleanly on sandbox with no collision.** Its ids
67
+ (Surface 52, Elements 187-189, Messages 251-260) all sat above the then-MAX of 47/176/232.
68
+ Verified present and correct.
69
+
70
+ - **Proved no damage was done to the other team's feature.** All denial-details rows show
71
+ `dtCreated == dtUpdated == 2026-08-31 09:45:11` (the reset timestamp) — never updated. And
72
+ `_underscore/Model/Core/Surface.php:748` `_loadOverrides()` filters
73
+ `WHERE SurfaceOverrides.surfaceId = $surfaceId`, so the NYCHH override row (surfaceId 39,
74
+ surfaceElementId 170) is only ever loaded when rendering surface 39 and can never reach
75
+ surface 47. It is inert in both directions.
76
+
77
+ - **Renumbered `Core/2026-08-28a` safely.** Shifts applied: Surfaces `47-51 -> 53-57`,
78
+ SurfaceElements `170-186 -> 190-206`, Messages `227-250 -> 261-284`. Verified after the
79
+ rewrite: the md5 of every quoted string in the file is IDENTICAL to the backup (UUIDs and
80
+ slugs untouched), and the occurrence counts of `312`, `351`, `39` and `70` are unchanged.
81
+ FK graph re-derived and correct — nav element 190 on surface 39; 191-194 -> 54;
82
+ 195-197 -> 55; 198-200 -> 56; 201-206 -> 57.
83
+
84
+ - **Repointed the cross-DB reference.** `Client_Nychh/2026-08-28b` had 3 occurrences of `170`
85
+ (comment, INSERT value, NOT EXISTS guard) — all now `190`.
86
+
87
+ - **Verified the new blocks are free on BOTH sandbox-client and local** (`53-57`, `190-206`,
88
+ `261-284` all return 0), and that `Core.Surfaces 39` is `navigation` (TAB_STRIP).
89
+
90
+ ---
91
+
92
+ ## What did NOT work — DO NOT RETRY THESE
93
+
94
+ - **`rm -rf node_modules/.vite` + hard reload did NOT fix the `TalosLauncher` error.** This was
95
+ the first hypothesis and it was wrong. The export genuinely was not in the package Vite had
96
+ pre-bundled, because supply was consuming the published tarball, not the local checkout. Do
97
+ not reach for the cache clear before confirming `ls -la node_modules/@agilant/` shows a `->`.
98
+
99
+ - **After symlinking, the error STILL persisted** and a normal hard reload did not clear it.
100
+ Vite serves `/node_modules/.vite/deps/*` with `Cache-Control: max-age=31536000, immutable`.
101
+ The re-optimize rewrote the file but kept the same `browserHash` (`69916b97`), so the URL
102
+ never changed and Chrome would not revalidate. Proven by `curl`-ing the dev server for that
103
+ exact URL and finding `TalosLauncher_default as TalosLauncher` present in the response while
104
+ the browser still errored. Fix at the time: DevTools -> Network -> **Disable cache**. Fix
105
+ permanently: the `optimizeDeps` change above.
106
+
107
+ - **First renumbering attempt CORRUPTED the file — UUIDs got shuffled.** The Python transform
108
+ protected quoted strings by replacing them with `\x00<index>\x00` placeholders. `\x00` is not
109
+ a word character, so the subsequent bare-integer regex matched the placeholder INDICES and
110
+ shifted them, meaning literals were restored to the wrong positions. Caught by comparing the
111
+ md5 of the extracted UUID list before/after (`CHANGED`). Fixed by restoring from backup and
112
+ re-running with a **digit-free placeholder** (`\x01<a-j encoded index>\x01`). Always verify a
113
+ bulk rewrite by diffing the quoted-string set, not by eyeballing.
114
+
115
+ - **Assuming the hyphenated ranges in the file header would be shifted.** The bare-integer regex
116
+ is `(?<![\w.\-])\d+(?![\w.\-])`, so `227-250`, `47-51` and `170-186` in comments were skipped
117
+ (hyphen guard on both sides). A `str.replace` of the old header block asserted false because
118
+ it still contained the ORIGINAL numbers. This is desirable behaviour — it is why nothing
119
+ unintended shifted — but the header had to be rewritten by hand afterwards.
120
+
121
+ - **macOS/zsh tool gaps hit repeatedly** (all cost a round trip):
122
+ - `timeout` does not exist — use `mysql --connect-timeout=N`.
123
+ - `cat -A` is illegal on macOS — use `od -c` or `sed -e 's/$/<EOL>/'`.
124
+ - Unquoted `--include=*.js` is glob-expanded by zsh and fails — quote it.
125
+ - `grep -oE` does not support lookbehind; `grep -P` is required for `(?<!...)`.
126
+ - The `mysql` alias is a shell alias, so `$LM="mysql ..."` in a variable is not resolved —
127
+ call `/Applications/XAMPP/xamppfiles/mysql/bin/mysql` by full path.
128
+
129
+ - **Do NOT re-run `Client_Nychh/2026-08-28b` on any machine that already has the row.** It now
130
+ carries element `190`, but its `uuid` is a fixed literal
131
+ (`7a8b9c0d-1e2f-4304-8516-6a7b8c9d0e1f`), so the insert would fail on the duplicate UUID. Use
132
+ the `UPDATE ... SET surfaceElementId = 190 WHERE uuid = '...'` instead.
133
+
134
+ ---
135
+
136
+ ## Not tried yet (candidates for next session)
137
+
138
+ - Running the 4 sandbox steps and 3 local steps listed under **Exact next step** — nothing has
139
+ been executed yet.
140
+ - Committing the 7 dbchanges2 files. They are ALL still untracked, which is the direct cause of
141
+ the id collision (no registry, no visibility to the other developer).
142
+ - Production rollout — nothing has been run there at all.
143
+ - Beta — still blocked, it has no `TransferOrderStages` table.
144
+ - Flipping `TRANSFER_ORDER_LINES_ENABLED` to `true` in
145
+ `toga25-supply/src/pages/TransferOrders/view/TransferOrderRecordModalLayout/hooks/useTransferOrderRecord.ts`
146
+ once `Client/2026-08-28b` is applied everywhere.
147
+ - Fixing the blank-client template (`Client/2026-06-03- BLANK_CLIENT_DATABASE.sql` line ~9462)
148
+ so new tenants get `TransferOrderItems.dtCreated`/`dtUpdated`.
149
+ - The Create Transfer Order modal — still a UI shell; its 3 blocking data questions remain
150
+ unanswered (which `UnitDispositions` slug counts as available; whether `Locations` are
151
+ hierarchical; who owns the unit-disposition flip to In Transit).
152
+ - Switching `vite.config.ts`'s `BLOX_EXTERNALS` to something generated at config time rather
153
+ than a hand-maintained list.
154
+
155
+ ---
156
+
157
+ ## Current file state
158
+
159
+ | File | Status | Notes |
160
+ |------|--------|-------|
161
+ | `toga25-supply/vite.config.ts` | MODIFIED (uncommitted) | Symlink-aware `optimizeDeps` + `server.fs.allow`. Backup at `scratchpad/vite.config.ts.bak`. Verified working against the running dev server. |
162
+ | `toga25-supply/node_modules/@agilant/toga-blox` | RELINKED | Now `-> ../../../toga-blox-npm` (v1.1.0). `--no-save`, so `package.json` untouched. Any plain `npm i` will clobber it. |
163
+ | `dbchanges2/Core/2026-08-28a - TransferOrderSurfaceSeed.sql` | RENUMBERED (untracked) | Surfaces 53-57, Elements 190-206, Messages 261-284. Header rewritten with the collision post-mortem + a re-verify warning. NOT RUN ANYWHERE YET. |
164
+ | `dbchanges2/Core/2026-08-28b - TransferOrderListActionsSurfaceSeed.sql` | UNCHANGED (untracked) | Already applied to sandbox-client Core AND local Core. Correct as-is. |
165
+ | `dbchanges2/Client_Nychh/2026-08-28b - TransferOrdersNavigationEnable.sql` | MODIFIED (untracked) | `surfaceElementId` 170 -> 190 in 3 places. Already-applied rows need the UPDATE, not a re-run. |
166
+ | `dbchanges2/Client_Nychh/2026-08-28a - TransferOrdersTableView.sql` | UNCHANGED (untracked) | Applied to sandbox (TableView 22, 4 fields) and local. |
167
+ | `dbchanges2/Client_Nychh/2026-08-28c - TransferOrderRecordAcl.sql` | UNCHANGED (untracked) | Applied to sandbox (4 record perms, 34 field perms). |
168
+ | `dbchanges2/Client/2026-08-28a - TransferOrderStageThemeTokens.sql` | UNCHANGED (untracked) | NOT RUN on sandbox OR local (0 `color.transferStage.*` tokens on both). |
169
+ | `dbchanges2/Client/2026-08-28b - TransferOrderItemsTimestamps.sql` | UNCHANGED (untracked) | No action needed — production already had the columns, so sandbox has them via the reset. |
170
+ | `scratchpad/local-undo-transfer-surface-old-ids.sql` | CREATED | Deletes 24 messages / 5 surfaces / 17 elements / 6 vocabulary rows BY UUID in FK order, then repoints local's override to 190. Leaves `2026-08-28b` alone. |
171
+ | `scratchpad/28a.before.sql`, `nychh28b.before.sql`, `vite.config.ts.bak` | CREATED | Pre-change backups. |
172
+
173
+ ---
174
+
175
+ ## Decisions made
176
+
177
+ - **Renumber into a contiguous block ABOVE the current MAX (53-57 / 190-206 / 261-284) rather
178
+ than back-filling the gaps** left at Surfaces 48-51, Elements 177-186, Messages 233-250.
179
+ Rationale: a contiguous block above MAX is trivially verifiable and trivially reversible
180
+ (`DELETE WHERE id >= n`), whereas a split block is neither. Ids are not scarce. Rejected:
181
+ filling the gaps to keep numbering compact.
182
+
183
+ - **Fix already-applied override rows with a targeted `UPDATE` by uuid, not by re-running the
184
+ migration.** Rationale: the file's uuid is a fixed literal, so a re-run would fail on the
185
+ duplicate key; and after the UPDATE the file's `NOT EXISTS` guard correctly no-ops. Rejected:
186
+ DELETE-then-rerun (more destructive for no benefit).
187
+
188
+ - **`vite.config.ts` detects the symlink instead of exposing a flag/env var.** Rationale: the
189
+ linked and published cases need OPPOSITE `optimizeDeps` settings, and any flag a developer
190
+ must remember to flip will be wrong half the time — which is the whole class of bug this
191
+ session was spent on. Rejected: an env var, and rejected leaving `include` in place and
192
+ documenting the manual cache-clear ritual.
193
+
194
+ - **Left `BLOX_EXTERNALS` as a hand-maintained list with the regeneration command in a comment.**
195
+ Rationale: generating it at config time means reading blox's dist on every server start.
196
+ Accepted cost: if blox adds a dependency, the symptom is
197
+ `does not provide an export named 'default'` on that new package.
198
+
199
+ - **Declined both ELEVATED knowledge-base edits** during `/capture` (developer's call):
200
+ the dbchanges2 `architecture.md` test-data Critical rule, and the `standards/frontend.md`
201
+ §11/§13(c) dedupe accuracy fix. Consequence: the dedupe + `rm -rf node_modules/.vite`
202
+ detail lives ONLY in `toga-blox/workflows/local-link-into-a-consumer-app.md`, and the
203
+ test-data rule ONLY in `toga25-supply/features/transfer-orders-page.md`.
204
+
205
+ - **Did not commit the `.env.development` change** in toga25-supply. Rationale: its diff
206
+ repoints every developer's dev server.
207
+
208
+ ---
209
+
210
+ ## Blockers
211
+
212
+ - **The 7 dbchanges2 files are all untracked.** This is not incidental — it is the direct cause
213
+ of the id collision. Two developers both computed `MAX(id)+1` against the same Core; the other
214
+ one shipped first. Nothing in git could warn either side.
215
+ - **Beta cannot take these migrations** — it has no `TransferOrderStages` table.
216
+ - **Reserved ids remain structurally unsafe.** Core ids must be literals because Core and Client
217
+ are on separate clusters in production, so a Client file cannot join to Core to resolve one.
218
+ That forces the number to be chosen at authoring time, opening a race for however long the
219
+ feature takes to ship. Nothing systemic was changed this session — only this one file was
220
+ renumbered and a re-verify warning added to its header.
221
+
222
+ ---
223
+
224
+ ## Exact next step
225
+
226
+ > Run, in order, and stop if any verification returns non-zero:
227
+ >
228
+ > **sandbox-client / `Core`:** (1) `SELECT (SELECT COUNT(*) FROM Surfaces WHERE id BETWEEN 53 AND 57) AS surf, (SELECT COUNT(*) FROM SurfaceElements WHERE id BETWEEN 190 AND 206) AS elem, (SELECT COUNT(*) FROM Messages WHERE id BETWEEN 261 AND 284) AS msg;` — all must be 0.
229
+ > (2) run `Core/2026-08-28a - TransferOrderSurfaceSeed.sql`.
230
+ >
231
+ > **sandbox-client / `Client_Nychh`:** (3) `UPDATE SurfaceOverrides SET surfaceElementId = 190 WHERE uuid = '7a8b9c0d-1e2f-4304-8516-6a7b8c9d0e1f';`
232
+ > (4) run `Client/2026-08-28a - TransferOrderStageThemeTokens.sql`. Then reload the app — the
233
+ > Transfer Orders nav item should appear for NYCHH.
234
+ >
235
+ > **local:** (5) run `scratchpad/local-undo-transfer-surface-old-ids.sql` (its closing SELECT
236
+ > must be all zeros), (6) run the renumbered `Core/2026-08-28a`, (7) run
237
+ > `Client/2026-08-28a` against `Client_Nychh`.
238
+ >
239
+ > Then commit all 7 dbchanges2 files so the id blocks are recorded in git.
240
+
241
+ ---
242
+ _Saved by /session-save on 2026-08-31_
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.711",
3
+ "version": "1.0.712",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",