toga-ai 1.0.303 → 1.0.305

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.
@@ -21,4 +21,5 @@
21
21
  | [Surface Resolver (_Model_Core_Surface::resolve — replaces Page::meta)](features/surface-resolver.md) | The runtime for the platform-wide **Surface** UI presentation layer: 9 `_underscore` models plus a cached resolver, `_Model_Core_Surface::resolve(&$api, string | _underscore/Model/Core/Surface.php, _underscore/Model/Client/AclRecordScript.php, _underscore/Model/Core/RecordScript.php, dbchanges2/Core/2026-06-30a - SurfaceMetaGroupAndSalesOrderSections.sql, dbchanges2/Client/2026-06-30a - SurfaceMetaGroupAcl.sql, dbchanges2/Client_Quad/2026-07-01a - GrantSurfacesMetaGroupScriptAcl.sql, dbchanges2/Client_CompassCanada/2026-07-01a - GrantSurfacesMetaGroupScriptAcl.sql, dbchanges2/Core/2026-06-29b - SurfaceMetaPublicReadAcl.sql, dbchanges2/Client/2026-06-29c - SurfaceRecordScriptAcl.sql, dbchanges2/Core/2026-06-29c - SurfaceDebugPhpMethodFix.sql, _underscore/Model/Core/SurfaceElement.php, _underscore/Model/Core/Action.php, _underscore/Model/Core/Vocabulary.php, _underscore/Model/Core/VocabularyTerm.php, _underscore/Model/Core/Message.php, _underscore/Model/Client/SurfaceOverride.php, _underscore/Model/Client/MessageTranslation.php, _underscore/Model/Client/ThemeToken.php, _underscore/Model/Core/Page.php |
22
22
  | [Tracking-Number Bridge Migration (ASN / Item Fulfillment / Item Receipt)](features/tracking-number-bridges.md) | Shipment tracking numbers used to live as **scalar FK columns** (`trackingNumberId`, `returnTrackingNumberId`) directly on the lowest-level "unit"/"item" tables | api2/Component/Api/V2/V2.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillmentItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Prudential/AdvanceShippingNotice.php, _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Trait/Netsuite/ItemFulfillment.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Core/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Client_Prudential/2026-06-15 - ItemFulfillmentTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Quad/2026-06-18a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Nychh/2026-06-19b - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql, dbchanges2/Client_Nychh/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql, dbchanges2/Client_Quad/2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql |
23
23
  | [Units for Items for Purchase Orders — Data Structure](features/units-for-items-for-purchase-orders.md) | Describes how unit (serialized inventory) data is linked to sales-order and purchase-order line items behind the `units-for-items-for-purchase-orders` TableView | |
24
+ | [Refreshing a Local Dev Database from Beta (dev-sandbox)](workflows/local-db-refresh-from-beta.md) | How to reset a local 2.0 dev database from the **beta / dev-sandbox** environment: dump each schema (`Core`, `Client_<Id>`, `Logs_<Id>`, …) from the beta host, | api2/Config/, _underscore/Loader.php, _underscore/Model/Client/BundleTranslation.php, api2/Component/Api/V2/V2.php, toga25-supply/sync_compasscanada_schema.sql |
24
25
  | [Running a 2.0 App Locally (browser, end-to-end via api2)](workflows/running-a-2.0-app-locally.md) | The full dependency chain required to run a 2.0 client app **through the browser**, end-to-end, against a **local `api2`** (e.g. | _underscore/Environment.php, _underscore/Config.php, _underscore/Database.php, _underscore/Route.php, api2/Component/Api/V2/V2.php, api2/index.php, api2/.htaccess |
@@ -7,13 +7,14 @@ client: shared
7
7
  type: feature
8
8
  status: active
9
9
  updated: 2026-07-09
10
- owners: ["dfranks", "jcardinal", "mhammontree"]
10
+ owners: ["dfranks", "jcardinal", "mhammontree", "apeterson"]
11
11
  files:
12
12
  - _underscore/Database.php
13
13
  - _underscore/ApiRequest.php
14
14
  - _underscore/Model/Client/Logs/Api.php
15
15
  related:
16
16
  - ../architecture.md
17
+ - ../workflows/local-db-refresh-from-beta.md
17
18
  ---
18
19
 
19
20
  ## Summary
@@ -84,9 +85,10 @@ registration is region-aware in `api2/Controller/Index.php`; the alias const is
84
85
  For logs, structure-only is enough (you never need prod log rows locally):
85
86
  `mysqldump -h reader1.logs.database.togahub.com -u admin -p<pw> --no-data --no-tablespaces
86
87
  --set-gtid-purged=OFF --column-statistics=0 Logs_<Id> | mysql -u root Logs_<Id>` (create the
87
- empty DB first). Data DB comes from `reader1.client.database.togahub.com` (see the local-DB
88
- refresh notes). This is a **local-environment** gap, not a code bug — do not "fix" it by
89
- disabling logging in shared code.
88
+ empty DB first). Data DB comes from `reader1.client.database.togahub.com`, or refresh the whole
89
+ set from beta — see [Refreshing a local dev DB from beta](../workflows/local-db-refresh-from-beta.md).
90
+ This is a **local-environment** gap, not a code bug — do not "fix" it by disabling logging in
91
+ shared code.
90
92
  - Related 1.0 analogue: the legacy `App_` worker has the same hazard writing to `Logs.API`
91
93
  (`db_logs`) — the laptop trap there is documented separately in the worker NetSuite bootstrap
92
94
  notes.
@@ -94,6 +96,8 @@ registration is region-aware in `api2/Controller/Index.php`; the alias const is
94
96
  ## Change history
95
97
 
96
98
  - 2026-07-09 — Linked the new [Running a 2.0 app locally](../workflows/running-a-2.0-app-locally.md) runbook, which frames these three connections as one requirement of a full local browser run. (mhammontree)
99
+ - 2026-07-09 — Linked the new [local-DB-refresh-from-beta workflow](../workflows/local-db-refresh-from-beta.md)
100
+ from the logs-trap fix (refreshing all local schemas from beta covers the missing `Logs_<Id>`). (apeterson)
97
101
  - 2026-07-07 — Noted the new shared **Cache** cluster (`Databases` id 145, alias `DB_CACHE`,
98
102
  region-aware) added for the api2 cross-client retrieval engine. (jcardinal)
99
103
  - 2026-06-18 — Documented after the `Logs_Growrk`/`Logs_Aig` local 500s while testing the
@@ -6,8 +6,8 @@ project: _Underscore
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-06-19
10
- owners: ["jcardinal", "mhammontree", "dfranks"]
9
+ updated: 2026-07-09
10
+ owners: ["jcardinal", "mhammontree", "dfranks", "apeterson"]
11
11
  files:
12
12
  - api2/Component/Api/V2/V2.php
13
13
  - _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php
@@ -156,9 +156,20 @@ returnTrackingNumber: {...} }]`, and an IFIU's as `itemFulfillmentItemUnitTracki
156
156
  (`Client_Nychh/2026-06-19b - ...`, all of 317-322) so far. Each new client is whack-a-mole until
157
157
  the chain is folded back into the base migration + blank-client template.
158
158
 
159
+ - **`Client_CompassCanada` is missing these bridge tables on *beta* (local drift).** Beta's
160
+ `Client_CompassCanada` lacks 17 tables that prod has — including the `*_TrackingNumbers`
161
+ bridges and `AdvanceShippingNoticeItemUnits` — so any local DB reset **from beta** reintroduces
162
+ the drift and a SalesOrders record load 500s with **1146 "table doesn't exist"** (the
163
+ `_trackingNumbers` computed field joins the bridges). Fix locally by re-running
164
+ `toga25-supply/sync_compasscanada_schema.sql` against `Client_CompassCanada` (local-only — prod
165
+ already has the tables). See the
166
+ [local-DB-refresh-from-beta workflow](../workflows/local-db-refresh-from-beta.md).
159
167
  - **Porting the item-fulfillment TableView fix to another client is two independent decisions, not a copy-paste.** The **re-root** (Units 31 → ItemFulfillmentItems 29 + OUTER unit chain) is universally portable and fixes the "0 records" bug everywhere. The **tracking source is client-specific**: Compass writes one tracking number per item fulfillment at the **item level (318)**, so its views read 318. Other clients populate different bridge levels — verify with `SELECT COUNT(*)` per bridge before choosing. As of 2026-06-19, **record 318 is empty in `Client_Nychh` and `Client_Quad`**; their tracking lives at the **IF/shipment level (317)** (covers IFIs: NYCHH 7955/10049 ≈ 79%, Quad 4878/4967 ≈ 98%) and the **unit level (319)** (≈ 7–9% — serialized only). Copying Compass's 318 join into a client that doesn't write 318 yields a structurally-correct view with permanently blank tracking until 318 is backfilled. (NYCHH's pre-fix view pointed at the now-deleted record 41 = old IF-level/package bridge, i.e. it originally intended IF-level 317.)
160
168
 
161
169
  ## Change history
170
+ - 2026-07-09 — Noted that `Client_CompassCanada` is missing these bridge tables on **beta**, so a local
171
+ reset from beta reintroduces the 17-table drift (1146 on SalesOrders load); fix locally with
172
+ `sync_compasscanada_schema.sql`. Cross-linked the new local-DB-refresh-from-beta workflow. (apeterson)
162
173
  - 2026-06-19 — **NYCHH** hit the bridge ACL gap in prod: 403 EZ-1 on `item-fulfillment-tracking-numbers` (DEBUG "No ACL Logic Groups defined", aclRecordPermissionId 318 = record 317, roleId 1, appId NULL). Confirmed all 6 bridge perms (ids 318-323, records 317-322) had 0 logic groups; added the chain via `Client_Nychh/2026-06-19b - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql` (all 6 bridges, idempotent anti-joins, RANDOM_BYTES uuids, slug='all'/sqlExpression='1', record ids derived from AclRecordPermissions). Same fix pattern as Quad 2026-06-18a / Prudential 2026-06-15. (jcardinal)
163
174
  - 2026-06-19 — Applied the Compass item-fulfillment TableView fix to **NYCHH** and **Quad** (`Client_Nychh`/`Client_Quad` `2026-06-19a - FixItemFulfillmentTableViewTrackingAndRoot.sql`): re-rooted views 12 & 13 at ItemFulfillmentItems, item-level tracking via 318, preserving Quad's three Units-level custom columns. Confirmed read-only that record 318 is empty for both clients (tracking blank until backfilled) — their data is at 317 (IF-level, ~79%/~98% coverage) and 319 (unit-level); recorded the portability gotcha. (jcardinal)
164
175
  - 2026-06-18 — Quad's NetSuite TOGa Supply sync (`sync_togasupply_quad.php`) hit the bridge ACL gap in prod: 403 EZ-1 on `item-fulfillment-tracking-numbers` (Sentry 7559037554, 46×, since the 2026-06-15 deploy). Confirmed `Client_Quad` perms 380-385 (recs 317-322, role 1) had 0 logic groups; added the chain via `Client_Quad/2026-06-18a - ItemFulfillmentItemReceiptTrackingNumberAclLogicGroups.sql` (all 6 bridges, idempotent, RANDOM_BYTES uuids). Noted the gap surfaces via the per-client sync, not only UI reads. (dfranks)
@@ -0,0 +1,103 @@
1
+ ---
2
+ title: Refreshing a Local Dev Database from Beta (dev-sandbox)
3
+ framework: "2.0"
4
+ repo: _underscore
5
+ project: _Underscore
6
+ client: shared
7
+ type: workflow
8
+ status: active
9
+ updated: 2026-07-09
10
+ owners: ["apeterson"]
11
+ files:
12
+ - api2/Config/
13
+ - _underscore/Loader.php
14
+ - _underscore/Model/Client/BundleTranslation.php
15
+ - api2/Component/Api/V2/V2.php
16
+ - toga25-supply/sync_compasscanada_schema.sql
17
+ related:
18
+ - ../features/per-client-database-connections.md
19
+ - ../features/tracking-number-bridges.md
20
+ ---
21
+
22
+ ## Summary
23
+
24
+ How to reset a local 2.0 dev database from the **beta / dev-sandbox** environment: dump each
25
+ schema (`Core`, `Client_<Id>`, `Logs_<Id>`, …) from the beta host, drop+recreate the local
26
+ schema, and re-import. This is the "local-DB refresh" the
27
+ [per-client DB connections](../features/per-client-database-connections.md) doc points at. The
28
+ procedure is routine, but the **beta sandbox user is a managed account without `SUPER`/`RELOAD`**,
29
+ so the naive `mysqldump` invocation fails — and a reset pulls Core state that can leave the local
30
+ API broken until two known side-effects are fixed (see Gotchas).
31
+
32
+ Connection endpoints (beta host, port, schema names) live in **api2 `Config/*.ini`** under the
33
+ `[database]` blocks. Read them there — **never record credential values in knowledge or commits.**
34
+
35
+ ## Steps
36
+
37
+ Order matters — dump first so a failed dump never wipes a local schema it can't refill.
38
+
39
+ 1. **Get on the company VPN.** The beta DB host (`dev.sandbox.database.togahub.com`) is
40
+ firewalled — reachable **only** on the VPN. Off-VPN a direct connect just times out (it is not
41
+ an auth error), which is the usual first red herring.
42
+ 2. **Per schema, dump → drop → recreate → import**, looping over the schemas you need
43
+ (`Core`, `Client_<Id>`, and any `Logs_<Id>`/`Archive_<Id>` you run locally):
44
+ ```bash
45
+ for DB in Core Client_Compass Client_CompassCanada Client_Quad Client_Nychh; do
46
+ mysqldump -h dev.sandbox.database.togahub.com -u admin -p<pw> \
47
+ --skip-lock-tables --no-tablespaces --set-gtid-purged=OFF \
48
+ --routines --triggers "$DB" > "/tmp/$DB.sql" || break
49
+ mysql -u root -e "DROP DATABASE IF EXISTS \`$DB\`; CREATE DATABASE \`$DB\`;"
50
+ mysql -u root "$DB" < "/tmp/$DB.sql"
51
+ done
52
+ ```
53
+ The `|| break` is load-bearing: if the dump fails, stop before the `DROP` so you never destroy
54
+ a local schema you cannot refill.
55
+ 3. **Bring the local `_underscore` checkout up to the branch beta was built from** (see the
56
+ missing-model gotcha) and **re-apply local-only client schema fixes** (see the CompassCanada
57
+ drift gotcha).
58
+ 4. **Smoke-test** one API request per refreshed client before relying on the reset.
59
+
60
+ ## Gotchas / known issues
61
+
62
+ - **Beta `admin` lacks `RELOAD` → `--single-transaction` fails.** The managed sandbox account
63
+ cannot `FLUSH TABLES WITH READ LOCK`, so the default `mysqldump --single-transaction` dies with
64
+ `Couldn't execute 'FLUSH TABLES WITH READ LOCK': Access denied ... (1045)`. **Fix:** drop
65
+ `--single-transaction` and take a **non-locking** dump instead:
66
+ `--skip-lock-tables --no-tablespaces --set-gtid-purged=OFF --routines --triggers`. (Add
67
+ `--column-statistics=0` if your client's mysqldump is newer than the server.)
68
+ - **A reset can 500 *every* request with a missing `_Model_Client_*` autoload.** Beta's `Core`
69
+ registers models in `Core.Records`/`RecordFields`, and `api2/Component/Api/V2/V2.php`
70
+ (`processRoutePairs`, ~line 3454) iterates **every** registered model and dereferences its
71
+ `::TABLE`. If beta registers a model whose PHP class is **newer than your local `_underscore`
72
+ checkout**, the `_underscore/Loader.php` autoloader throws
73
+ `Could not find required file for '_Model_Client_BundleTranslation'` and the whole API 500s.
74
+ Models are **hand-written committed source** (no generator, no cache), so the fix is a **git
75
+ pull of the missing file**, not a cache clear — e.g. bring
76
+ `_underscore/Model/Client/BundleTranslation.php` in from branch `TRUE-80065`
77
+ (commit `ef6ebd80`). General rule: after a beta reset, sync `_underscore` to (at least) the
78
+ branch beta was built from.
79
+ - **Resetting `Client_CompassCanada` reintroduces the 17-table schema drift.** CompassCanada on
80
+ **beta** is missing 17 tables that **prod** has (`AdvanceShippingNoticeItemUnits`, the
81
+ `*_TrackingNumbers` bridges, TransferOrder link tables, `Customers_Catalogs`), so a reset wipes
82
+ the prior local fix and a SalesOrders record load 500s with **1146 "table doesn't exist"** (the
83
+ `_trackingNumbers` computed field joins those tables). **Fix:** re-run
84
+ `toga25-supply/sync_compasscanada_schema.sql` against `Client_CompassCanada` (17 ×
85
+ `CREATE TABLE IF NOT EXISTS`). **Local-only — do NOT replay to beta/prod** (prod already has
86
+ them). **Operator trap:** the file uses **unqualified** table names, so you must have
87
+ `Client_CompassCanada` selected as the active DB in your client — a standalone `USE` line run
88
+ as a separate statement does **not** carry over, and the tables land in the wrong schema. See
89
+ [tracking-number-bridges](../features/tracking-number-bridges.md) for the bridge tables.
90
+ - **The logs-DB write trap still applies.** A reset only refreshes the schemas you loop over; if
91
+ you skip `Logs_<Id>` the first request 500s (`Unknown database 'logs_<id>'`) on the logging
92
+ write. See [per-client DB connections](../features/per-client-database-connections.md).
93
+ - **Committed dbchanges2 seeds usually survive a reset.** Beta already carries the committed
94
+ `Core` change-sets (e.g. the Surface-layer seeds), so a later replay of *committed* changes is
95
+ largely a no-op. Only ad-hoc changes that were never committed to dbchanges2 need re-applying
96
+ after a reset.
97
+
98
+ ## Change history
99
+
100
+ - 2026-07-09 — Initial capture: non-locking `mysqldump` recipe (beta `admin` lacks `RELOAD`), the
101
+ VPN-only beta host, and the two recurring post-reset side-effects — a missing `_Model_Client_*`
102
+ autoload 500 (pull the model file, no cache) and the CompassCanada 17-table drift
103
+ (`sync_compasscanada_schema.sql`, local-only). (apeterson)
@@ -17,7 +17,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
17
17
 
18
18
  ## 2.0 framework
19
19
 
20
- - **_underscore** (_Underscore) _(framework core)_ — 27 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
20
+ - **_underscore** (_Underscore) _(framework core)_ — 28 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
21
21
  - **worker2** (Worker) — 27 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
22
22
  - **api2** (API) — 10 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
23
23
  - **dbchanges2** (Database Changes) _(framework core)_ — 3 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
@@ -5,13 +5,14 @@ apps:
5
5
  - _underscore
6
6
  - api2
7
7
  - toga2-supply
8
+ - toga25-supply
8
9
  - dbchanges2
9
10
  project: _Underscore
10
11
  client: nychh
11
12
  type: profile
12
13
  status: active
13
- updated: 2026-06-19
14
- owners: ["jcardinal"]
14
+ updated: 2026-07-09
15
+ owners: ["jcardinal", "apeterson"]
15
16
  files: []
16
17
  related:
17
18
  - ../../2.0/apps/_underscore/features/tracking-number-bridges.md
@@ -0,0 +1,64 @@
1
+ ---
2
+ type: session
3
+ slug: true-80100-mso-create-fix
4
+ title: Fix errors creating a manual managed service order (togadesk)
5
+ author: mhammontree
6
+ repos: [togadesk]
7
+ framework: "1.0"
8
+ client: shared
9
+ status: active
10
+ created: 2026-07-09
11
+ updated: 2026-07-09
12
+ ---
13
+
14
+ # Session: true-80100-mso-create-fix
15
+ **Date:** 2026-07-09
16
+ **Project/Repo:** togadesk (1.0)
17
+ **Task:** Fix TRUE-80100 — errors creating a manual managed service order (MSO) in togadesk; reported against the Northwell Health client but the defects are general to the shared MSO create flow.
18
+
19
+ ---
20
+
21
+ ## What WORKED
22
+ <!-- Include specific file paths and evidence -->
23
+ - **Server crash fix** — `desk/includes/controllers/actions/tickets/add.php:353-354`: changed `App_Page::getVar('installation')` and `getVar('access-instructions')` to `App_Page::getVarIfSet(...)`. Root cause: `App_Page::getVar()` (library/app/page.php:354) THROWS `Exception("Variable 'X' does not exist in the request headers.")` when the var is absent; the manual MSO form omits `installation`, so the onsite-service (TYPE_ONSITESERVICE) branch crashed. `getVarIfSet()` (page.php:382) returns null instead. Evidence: matched the original Sentry trace (getVar → add.php:353 → require chain); after fix, **Test 1** (user WITH an address) created the MSO successfully with no exception.
24
+ - **Submit-validation deadlock fix** — `desk/template/modals/tickets/addNew.php` submit handler (~line 3284): validator now reads `newAddressCount = parseInt($('#newAddressCount').val())||0` and only blocks when `selectedValue==0 && newAddressCount==0`. Root cause: an existing End User with no saved address got an empty `#userlocation` dropdown + an auto-opened inline add-address form, but the validator required a non-zero dropdown pick and ignored the inline address — unresolvable deadlock. Evidence: **Test 2** (user with NO address → filled inline add-address form) created the MSO successfully.
25
+ - **Chrome autofill hardening** — added `autocomplete` attributes: `autocomplete="off"` on `#formModal` (`desk/template/footer.php:9`); `autocomplete="new-password"` on `#new-user-password`; `autocomplete="off"` on the new-user fields, new-address fields (address1/2, city, state, zip), Summary (`#subject`), and the select2 dropdowns (`#enduser`, `#userlocation`, `#location`) in `addNew.php`. Root cause: the password field made Chrome autofill Summary/address fields (blue highlight) without firing change/input events or syncing select2, so validation saw empty values. Defensive — cannot regress the create flow. Not independently re-tested (users filled fields manually in both tests).
26
+ - **Address data model confirmed** — the End User Address dropdown is sourced per-person from `people_addresses INNER JOIN addresses ON addresses.id = people_addresses.addressid WHERE people_addresses.peopleid = <uid>` (`desk/template/pages/getinfo.php:152-171`, db_togadesk / TOGaDeskSupport). Confirmed live: a user WITH a `people_addresses` row populates the dropdown and selects fine. Empty dropdown = that person has no `people_addresses` row (legitimate data state), not a bug.
27
+ - **Knowledge captured & pushed** — `/capture` published to `_main`: new feature doc `1.0/apps/togadesk/features/managed-service-order-create.md` and an elevated update to `1.0/standards/backend-php.md` (getVar-throws rule). validate OK (28 repos), index 233 docs.
28
+ - **Code pushed** — all three fixes committed and pushed to branch `TRUE-80100` in the togadesk repo; local togadesk is checked out on `TRUE-80100`.
29
+
30
+ ## What did NOT work — DO NOT RETRY THESE
31
+ <!-- Exact failure reasons — do not vague-ify -->
32
+ - **Do NOT restore the commented-out `locations` UNION in getinfo.php** (getinfo.php:95-148) as a "fix" for the empty End User Address dropdown. The empty dropdown is NOT a regression: git blame shows the per-person-only query dates to the 2021-12-06 schema migration `repair_order_addresses/primaryaddress` → `addresses/isprimary` (commit bf1abaa06, Jeff). Client/site addresses intentionally live in the `locations` table and are reached via the modal's "Select either End User or Client Location" toggle (`#checkbox` → `#servicelocation`/`#location`), enabled once a Contract is chosen. Empty per-person dropdown is expected; inline add-address is the designed fallback.
33
+ - **Do NOT fix only add.php:353 and leave :354.** Line 354 (`access-instructions`) is the identical unguarded `getVar` on the next line and would throw immediately after 353 is fixed — both must use `getVarIfSet`.
34
+
35
+ ## Not tried yet (candidates for next session)
36
+ - Independently verify the autofill fix in an incognito Chrome window (both create tests were done with manual field entry, so fix #2 was never actually exercised against live autofill).
37
+ - Optional pre-merge hygiene: `php -l` on the 3 changed files and a `php-reviewer` pass (never run this session).
38
+ - Sweep the rest of the MSO create block in add.php for OTHER unconditional `getVar()` reads that could throw the same way (departmentid, priority, deliveryc, warrentyStartDate, deviceAge, etc.) — deferred per developer ("just the reported crash"). Only revisit if a NEXT-field crash surfaces.
39
+ - PR review/merge of branch `TRUE-80100` (not started).
40
+
41
+ ## Current file state
42
+ | File | Status | Notes |
43
+ |------|--------|-------|
44
+ | desk/includes/controllers/actions/tickets/add.php | Modified, committed on TRUE-80100 | Lines 353-354 `getVar`→`getVarIfSet` |
45
+ | desk/template/footer.php | Modified, committed on TRUE-80100 | `autocomplete="off"` on `#formModal` (line 9) |
46
+ | desk/template/modals/tickets/addNew.php | Modified, committed on TRUE-80100 | Validator deadlock fix (~3284) + `autocomplete` attrs on new-user/new-address/Summary/select2 fields |
47
+ | desk/template/pages/getinfo.php | Read-only (no change) | Investigated only — confirmed per-person address query is correct/by-design |
48
+ | knowledge/1.0/apps/togadesk/features/managed-service-order-create.md | Created, pushed to _main | New feature doc (MSO create flow + 3 fix gotchas) |
49
+ | knowledge/1.0/standards/backend-php.md | Modified, pushed to _main | Added getVar-throws rule (elevated, approved) |
50
+
51
+ ## Decisions made
52
+ - **Guard the read in add.php rather than fix the form to always post `installation`** (developer choice). Rationale: immediate, minimal, matches the surrounding guarded pattern; `location` becomes null when absent, which is acceptable for onsite-service. Rejected: form-side fix (larger surface) and "both".
53
+ - **Empty End User Address dropdown is by-design, not a code bug.** Rationale: confirmed via git blame (2021 per-person migration) + live test (a user with an address works); client locations are a separate intentional path via the toggle. Rejected: restoring the `locations` UNION.
54
+ - **Promote the getVar-throws rule to the elevated 1.0 backend-php standard** (developer approved). Rationale: `getVar` throwing vs `getVarIfSet` returning null is App_-framework-wide, not togadesk-specific; it's a recurring 1.0 crash class.
55
+ - **No client doc for Northwell.** Rationale: Northwell was only the reporting client; the defects and knowledge are shared/internal to the togadesk MSO flow.
56
+
57
+ ## Blockers
58
+ none — all three fixes verified for the two create paths and pushed; knowledge published.
59
+
60
+ ## Exact next step
61
+ > This task is essentially complete. If anything remains: open branch `TRUE-80100` for PR review/merge, and optionally verify the autofill fix (#2) in an incognito Chrome window since both create tests used manual field entry (autofill was never exercised).
62
+
63
+ ---
64
+ _Saved by /session-save on 2026-07-09_
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.303",
3
+ "version": "1.0.305",
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",