toga-ai 1.0.546 → 1.0.548
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/2.0/apps/_underscore/INDEX.md +1 -1
- package/knowledge/2.0/apps/_underscore/features/component-model-namespace-registration.md +14 -2
- package/knowledge/2.0/apps/worker2/features/oneuptime-incident-clickup-sync.md +1 -0
- package/knowledge/sessions/2026-08-10-elite-supply-fe-tcox.md +35 -44
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| [Carrier Shipping Labels (UPS/FedEx) & NetSuite Item Fulfillment](features/carrier-shipping-labels.md) | Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracki | _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Client/TrackingNumber.php, _underscore/Model/Client/ItemFulfillments/TrackingNumber.php, _underscore/Component/Library/LabelPdf/LabelPdf.php, _underscore/Component/Library/Carriers/ShipmentRequest/ShipmentRequest.php, _underscore/Component/Library/Carriers/Ups/Ups.php, _underscore/Component/Library/Carriers/Fedex/Fedex.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Trait/Netsuite/SalesOrder.php, _underscore/Component/Library/NetSuite/NetSuite.php, _underscore/Model/Client/TrackingNumber.php, _underscore/Model/Client/ShippingMethod.php, _underscore/Model.php, _underscore/Cloud.php |
|
|
14
14
|
| [Running 2.0 code from a bare CLI script (bootstrap + transactions)](features/cli-script-bootstrap.md) | A throwaway CLI script (a data check, a backfill dry-run, a render harness) that wants the real 2.0 framework — `_Model`, `_Query`, `_Database` — is **not** the | _underscore/Database.php, _underscore/Environment.php, api2/Initialize.php |
|
|
15
15
|
| [_Cloud S3 helpers (copy / get / delete / list)](features/cloud-s3-helpers.md) | `_Cloud` centralizes AWS SDK S3 usage for the 2.0 stack so the `S3Client` never leaks into workers or app code. | _underscore/Cloud.php |
|
|
16
|
-
| [_Component_*/_Model_* project-namespace registration (autoloader) & backslash-qualify traps](features/component-model-namespace-registration.md) | Every **project-local** `_Component_*` and `_Model_*` class in a 2.0 app **must declare the project namespace** at the top of the file: ```php namespace <NAMESP | _underscore/Loader.php, worker2/_.php, api2/_.php, worker2/Component/Forecast/Db/Db.php, worker2/Component/Forecast/SaleImport/SaleImport.php, api2/Component/Api/Netsuite/Netsuite.php, _underscore/Component/Api/Paypal/Paypal.php |
|
|
16
|
+
| [_Component_*/_Model_* project-namespace registration (autoloader) & backslash-qualify traps](features/component-model-namespace-registration.md) | Every **project-local** `_Component_*` and `_Model_*` class in a 2.0 app **must declare the project namespace** at the top of the file: ```php namespace <NAMESP | _underscore/Loader.php, worker2/_.php, api2/_.php, worker2/Component/Forecast/Db/Db.php, worker2/Component/Forecast/SaleImport/SaleImport.php, worker2/Component/Api/Oneuptime/Oneuptime.php, api2/Component/Api/Netsuite/Netsuite.php, _underscore/Component/Api/Paypal/Paypal.php |
|
|
17
17
|
| [_Config group access — the two-argument "optional" form does NOT rescue a missing GROUP](features/config-group-access.md) | `_Config::<group>('<property>')` reads a value out of the active `Config/<ENVIRONMENT>.ini`, and **it throws when the requested group is absent from the ini.** | _underscore/Config.php, _underscore/Component/Api/Paypal/Paypal.php |
|
|
18
18
|
| [Re-pointing a DB alias mid-request (_Database::register park/restore)](features/database-alias-repointing.md) | `_Database` keys **all live per-database runtime state by the connection ALIAS** (`Client` / `_underscore::DB_CLIENT`, `ClientLogs`, `Archive`), **not** by the | _underscore/Database.php, _underscore/Query.php, api2/Component/Api/V2/V2.php, api2/Component/Api/CrossClient/CrossClient.php |
|
|
19
19
|
| [2.0 Email Send Pipeline (queue + Send worker)](features/email-send-pipeline.md) | In 2.0, `_Email::send()` **does not transmit** — it queues the message. | _underscore/Email.php, _underscore/String.php, worker2/Worker/Infrastructure/Email/Send.php |
|
|
@@ -6,14 +6,15 @@ project: _Underscore
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-08-
|
|
10
|
-
owners: [dfranks, mhammontree]
|
|
9
|
+
updated: 2026-08-10
|
|
10
|
+
owners: [dfranks, mhammontree, jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Loader.php
|
|
13
13
|
- worker2/_.php
|
|
14
14
|
- api2/_.php
|
|
15
15
|
- worker2/Component/Forecast/Db/Db.php
|
|
16
16
|
- worker2/Component/Forecast/SaleImport/SaleImport.php
|
|
17
|
+
- worker2/Component/Api/Oneuptime/Oneuptime.php
|
|
17
18
|
- api2/Component/Api/Netsuite/Netsuite.php
|
|
18
19
|
- _underscore/Component/Api/Paypal/Paypal.php
|
|
19
20
|
related:
|
|
@@ -113,8 +114,19 @@ project-local `_Component_*`/`_Model_*` must still declare the project namespace
|
|
|
113
114
|
runtime-only failure.
|
|
114
115
|
- A global-namespace `_Component_*`/`_Model_*` fails **loudly** (the throw above). An
|
|
115
116
|
unqualified `catch (Exception $e)` fails **silently** — the more insidious of the two.
|
|
117
|
+
- **The namespace rule is APP-repo-only.** `_Component_*` classes that live in the
|
|
118
|
+
`_underscore` **core** repo (e.g. `_Component_Api_Togaiq`, `_Component_Api_Clickup`) are
|
|
119
|
+
declared in the **global** namespace and do **not** `extend \_Component`. Do not copy a core
|
|
120
|
+
`_Component_*` as the template for a new worker2/api2 one — copy a *project-local* precedent
|
|
121
|
+
(e.g. `worker2/Component/Forecast/Db/Db.php`, `api2/Component/Api/Netsuite/Netsuite.php`).
|
|
116
122
|
|
|
117
123
|
## Change history
|
|
124
|
+
- 2026-08-10 — Confirmed again in worker2 building `_Component_Api_Oneuptime`
|
|
125
|
+
(`Component/Api/Oneuptime/Oneuptime.php`): the component threw the Loader
|
|
126
|
+
"namespace … has not been defined" fatal until `namespace worker;` + `extends \_Component`
|
|
127
|
+
+ `\`-prefixed framework refs (`\_ApiRequest`, `\_Config`, `\_Query`, `\Exception`, …) were
|
|
128
|
+
applied. Added the app-repo-only clarification — core-repo `_Component_*` (Togaiq, Clickup)
|
|
129
|
+
are global-namespace and don't extend `\_Component`, so they're the wrong template. (jcardinal)
|
|
118
130
|
- 2026-08-04 — TRUE-80282: documented the **file-layout** half of `_Component_*` loading, which
|
|
119
131
|
precedes the namespace rule — `_Loader::autoloader()` (`Loader.php:60-67`) pops the trailing
|
|
120
132
|
`_`-segment and appends it as **both a directory and the filename**, so
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: session
|
|
3
3
|
slug: elite-supply-fe
|
|
4
|
-
title: Elite Service Requests
|
|
4
|
+
title: Elite Service Requests + Inventory FE in toga2-supply — Service Requests VERIFIED end-to-end; remaining: orphan-modal decision, regression pass, PR
|
|
5
5
|
author: tcox
|
|
6
6
|
repos: [toga2-supply]
|
|
7
7
|
framework: "2.0"
|
|
@@ -14,69 +14,60 @@ updated: 2026-08-10
|
|
|
14
14
|
# Session: elite-supply-fe
|
|
15
15
|
**Date:** 2026-08-10
|
|
16
16
|
**Project/Repo:** toga2-supply (2.0)
|
|
17
|
-
**Task:** Elite's full supply2 FE surface — Service Requests page (retitled Orders page on the
|
|
17
|
+
**Task:** Elite's full supply2 FE surface — Service Requests page (retitled Orders page on the backend `service-requests` view) + details modal, plus the previously built Inventory page. Service Requests is now VERIFIED working end-to-end on beta; remaining work is a design decision, the regression pass, and PR mechanics.
|
|
18
18
|
|
|
19
|
-
> Supersedes session `elite-inventory-fe` (2026-08-06).
|
|
19
|
+
> Supersedes session `elite-inventory-fe` (2026-08-06). KB docs for everything durable were captured 2026-08-10 (`/capture`): see `clients/elite/features/supply2-scope.md`, `2.0/apps/toga2-supply/workflows/client-host-scoping.md`, `2.0/apps/_underscore/features/page-meta-context-field-settings.md`, `clients/elite/features/supply2-tableview-config-drift.md`.
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
23
|
## What WORKED
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- `SlideMenu.tsx` ELITE branch: "Service Requests" (link `/`) + Inventory deep-link.
|
|
30
|
-
- `renderModalContent.tsx` untouched — DEFAULT routes ELITE row-clicks to OrderDetailsModal only (verified: no ELITE key, no ApprovalsModal).
|
|
31
|
-
- **Review fixes (CodeRabbit) on Inventory work:** `InventoryPage.tsx` re-seeds `selectedGrouping` when the stored uuid isn't in the resolved host's array (corrupt JSON handled); `InventoryRouter.tsx` redirects `/inventory_items` → `/inventory` for hosts whose default view lacks `subTableParent` (data-driven, no host literal). Both no-ops for NYCHH/Compass/Quad.
|
|
32
|
-
- **`convertConstructorColumnTitles.ts`** null-guarded — a page slug without backend meta degrades to "" labels instead of crashing the table (was the white-screen when `service-requests-listing` didn't exist).
|
|
33
|
-
- **Post-merge diagnostics (2026-08-07 prod→beta refresh rebuilt Client_Elite at 11:55 + beta API redeploy) — root causes found via DB reads:**
|
|
34
|
-
1. Login failure → re-seeded devteam user had an EMPTY password → fixed by hash copy from `Client_Compass.Users` id 127046 (login verified working after).
|
|
35
|
-
2. `service-requests` table view wiped by merge → backend recreated it (ServiceRequests-record view joined to Tickets/Customers/ServiceRequestTypes/SalesOrders with Elite-tailored status CASE).
|
|
36
|
-
3. Service Requests table 500 → OUR `isQuote: false` filter against ServiceRequests → fixed FE-side (above), backend confirmed.
|
|
37
|
-
4. Inventory `/pages/meta?slug=inventory` 500 "Undefined array key 190" → fully diagnosed (see Blockers).
|
|
24
|
+
- **Service Requests verified end-to-end on beta (2026-08-10):** table loads on the `service-requests` view → row click opens the details modal → ServiceRequest→SalesOrder uuid resolution → order details/items/invoices/shipments render. Verified on the one SR with a linked SalesOrder (ticket INC-13982, SR uuid cfc6ea32-dcfa-46c0-bf1b-f40733117a0e).
|
|
25
|
+
- **Modal-not-opening fix:** `renderModalContent.tsx` registry is keyed by **pageTitle** — retitling the page to "Service Requests" silently unhooked the modal (`clientConfig[pageTitle]` → undefined → null). Fixed with an additive `"Service Requests": [{component: OrderDetailsModal}]` key in DEFAULT.
|
|
26
|
+
- **uuid mismatch fix:** rows carry ServiceRequests uuids; detail routes are /sales-orders record routes → `GET /sales-orders/{srUuid}` 404'd. Added `getSalesOrderUuidForServiceRequest()` (OrdersApi.ts: GET /sales-orders + ServiceRequests join + where ServiceRequests.uuid) and threaded `detailsUuid` through `useOrderDetailsViewModel.ts` via a react-query gated `enabled: hostName === "ELITE"` — other hosts bypass entirely.
|
|
27
|
+
- All Service Requests config/slug-threading work from earlier (ELITE BASE.json with pageTitle/tableSlug/listingSlug/hasQuoteFilter/approvals-off; OrdersPage 8-literal slug threading; conditional isQuote; SlideMenu entry) — see superseded session + KB scope doc for detail. tsc clean throughout.
|
|
28
|
+
- Post-merge fixes that held: devteam password restored (hash copy from Client_Compass id 127046); `convertConstructorColumnTitles` null guard; `listingSlug` = `sales-orders-listing` (no service-requests-listing page exists in Core.Pages).
|
|
38
29
|
|
|
39
30
|
## What did NOT work — DO NOT RETRY THESE
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- **
|
|
43
|
-
- **
|
|
44
|
-
-
|
|
31
|
+
- **Retitling a page without adding a matching `renderModalContent` DEFAULT key** — modal silently never opens; registry lookup is `clientConfig[pageTitle]`.
|
|
32
|
+
- **`listingSlug: "service-requests-listing"`** — no such page in `Core.Pages`; null pageMeta crashed the table until the null guard + revert to `sales-orders-listing`.
|
|
33
|
+
- **Fetching order details directly with the row uuid on ELITE** — 404 EV-6; row uuid is the ServiceRequests uuid, not SalesOrders.
|
|
34
|
+
- **Assuming an empty modal means a broken fetch** — 5 of 6 Elite dev-sandbox ServiceRequests have NO linked SalesOrder (only SR id 2 / INC-13982 does); the resolver correctly yields null and the modal is empty by design. Verify against INC-13982 before debugging.
|
|
35
|
+
- **Sending `isQuote` unconditionally** — ServiceRequests has no isQuote column (1054). Config-gated via `hasQuoteFilter: false`.
|
|
36
|
+
- (Carried) `/login` redirect ≠ Domains row; devteam lives in dev-sandbox Client_Compass (127046); MCP env `client-beta` empty — query `dev-sandbox`; beta hand-inserted rows are eaten by prod→beta refreshes.
|
|
45
37
|
|
|
46
38
|
## Not tried yet (candidates for next session)
|
|
47
|
-
- **
|
|
48
|
-
- Inventory nested-expand re-validation
|
|
49
|
-
- Four-client regression pass
|
|
50
|
-
-
|
|
51
|
-
-
|
|
39
|
+
- **Orphan-SR modal state (design decision, then ~minutes of FE):** options are (1) "No sales order linked" empty-state message wired to the resolver's null, (2) SR-level detail view (needs backend routes + design), (3) non-clickable orderless rows. Waiting on backend/product: is an order-less SR a legitimate lifecycle state?
|
|
40
|
+
- Inventory nested-expand re-validation — still blocked on backend TableViewJoins drift fix (dbchanges2 migration; match rows by tableViewId+joinRecordId+joinOnRecordFieldId, ids shifted in the 08-07 re-import) and the Page.php:824 isset() guard for the inventory /pages/meta 500 (KB: page-meta-context-field-settings.md).
|
|
41
|
+
- Four-client regression pass: NYCHH, ENDEAVORHEALTH, COMPASS, COMPASSCANADA inventory + orders in ONE browser session — release blocker per the host-scoping playbook.
|
|
42
|
+
- gitignore `TOGa Supply mockup Elite/` (untracked in repo root) before branching.
|
|
43
|
+
- Branch + PR: tcox branches personally (bare ticket-ID name, ask tcox first). Work sits uncommitted on local `_production`; beta already runs a deployed copy of it.
|
|
52
44
|
|
|
53
45
|
## Current file state
|
|
54
46
|
| File | Status | Notes |
|
|
55
47
|
|------|--------|-------|
|
|
56
|
-
| src/pages/Orders/viewModel/FIELDS/ELITE/BASE.json | new, uncommitted |
|
|
57
|
-
| src/pages/Orders/viewModel/index.ts | modified, uncommitted | BASE_ELITE export |
|
|
58
|
-
| src/pages/Orders/
|
|
59
|
-
| src/pages/Orders/
|
|
48
|
+
| src/pages/Orders/viewModel/FIELDS/ELITE/BASE.json | new, uncommitted | pageTitle/tableSlug/listingSlug(sales-orders-listing)/hasQuoteFilter:false/approvals off/export on |
|
|
49
|
+
| src/pages/Orders/viewModel/index.ts + useOrdersPageViewModel.ts | modified, uncommitted | BASE_ELITE export + ELITE base entry/branch |
|
|
50
|
+
| src/pages/Orders/OrdersPage.tsx | modified, uncommitted | slug threading, fields-driven pageTitle, conditional isQuote, null-safe ACL |
|
|
51
|
+
| src/pages/Orders/api/OrdersApi.ts | modified, uncommitted | getSalesOrderUuidForServiceRequest() resolver |
|
|
52
|
+
| src/pages/Orders/view/OrderView/viewModel/useOrderDetailsViewModel.ts | modified, uncommitted | ELITE-gated uuid resolution; all detail fetches keyed on detailsUuid |
|
|
53
|
+
| src/components/ui/Tables/PrimaryTable/helperFunctions/renderModalContent.tsx | modified, uncommitted | DEFAULT "Service Requests" → OrderDetailsModal |
|
|
60
54
|
| src/components/layout/SlideMenu/SlideMenu.tsx | modified, uncommitted | ELITE: Service Requests + Inventory |
|
|
61
|
-
| src/utils/convertConstructorColumnTitles.ts | modified, uncommitted | null-
|
|
62
|
-
| src/pages/Inventory/**
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
| dev-sandbox Client_Elite.Users | hand-fixed, KEPT | devteam password restored via Compass hash copy |
|
|
55
|
+
| src/utils/convertConstructorColumnTitles.ts | modified, uncommitted | null-safe pageMeta/settings |
|
|
56
|
+
| src/pages/Inventory/** + src/utils/resolveClientHostName.ts (from inventory session) | modified/new, uncommitted | host-scoped statics + CodeRabbit fixes (selectedGrouping re-seed, InventoryRouter subtable guard) |
|
|
57
|
+
| package.json | modified, uncommitted | `npm run elite` |
|
|
58
|
+
| dev-sandbox Client_Elite.Users | hand-fixed, KEPT | devteam password restored 08-10; note: any future prod→beta refresh re-empties it |
|
|
66
59
|
|
|
67
60
|
## Decisions made
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
- Keep devteam seeding + document every hand-fix — the 08-07 merge proved hand-inserted beta rows get eaten; everything must eventually be dbchanges2 migrations.
|
|
61
|
+
- Modal registry fix as an additive DEFAULT pageTitle key (idiomatic to the registry) — rejected refactoring the lookup to a title-independent pageType (shared-code churn).
|
|
62
|
+
- uuid resolution FE-side, host-gated in the detail view model — self-contained, no backend work, other hosts provably bypass (enabled flag + detailsUuid === activeUuid). Rejected: backend exposing SalesOrders.uuid as the drill identifier (still needed an FE change and backend coordination).
|
|
63
|
+
- Orphan-SR modal handling deliberately deferred — mockup doesn't cover the state; it's a product/backend decision first.
|
|
72
64
|
|
|
73
65
|
## Blockers
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
- Details-modal uuid mismatch (suspected, untested) — see Not tried.
|
|
66
|
+
- Backend (all reported + documented in KB): Page.php:824 isset() guard; TableViewJoins drift migration; answer on order-less ServiceRequests lifecycle.
|
|
67
|
+
- None on the Service Requests happy path — verified working.
|
|
77
68
|
|
|
78
69
|
## Exact next step
|
|
79
|
-
>
|
|
70
|
+
> Get the orphan-SR answer from backend/product; implement the chosen modal state (option 1 is a few lines wired to the resolver's null). Then run the four-client regression pass (NYCHH/ENDEAVORHEALTH/COMPASS/COMPASSCANADA, one browser session), gitignore `TOGa Supply mockup Elite/`, and branch for PR (ask tcox for the ticket-ID branch name).
|
|
80
71
|
|
|
81
72
|
---
|
|
82
73
|
_Saved by /session-save on 2026-08-10_
|
package/package.json
CHANGED