toga-ai 1.0.606 → 1.0.608
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/test/INDEX.md +1 -0
- package/knowledge/1.0/apps/test/features/compass-retrofix2-sql-generator.md +102 -0
- package/knowledge/INDEX.md +1 -1
- package/knowledge/clients/compass-usa/workflows/order-lifecycle-and-data-integrity.md +41 -7
- package/knowledge/sessions/2026-08-18-table-cell-actions-surface-apeterson.md +61 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
| [Test (test) Architecture](architecture.md) | `test` (project **Test**) is a **repository of ad-hoc developer scripts** — not a deployed application. | test/team/ |
|
|
6
6
|
| [2.0 Deployment — Per-Client SQL Generator](features/2-0-deployment-client-sql.md) | `team/2.0 deployment/generate_client_sql.php` fans a single SQL change-set out across **all 2.0 client databases**. | test/team/2.0 deployment/generate_client_sql.php, test/team/2.0 deployment/Clients_Db.txt, test/team/2.0 deployment/Client.sql |
|
|
7
7
|
| [Active Directory Authentication Test](features/active-directory-auth-test.md) | `team/active_directory_authentication_test.php` is an interactive CLI tool to test **Active Directory authentication**. | test/team/active_directory_authentication_test.php |
|
|
8
|
+
| [Compass retrofix2 — Retroactive Data-Fix SQL Generator](features/compass-retrofix2-sql-generator.md) | `@jeff/compass/retrofix2.php` is a standalone **1.0 `App_`** script that retroactively repairs historical Compass USA (`Client_Compass`, 2.0) order data left in | test/@jeff/compass/retrofix2.php |
|
|
8
9
|
| [Create Elastic Beanstalk Environment (script)](features/create-elastic-beanstalk.md) | `team/aws/create_elastic_beanstalk.php` is a **standalone** (no `App_` framework) constants-driven PHP generator. | test/team/aws/create_elastic_beanstalk.php |
|
|
9
10
|
| [Developer Generators (password, UUID)](features/dev-generators.md) | Two tiny **1.0 `App_` framework** convenience scripts for everyday developer needs. | test/team/generate_password.php, test/team/uuid.php |
|
|
10
11
|
| [Forecast vs NetSuite Discrepancy Analysis](features/forecast-netsuite-discrepancy-analysis.md) | `team/forecast-netsuite/discrepancy_analysis.php` detects discrepancies between our **Forecast database** and **NetSuite** (the source of truth for all sales da | test/team/forecast-netsuite/discrepancy_analysis.php |
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Compass retrofix2 — Retroactive Data-Fix SQL Generator
|
|
3
|
+
framework: "1.0"
|
|
4
|
+
repo: test
|
|
5
|
+
project: Test
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-08-18
|
|
10
|
+
owners: [jcardinal]
|
|
11
|
+
files:
|
|
12
|
+
- test/@jeff/compass/retrofix2.php
|
|
13
|
+
related:
|
|
14
|
+
- ../architecture.md
|
|
15
|
+
- ../../../clients/compass-usa/workflows/order-lifecycle-and-data-integrity.md
|
|
16
|
+
- ../../../clients/compass-usa/features/mits-po-to-so-item-linking.md
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Summary
|
|
20
|
+
|
|
21
|
+
`@jeff/compass/retrofix2.php` is a standalone **1.0 `App_`** script that retroactively repairs
|
|
22
|
+
historical Compass USA (`Client_Compass`, 2.0) order data left in the wrong shape by 50+ past bugs.
|
|
23
|
+
It **emits review-first `.sql`** — it never writes the DB directly. It supersedes the older sibling
|
|
24
|
+
`retrofix.php` in the same folder (that one is superseded/kept only for reference). The domain facts
|
|
25
|
+
it repairs against (the supply chain, item-link bridges, both fulfillment flows, over-fulfill cap)
|
|
26
|
+
live in the Compass
|
|
27
|
+
[order-lifecycle & data-integrity workflow](../../../clients/compass-usa/workflows/order-lifecycle-and-data-integrity.md);
|
|
28
|
+
this doc covers the **script's structure**.
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
`processOrder()` runs three phases per Compass SO, newest-first. **Phase ordering is load-bearing:
|
|
33
|
+
Phase 0 must run before Phase 1/2** because units are **shared up the chain** (the same `Units.id`
|
|
34
|
+
at every level), so unit corrections must land before Phase 2 mirrors fulfillments upward.
|
|
35
|
+
|
|
36
|
+
### Phase 0 — CG-unit asset-tag merge (new)
|
|
37
|
+
Reproduces retroactively what the forward fix does at `library/app/api/toga2.php` (~lines 3688–3965):
|
|
38
|
+
NetSuite delivers asset tags on **separate service-item lines** whose part number contains
|
|
39
|
+
`ASSETTAG` (e.g. `ODP-COMPASS-ASSETTAG1`); older Compass imports landed each asset tag as its **own
|
|
40
|
+
`Units` row** whose `serialNumber` holds the CG value (e.g. `CG2000027730`), attached via
|
|
41
|
+
`ItemFulfillmentItemUnits` alongside the real serialized unit on the same fulfillment. Phase 0 folds
|
|
42
|
+
each duplicate CG unit into its real device.
|
|
43
|
+
|
|
44
|
+
Per fulfillment, order the IFIU-attached units by `ItemFulfillmentItemUnits.id` and split into CG
|
|
45
|
+
(serial starts `CG`) vs real (non-CG serialized), then:
|
|
46
|
+
- **1:1** → merge (≈17,500 fulfillments).
|
|
47
|
+
- **equal N:N** → order-pair and emit a `REVIEW` comment (≈7).
|
|
48
|
+
- **unequal, or zero real units** → logged and skipped (≈184).
|
|
49
|
+
|
|
50
|
+
Each merge emits, in order:
|
|
51
|
+
1. `UPDATE Units SET assetTag = <CG serial>` on the real unit — **only if empty; never clobbers a
|
|
52
|
+
different existing tag**.
|
|
53
|
+
2. Repoint `InventoryAdjustmentItemUnits.unitId` CG→real (decided: **repoint, not delete**, to
|
|
54
|
+
preserve stock history — 14,249 CG units have inventory-adjustment rows).
|
|
55
|
+
3. Delete the CG unit's `ItemFulfillmentItemUnits` rows (and their `..._TrackingNumbers` bridges).
|
|
56
|
+
4. `DELETE` the CG unit.
|
|
57
|
+
|
|
58
|
+
Scope: **IFIU-attached CG units only** (per developer). DB facts at time of build: 22,288 total
|
|
59
|
+
CG-serial units, none with `assetTag` set; 19,214 attached to an IFIU.
|
|
60
|
+
|
|
61
|
+
### Phase 1 — header/link/bridge repairs (levels L1–L4)
|
|
62
|
+
Repairs the supply-chain header chain and the item-link bridges. Levels:
|
|
63
|
+
- **L1** `repairOdpPoToAgilantSoLinks` — **always calls NetSuite** (`buildNetsuiteGroupMap`), even
|
|
64
|
+
when the L1 links already exist.
|
|
65
|
+
- **L2/L3/L4** — NetSuite-free bridge repairs. **L3** repairs the
|
|
66
|
+
`PurchaseOrderItems_SalesOrderItems` rung (MITS PO item → ODP SO item) that the Flow-B recursive
|
|
67
|
+
IF mirror depends on.
|
|
68
|
+
|
|
69
|
+
### Phase 2 — fulfillment mirror climb
|
|
70
|
+
Walks each source ItemFulfillment up the chain (Agilant → ODP → Compass), creating the mirror IFs.
|
|
71
|
+
|
|
72
|
+
## Level isolation — `runLevel()`
|
|
73
|
+
|
|
74
|
+
Originally Phase 1 ran L1→L4 with **no isolation**. Because L1 unconditionally calls NetSuite, a
|
|
75
|
+
NetSuite SSL/SOAP failure there threw, `main()`'s catch marked the **whole order FAILED**, and the
|
|
76
|
+
independent NetSuite-free L2/L3/L4 repairs (including the L3 rung Phase 2 needs) were skipped — even
|
|
77
|
+
though L1 usually had nothing to insert (the affected orders' Agilant SOIs were already fully linked,
|
|
78
|
+
so the NetSuite call was pure overhead/risk).
|
|
79
|
+
|
|
80
|
+
`runLevel()` wraps each Phase-1 level (and each Phase-2 source-IF climb) so **a level's exception is
|
|
81
|
+
logged as a skip and swallowed**, letting the remaining independent levels still emit. This is the
|
|
82
|
+
core reliability fix: independent repairs no longer share a failure fate with L1's external call.
|
|
83
|
+
|
|
84
|
+
## Write guards — `emit()` vs `emitUnit()`
|
|
85
|
+
|
|
86
|
+
- `emit()` — the default SQL sink; **hard-blocks any write to the `Units` and `TrackingNumbers`
|
|
87
|
+
tables**.
|
|
88
|
+
- `emitUnit()` — a narrow helper for the Phase-0 units track that **permits `Units` UPDATE/DELETE
|
|
89
|
+
but still blocks `TrackingNumbers`**. This is a deliberate, scoped exemption to the
|
|
90
|
+
never-write-`Units` guard, used only by Phase 0.
|
|
91
|
+
|
|
92
|
+
Never emit writes to `TrackingNumbers`; existing tracking rows are only ever linked, never created
|
|
93
|
+
(consistent with the Compass workflow invariants).
|
|
94
|
+
|
|
95
|
+
## Change history
|
|
96
|
+
- 2026-08-18 — Initial doc. Recorded retrofix2.php's Phase 0/1/2 structure, the new **Phase 0
|
|
97
|
+
CG-unit asset-tag merge** (merge/order-pair/skip cases, the 4 emitted statements, repoint-not-delete
|
|
98
|
+
for inventory history), the **`runLevel()` level isolation** fix (L1's unconditional NetSuite call
|
|
99
|
+
no longer fails the whole order and skips the L2/L3/L4 bridge repairs), and the scoped **`emitUnit()`**
|
|
100
|
+
exemption to the never-write-Units guard. (jcardinal)
|
|
101
|
+
</content>
|
|
102
|
+
</invoke>
|
package/knowledge/INDEX.md
CHANGED
|
@@ -12,7 +12,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
12
12
|
- **togaview** (TOGa View) — 7 doc(s) → [1.0/apps/togaview/INDEX.md](1.0/apps/togaview/INDEX.md)
|
|
13
13
|
- **webhook** (Webhook) — 1 doc(s) → [1.0/apps/webhook/INDEX.md](1.0/apps/webhook/INDEX.md)
|
|
14
14
|
- **walmarttechservices** (Walmart Tech Services) — 1 doc(s) → [1.0/apps/walmarttechservices/INDEX.md](1.0/apps/walmarttechservices/INDEX.md)
|
|
15
|
-
- **test** (Test) —
|
|
15
|
+
- **test** (Test) — 15 doc(s) → [1.0/apps/test/INDEX.md](1.0/apps/test/INDEX.md)
|
|
16
16
|
- **toga** (TOGa) — 3 doc(s) → [1.0/apps/toga/INDEX.md](1.0/apps/toga/INDEX.md)
|
|
17
17
|
- **tools** (Tools) — 15 doc(s) → [1.0/apps/tools/INDEX.md](1.0/apps/tools/INDEX.md)
|
|
18
18
|
|
|
@@ -5,10 +5,11 @@ project: _Underscore
|
|
|
5
5
|
client: compass-usa
|
|
6
6
|
type: workflow
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-08-
|
|
8
|
+
updated: 2026-08-18
|
|
9
9
|
owners: ["jcardinal", "bala", "dfranks"]
|
|
10
10
|
files: []
|
|
11
11
|
related:
|
|
12
|
+
- 1.0/apps/test/features/compass-retrofix2-sql-generator.md
|
|
12
13
|
- clients/compass-usa/profile.md
|
|
13
14
|
- clients/compass-usa/features/asn-to-item-fulfillment.md
|
|
14
15
|
- clients/compass-usa/features/mits-po-to-so-item-linking.md
|
|
@@ -71,6 +72,27 @@ back-link chain climbs **Agilant → ODP → Compass**. Item back-links use
|
|
|
71
72
|
`ItemFulfillmentItems.upstreamItemFulfillmentItemId` the same direction and may be many-downstream →
|
|
72
73
|
one-upstream for bundles.
|
|
73
74
|
|
|
75
|
+
> **Mirror-gap root cause — a missing item bridge stalls the climb (verified 2026-08-18).** The
|
|
76
|
+
> recursive IF mirror climbs Agilant → ODP → Compass through **BOTH** bridge tables. If the
|
|
77
|
+
> `PurchaseOrderItems_SalesOrderItems` rung linking the Compass/MITS PO item → the ODP SO item is
|
|
78
|
+
> **missing**, the mirror **cannot map past the ODP SO** and never creates the ODP/Compass mirror IFs
|
|
79
|
+
> — the Compass SO shows "nothing fulfilled" even though the Agilant SO has an ItemFulfillment
|
|
80
|
+
> (`c_netsuiteInternalItemFulfillmentId` set, created by NetSuite sync). Orders SA130530, SA130334,
|
|
81
|
+
> SA130430 all had an intact header chain and every other item bridge, but were missing **only** that
|
|
82
|
+
> one rung (confirmed against a healthy order that had it). When diagnosing a Flow-B order that
|
|
83
|
+
> fulfilled upstream but shows empty on Compass, check that specific bridge first.
|
|
84
|
+
|
|
85
|
+
### Asset tags arrive as separate CG "units" (Flow B)
|
|
86
|
+
NetSuite delivers asset tags on **separate service-item lines** whose part number contains
|
|
87
|
+
`ASSETTAG` (e.g. `ODP-COMPASS-ASSETTAG1`). Older Compass imports landed each asset tag as its **own
|
|
88
|
+
`Units` row** whose `serialNumber` holds the CG value (e.g. `CG2000027730`), attached via
|
|
89
|
+
`ItemFulfillmentItemUnits` alongside the real serialized unit on the **same** fulfillment. The
|
|
90
|
+
forward fix (`library/app/api/toga2.php` ~lines 3688–3965) applies those asset tags to the serialized
|
|
91
|
+
items **in order** and sets `Units.assetTag` on the real device. Retroactively this is Phase 0 of the
|
|
92
|
+
[retrofix2 tool](../../../1.0/apps/test/features/compass-retrofix2-sql-generator.md); because units
|
|
93
|
+
are **shared up the chain** (same `Units.id` at every level), the correction must land before the
|
|
94
|
+
fulfillment mirror climbs.
|
|
95
|
+
|
|
74
96
|
## Expected raw-data invariants (for detect-and-repair)
|
|
75
97
|
|
|
76
98
|
1. **Links:** every SOI that should be procured has exactly one PURE bridge to the matching POI on the
|
|
@@ -141,12 +163,18 @@ column is `ON UPDATE CURRENT_TIMESTAMP`), which can look like a fresh modificati
|
|
|
141
163
|
`api2` cXML ShipNotice handler; the `_underscore` recursive item-fulfillment engine.
|
|
142
164
|
|
|
143
165
|
## Retrofix tooling
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
166
|
+
The current repair script is **`test/@jeff/compass/retrofix2.php`** (1.0 `App_`), which
|
|
167
|
+
**supersedes** the older `retrofix.php` sibling in the same folder. Unlike the description below of the
|
|
168
|
+
earlier tool, retrofix2 **emits review-first `.sql`** rather than writing the DB directly. It runs
|
|
169
|
+
three phases newest-first per SO — **Phase 0** (CG-unit asset-tag merge; must run first because units
|
|
170
|
+
are shared up the chain), **Phase 1** (header/link/bridge repairs, levels L1–L4, where L3 fixes the
|
|
171
|
+
`PurchaseOrderItems_SalesOrderItems` rung the mirror needs), **Phase 2** (fulfillment mirror climb).
|
|
172
|
+
Each level is wrapped in `runLevel()` so one level's exception (notably L1's unconditional NetSuite
|
|
173
|
+
call failing) is logged as a skip and swallowed, letting the independent NetSuite-free repairs still
|
|
174
|
+
emit. Write guards: `emit()` hard-blocks `Units` and `TrackingNumbers` writes; the Phase-0-only
|
|
175
|
+
`emitUnit()` permits `Units` UPDATE/DELETE but still blocks `TrackingNumbers`. Full structure in the
|
|
176
|
+
[retrofix2 feature doc](../../../1.0/apps/test/features/compass-retrofix2-sql-generator.md). It is a
|
|
177
|
+
diagnostic/repair tool, not part of the runtime workflow.
|
|
150
178
|
|
|
151
179
|
## Edge cases & escalation
|
|
152
180
|
- Incomplete orders (no PO/ASN/Agilant leg yet) are normal — repair only the layers that exist.
|
|
@@ -155,6 +183,12 @@ runtime workflow.
|
|
|
155
183
|
- High-multiplier over-fulfillment (5×–20×) does not fit the split-PO spurious-link pattern — separate cause.
|
|
156
184
|
|
|
157
185
|
## Change history
|
|
186
|
+
- 2026-08-18 — Recorded the **Flow-B mirror-gap root cause** (a missing `PurchaseOrderItems_SalesOrderItems`
|
|
187
|
+
rung stalls the recursive IF mirror past the ODP SO, so a fulfilled Agilant order shows empty on
|
|
188
|
+
Compass — orders SA130530/SA130334/SA130430), the **CG asset-tag "unit" data shape** (asset tags land
|
|
189
|
+
as their own CG-serial `Units` rows), and repointed the Retrofix tooling section to the new
|
|
190
|
+
**retrofix2.php** (review-first `.sql`; Phase 0/1/2; `runLevel()` level isolation; `emit()`/`emitUnit()`
|
|
191
|
+
write guards). (jcardinal)
|
|
158
192
|
- 2026-08-04 — Added the **"empty shell" order signature** — the ODP importer writes the SO header
|
|
159
193
|
and its items in two separate API requests, so a fatal on the second leaves a committed,
|
|
160
194
|
zero-item order — plus the three orphan sweeps that detect it (zero-item SOs, zero-item POs, ODP
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: session
|
|
3
|
+
slug: table-cell-actions-surface
|
|
4
|
+
title: Table cell/row actions — settle surface-layer design
|
|
5
|
+
author: apeterson
|
|
6
|
+
repos: [dbchanges2, api2, toga25-supply]
|
|
7
|
+
framework: "2.0"
|
|
8
|
+
client: elite
|
|
9
|
+
status: active
|
|
10
|
+
created: 2026-08-18
|
|
11
|
+
updated: 2026-08-18
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Session: table-cell-actions-surface
|
|
15
|
+
**Date:** 2026-08-18
|
|
16
|
+
**Project/Repo:** dbchanges2 / api2 / toga25-supply (2.0)
|
|
17
|
+
**Task:** Recover the settled design for moving table cell/row actions (e.g. Elite's "See units" chevron) into the surface layer so per-client visibility (Elite off, NYCHH on) is a surface override — and clean up the stale first-attempt migration.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What WORKED
|
|
22
|
+
- Located the original design conversation: **api2 session `e761c825-6073-40fc-ab0f-a984bca7f770`** (Aug 13, 2026, `surface-layer` branch). Transcript at `~/.claude/projects/-Applications-XAMPP-xamppfiles-htdocs-api2/e761c825-6073-40fc-ab0f-a984bca7f770.jsonl` (1076 lines, 3.2MB).
|
|
23
|
+
- Extracted the full plan/decision text verbatim via a general-purpose subagent (raw dump saved at `scratchpad/dump.txt` in the api2 session scratchpad). The settled design is captured in this session's Decisions section.
|
|
24
|
+
- Confirmed current on-disk SQL state in `dbchanges2`: **no Phase 1/Phase 3 SQL for the final plan exists yet**; grep for `ROW_ACTIONS` only hit unrelated Core seeds (SalesOrder login surface, PO details row-action menu item 2026-08-18a).
|
|
25
|
+
- **Deleted the stale migration** `dbchanges2/Client_Elite/2026-08-14a - InventoryUnitsByItemsRemoveUnitsDrill.sql` (the rejected drop-the-grouping-level approach). Shows as staged deletion (`D`) in git — NOT yet committed.
|
|
26
|
+
|
|
27
|
+
## What did NOT work — DO NOT RETRY THESE
|
|
28
|
+
These are the mechanisms explicitly rejected in the e761c825 design thread. Do not re-propose them:
|
|
29
|
+
- **Dropping the `inventory_units` grouping level** from Elite's `unitsByItems` CONFIG override (the shipped `2026-08-14a` migration). Reason: destroys the nested-table definition instead of just hiding the button; wrong mechanism. This file was deleted this session.
|
|
30
|
+
- **Per-field `is*` boolean flags** (`isNestedTableEnabled`, `isRowActionEnabled`, `isCellActionEnabled`) on `TableViews`. Reason: wrong grain — a drill/action is not a field capability like isSortable; and it would duplicate the existing `childTableViewId`.
|
|
31
|
+
- **A new dedicated binding table** (`TableViewCellActions` / `TableViewFieldActions`). Reason: label/icon/style/visibility/ACL/per-client overrides is *the surface layer's entire job* — a parallel table duplicates `SurfaceElements` + `SurfaceOverrides`.
|
|
32
|
+
- **Table-meta `actions[]` array with numeric `surfaceElementId` pointers** (the `surfaceElementId: 412` sketch). Reason: superseded once the schema explore found `Surface.type=ROW_ACTIONS` + `Surface.tableViewId` + `SurfaceElement.recordFieldId`/`actionId` already bind everything natively. Also numeric id is wrong key — emitted element key is the `uuid`.
|
|
33
|
+
|
|
34
|
+
## Not tried yet (candidates for next session)
|
|
35
|
+
- **Phase 1 SQL** — seed a `ROW_ACTIONS` surface for `inventory_units` (`Core.Surfaces` `type=ROW_ACTIONS`, `tableViewId=<inventory_units view>`) + a "See units" BUTTON `SurfaceElement` (labelMessageId, `iconToken=chevronsRight`, an `actionId` for a nested-table action, anchored to its column).
|
|
36
|
+
- **Phase 2 FE** — cell-action renderer in `toga25-supply`/`toga-blox`: fetch the table's `ROW_ACTIONS` surface, render each element as a cell action, wire behavior via `actionRegistry` (add nested-table/route/modal handlers), replace hardcoded `makeSeeUnitsColumns`. Injection point: `useGenericTableViewModel.tsx:36-63` meta memo → `actionColumns`.
|
|
37
|
+
- **Phase 3 Elite** — one `SurfaceOverride` row `isVisible=0` on the "See units" element for Elite.
|
|
38
|
+
- **CTO second opinion** — recommended in the original thread, never run.
|
|
39
|
+
- **Verify whether deleted `2026-08-14a` was already applied to sandbox** — if so, DB state still has the drill dropped; may need the Phase work (or an interim revert) to restore.
|
|
40
|
+
|
|
41
|
+
## Current file state
|
|
42
|
+
| File | Status | Notes |
|
|
43
|
+
|------|--------|-------|
|
|
44
|
+
| `dbchanges2/Client_Elite/2026-08-14a - InventoryUnitsByItemsRemoveUnitsDrill.sql` | Deleted (staged, uncommitted) | Rejected drop-the-grouping-level approach; removed per final design |
|
|
45
|
+
| `scratchpad/dump.txt` (api2 session scratchpad) | Created | Raw verbatim extraction of the e761c825 design thread |
|
|
46
|
+
|
|
47
|
+
## Decisions made
|
|
48
|
+
- **Surface layer owns cell/row actions** — not a new table, not FE hardcoding. The button (label, icon, style, visibility, enablement, ACL, per-client/role/persona overrides) is a `SurfaceElement` on a `type=ROW_ACTIONS` Surface linked to the table via `Surface.tableViewId`. Rationale: the surface layer already models all of this; a parallel mechanism duplicates it. Vindicates the original "this is surface-layer" instinct — only earlier mechanisms were wrong.
|
|
49
|
+
- **Grain rule:** table-level toggles → table block; per-cell action presentation → surface element bound to a field (`recordFieldId`/`customRecordFieldId`). Cell action (chevron) and row action (row-click → modal) are conceptually independent (today wrongly coupled at `GenericNestedTables.tsx:37-42`).
|
|
50
|
+
- **Elite vs NYCHH gating** = one `SurfaceOverride` `isVisible=0` on the "See units" element scoped to Elite; element stays visible for NYCHH/others on the same shared table.
|
|
51
|
+
- **Cross-DB binding** (Core surface ↔ Client table view) uses **soft integer FKs** — framework FK traversal can't cross Core↔Client. Stable FE-facing key is the SurfaceElement **uuid**, not numeric id. CONFIG override REPLACES (does not merge).
|
|
52
|
+
- **Two open questions to settle before seeding:** (1) how FE finds a table's ROW_ACTIONS surface — lean **slug convention** `<tableViewSlug>-row-actions` over `tableViewId` query; (2) how element anchors to a column — lean **column-slug in element `config`** over `recordFieldId`.
|
|
53
|
+
|
|
54
|
+
## Blockers
|
|
55
|
+
- None hard. Soft: the two open questions above should be settled before writing Phase 1 SQL; and confirm whether `2026-08-14a` was already applied to sandbox before assuming Elite DB is clean.
|
|
56
|
+
|
|
57
|
+
## Exact next step
|
|
58
|
+
> Settle the two open questions (slug-convention lookup + column-slug-in-config anchor), then write **Phase 1 SQL**: a `Core/` migration seeding the `inventory_units` `ROW_ACTIONS` surface + "See units" BUTTON `SurfaceElement`. Check first whether deleted `2026-08-14a` was applied to sandbox.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
_Saved by /session-save on 2026-08-18_
|
package/package.json
CHANGED