toga-ai 1.0.423 → 1.0.425
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.
|
@@ -6,8 +6,8 @@ project: TOGa Blox
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: workflow
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-07-
|
|
10
|
-
owners: [jcardinal]
|
|
9
|
+
updated: 2026-07-23
|
|
10
|
+
owners: [jcardinal, apeterson]
|
|
11
11
|
files:
|
|
12
12
|
- toga-blox/.github/workflows/publish.yml
|
|
13
13
|
- toga-blox/src/utils/getFontAwesomeIcon.tsx
|
|
@@ -35,6 +35,26 @@ resolve in a consuming app's build, or touching `publish.yml`.
|
|
|
35
35
|
- **Every** branch (including `_production`) publishes a **prerelease** version
|
|
36
36
|
`X.Y.Z-<mode>.<run>` under dist-tag `<mode>`. There is no longer a production special case.
|
|
37
37
|
Verified live: `production:1.0.315-production.96`, `sandbox-client:1.0.315-sandbox-client.97`.
|
|
38
|
+
Observed 2026-07-23: `sandbox-client:1.0.317-sandbox-client.101`, `sandbox-dev:1.0.316-sandbox-dev.102`.
|
|
39
|
+
|
|
40
|
+
### Version derivation (CI owns the suffix; dev owns only the base)
|
|
41
|
+
|
|
42
|
+
- CI reads `version` from `package.json`, **strips any `-<suffix>`**, does **`patch + 1`**, then
|
|
43
|
+
appends `-<mode>.<GITHUB_RUN_NUMBER>`. So base `1.0.317` on `_sandbox-client` run 104 publishes
|
|
44
|
+
`1.0.318-sandbox-client.104` under dist-tag `sandbox-client`.
|
|
45
|
+
- **The developer controls only the BASE version** committed in `package.json` on the feature
|
|
46
|
+
branch. **Never hand-write the `-<mode>.N` prerelease suffix** — CI generates it. There is no
|
|
47
|
+
manual `npm publish`; CI is the only publisher.
|
|
48
|
+
|
|
49
|
+
### Deploy procedure (e.g. `_sandbox-client`)
|
|
50
|
+
|
|
51
|
+
1. Ensure a clean tree; optionally bump the base version in `package.json` on the feature branch.
|
|
52
|
+
2. Merge the feature branch into `_sandbox-client`, then push (this triggers the CI publish).
|
|
53
|
+
3. Monitor with `gh run watch`; verify with `npm dist-tag ls @agilant/toga-blox`.
|
|
54
|
+
4. Consuming apps (e.g. `toga25-supply` on `_sandbox-client`) install from the `sandbox-client`
|
|
55
|
+
dist-tag or a pinned `1.0.x-sandbox-client.N` version and must **re-install** to pick up a new
|
|
56
|
+
build. The `deploy-sandbox-client` project skill (`.claude/skills/` in this repo) drives this
|
|
57
|
+
procedure end-to-end.
|
|
38
58
|
|
|
39
59
|
### What was removed (and why it's safe)
|
|
40
60
|
|
|
@@ -66,6 +86,12 @@ environment needs its own maintained `_<mode>` branch in `toga-blox-npm`.
|
|
|
66
86
|
- **Publish before build.** `npm install @agilant/toga-blox@<mode>` fails `ETARGET No matching
|
|
67
87
|
version` in the app build until this repo has published that channel. GitHub Actions runs the
|
|
68
88
|
workflow version *on the pushed branch*, so the branch must carry the current `publish.yml`.
|
|
89
|
+
- **`publish.yml` has diverged across branches (2026-07-23).** The dynamic `_*` wildcard trigger
|
|
90
|
+
lives on `_sandbox-client`, but older/feature branches (e.g. `feature-new-table`) still carry the
|
|
91
|
+
*old* `publish.yml` that triggers only on `_production/_gamma/_beta`. Because Actions runs the
|
|
92
|
+
copy on the pushed branch, a new `_<mode>` channel will **not** publish unless the branch you push
|
|
93
|
+
carries the wildcard-trigger version. When standing up a new channel, merge from a branch that has
|
|
94
|
+
the dynamic `publish.yml` (or update it first).
|
|
69
95
|
- **FontAwesome v7 `style`-prop TS2322** (fixed 2026-07-21 in `getFontAwesomeIcon.tsx`, and a
|
|
70
96
|
reusable pattern for any consumer). FA v7 types the `FontAwesomeIcon` `style` prop as
|
|
71
97
|
`CSSProperties & CSSVariables`, where `CSSVariables` requires a `--fa-*` custom-property index
|
|
@@ -78,6 +104,11 @@ environment needs its own maintained `_<mode>` branch in `toga-blox-npm`.
|
|
|
78
104
|
the pattern the consuming apps should follow (see the commerce workflow's secret-hygiene note).
|
|
79
105
|
|
|
80
106
|
## Change history
|
|
107
|
+
- 2026-07-23 — Documented CI version derivation (strip suffix → patch+1 → append `-<mode>.<run>`;
|
|
108
|
+
dev owns only the base version, never the suffix) and the `_sandbox-client` deploy procedure now
|
|
109
|
+
driven by the `deploy-sandbox-client` project skill. Recorded that `publish.yml` has diverged
|
|
110
|
+
across branches: the dynamic `_*` trigger is on `_sandbox-client` while older/feature branches
|
|
111
|
+
still trigger only on `_production/_gamma/_beta`. (apeterson)
|
|
81
112
|
- 2026-07-21 — Made `publish.yml` fully dynamic: trigger `_*`, branch→dist-tag by stripping the
|
|
82
113
|
leading underscore (mode == channel 1:1), every branch (incl. `_production`) publishes a
|
|
83
114
|
`X.Y.Z-<mode>.<run>` prerelease; removed the `_production`→`latest` special case (workflow no
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
| [Rate SAML SSO](features/saml-sso.md) | 2.0 | Rate uses Azure AD as its IdP (`login.rate.com`). | _underscore/Model/Rate/ClientAuthentication.php, saml/Controller/Index.php, toga2-view/src/hooks/useAuthenticationFlow.ts |
|
|
9
9
|
| [Service Card Entitlement Display](features/service-card-entitlements.md) | 2.0 | Rate's home and services pages display one service card per purchased entitlement. | src/components/ServiceCard/ServiceCard.tsx, src/components/ServiceCard/index.ts, src/hooks/useBundleServices.ts, src/hooks/useActiveServices.ts, src/pages/Home/api/homeApi.ts, src/pages/Home/view/HomePage.tsx, src/pages/Home/viewModels/useHomePageViewModel.ts, src/pages/Services/view/ServicesPage.tsx, src/pages/Services/viewModels/useServicePageViewModel.ts, src/api/serviceAddressApi.ts, src/api/apiErrors.ts |
|
|
10
10
|
| [Rate Service-Purchase Confirmation Emails (Tech / Warranty)](features/service-purchase-emails.md) | 2.0 | When a Rate customer purchases a service, a confirmation email is sent. | _underscore/Model/Rate/Entitlement.php, worker2/Worker/Notification/EmailTemplate.php, dbchanges2/Client_Rate/2026-06-30a - Rate purchase email templates.sql |
|
|
11
|
-
| [Rate Whole Home Warranty Per-Address Purchase Guard](features/whole-home-warranty-purchase-guard.md) | 2.0 | > **⚠ DEPLOYING beta→production, NOT YET PROD-VERIFIED (as of 2026-07-23).** TRUE-79533 is > beta-verified (PM Paulina tested the WH purchase flow on beta) and | _underscore/Model/Rate/Entitlement.php, _underscore/Model/Client/Entitlement.php, _underscore/Model/Client/Address.php, dbchanges2/Client/2026-07-22a - EntitlementServiceAddressId.sql, dbchanges2/Core/2026-07-22a - EntitlementServiceAddressIdField.sql, dbchanges2/
|
|
11
|
+
| [Rate Whole Home Warranty Per-Address Purchase Guard](features/whole-home-warranty-purchase-guard.md) | 2.0 | > **⚠ DEPLOYING beta→production, NOT YET PROD-VERIFIED (as of 2026-07-23).** TRUE-79533 is > beta-verified (PM Paulina tested the WH purchase flow on beta) and | _underscore/Model/Rate/Entitlement.php, _underscore/Model/Client/Entitlement.php, _underscore/Model/Client/Address.php, dbchanges2/Client/2026-07-22a - EntitlementServiceAddressId.sql, dbchanges2/Core/2026-07-22a - EntitlementServiceAddressIdField.sql, dbchanges2/Client_Rate/2026-07-23a - EntitlementServiceAddressIdFieldPermission.sql, test/@Mark/Rate/verify_wholehome_per_address_guard.php |
|
|
12
12
|
| [Rate](profile.md) | 2.0 | Rate is a mortgage/lending client. | |
|
|
@@ -14,7 +14,7 @@ files:
|
|
|
14
14
|
- _underscore/Model/Client/Address.php
|
|
15
15
|
- dbchanges2/Client/2026-07-22a - EntitlementServiceAddressId.sql
|
|
16
16
|
- dbchanges2/Core/2026-07-22a - EntitlementServiceAddressIdField.sql
|
|
17
|
-
- dbchanges2/
|
|
17
|
+
- dbchanges2/Client_Rate/2026-07-23a - EntitlementServiceAddressIdFieldPermission.sql
|
|
18
18
|
- test/@Mark/Rate/verify_wholehome_per_address_guard.php
|
|
19
19
|
related:
|
|
20
20
|
- clients/rate/profile.md
|
|
@@ -32,11 +32,12 @@ related:
|
|
|
32
32
|
> **shared-interceptor merge hazard** gotcha and the **dangling-pin** / **unguarded prod
|
|
33
33
|
> interceptor** gotchas before merging to `_production`.
|
|
34
34
|
>
|
|
35
|
-
> **🚨 LAUNCH BLOCKER (
|
|
36
|
-
> READ ACL grant.** The custom→standard
|
|
37
|
-
>
|
|
38
|
-
>
|
|
39
|
-
>
|
|
35
|
+
> **🚨 LAUNCH BLOCKER — RESOLVED (migration built 2026-07-23, mhammontree; found 2026-07-23,
|
|
36
|
+
> tcox) — the standard `serviceAddressId` field had NO READ ACL grant.** The custom→standard
|
|
37
|
+
> redesign shipped the column + `Core.RecordFields` row but **not** the `AclFieldPermissions`
|
|
38
|
+
> read grant, so `GET /v2/entitlements?fields=serviceAddressId` returned **403 `EZ-2`**. The fix
|
|
39
|
+
> now ships as **`dbchanges2/Client_Rate/2026-07-23a - EntitlementServiceAddressIdFieldPermission.sql`**
|
|
40
|
+
> (committed `b74f42a` on TRUE-79533) — see
|
|
40
41
|
> **[Launch blocker: standard field needs a READ ACL grant](#launch-blocker-true-79533--the-standard-field-needs-a-read-acl-grant)**.
|
|
41
42
|
|
|
42
43
|
## Summary
|
|
@@ -144,7 +145,7 @@ during backend review (Jeff). This is the single biggest change since the beta b
|
|
|
144
145
|
|
|
145
146
|
**The custom→standard redesign shipped the column and the `Core.RecordFields` row but NOT the
|
|
146
147
|
`AclFieldPermissions` READ grant.** Probe-verified on **beta 2026-07-23**:
|
|
147
|
-
`GET /v2/entitlements?fields=serviceAddressId` returns **403 `EZ-2`**
|
|
148
|
+
`GET /v2/entitlements?fields=serviceAddressId` returns **403 `EZ-2`** (no read ACL row)
|
|
148
149
|
(Entitlements has `Core.Records.aclDatabase = 'CLIENT'`, so the grant lives in each client DB).
|
|
149
150
|
Without the grant, **production launches with the exact `EZ-2` failure beta hit** — the field is
|
|
150
151
|
registered but unreadable, so the service cards cannot fetch the pin.
|
|
@@ -157,16 +158,20 @@ field is authorized through **`AclFieldPermissions`**, keyed by the **`Core.Reco
|
|
|
157
158
|
because the `CustomRecordFields` row for `c_serviceAddressId` was deleted in the standard-field
|
|
158
159
|
redesign. The read grant now has to be an **`AclFieldPermissions`** row instead.
|
|
159
160
|
|
|
160
|
-
**
|
|
161
|
-
`dbchanges2/
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
|
|
161
|
+
**The migration that ships (built + committed `b74f42a` on TRUE-79533):**
|
|
162
|
+
`dbchanges2/Client_Rate/2026-07-23a - EntitlementServiceAddressIdFieldPermission.sql`:
|
|
163
|
+
- Resolves field ids via cross-schema `Core.RecordFields` / `Core.Records` subselects (route
|
|
164
|
+
`'entitlements'`, field `'serviceAddressId'`) — never hardcodes ids.
|
|
165
|
+
- **Grants READ only (`isWritable = 0`)** — `serviceAddressId` is written **server-side** by
|
|
166
|
+
`_Model_Rate_Entitlement::postPost` via raw SQL, never by the API caller.
|
|
167
|
+
- **Mirrors the reader ROLE(s) of the sibling standard FK `saleItemId` — which is `role 1` in
|
|
168
|
+
`Client_Rate`** (the same role the earlier `c_serviceAddressId` custom grant used). Although
|
|
169
|
+
the cross-role probe showed roles 1/2/4 all lacked a grant, **role 1 is the only actual reader**
|
|
170
|
+
of this field (Rate's toga2-view service cards), so the grant is role-1 only.
|
|
171
|
+
- Guards each INSERT with `NOT EXISTS` — safe no-op until the field is registered
|
|
172
|
+
(`AclFieldPermissions` is `UNIQUE (recordFieldId, roleId)`).
|
|
173
|
+
- **Scoped to `Client_Rate`, not a `Client/` fan-out** — Rate is the only client whose UI reads
|
|
174
|
+
the field today. A `Client/` fan-out grant is the follow-up if another client's UI needs it.
|
|
170
175
|
|
|
171
176
|
## Beta data migration — old-column pins are orphaned by the redesign (beta only, NO prod impact)
|
|
172
177
|
|
|
@@ -289,6 +294,17 @@ live carrier waterfall is opt-in via `RUN_LIVE=1` (defaults off). Verified **18/
|
|
|
289
294
|
the deleted `2026-07-07a` interceptor registration was redundant — and why keeping it would have
|
|
290
295
|
been a latent hazard: a fresh environment running both would **double-register**, firing
|
|
291
296
|
`prePost` twice. **Recommend adding a `NOT EXISTS` guard to the `2026-07-15` file.**
|
|
297
|
+
- **`AclFieldPermissions` has NO `isReadable` column — a ROW grants READ; `isWritable`
|
|
298
|
+
*additionally* grants WRITE** (reusable platform fact, verified against the api2 enforcement
|
|
299
|
+
code, not just schema). In `api2/Component/Api/V2/V2.php`, `getAclFieldPermissions()` (~line
|
|
300
|
+
5731) sets the field key regardless of `isWritable`, and the read-authorization checks test key
|
|
301
|
+
**presence** (`isset`/`array_key_exists`). Consequences: to make a field API-**readable** you
|
|
302
|
+
insert an `AclFieldPermissions` row (`isWritable = 0` for read-only); to make it **writable** set
|
|
303
|
+
`isWritable = 1`. And promoting a custom (`c_`) field to a **standard** field means its read grant
|
|
304
|
+
must be **re-created** as a standard `AclFieldPermissions` row (keyed by the `Core.RecordFields`
|
|
305
|
+
id) — the old `AclCustomFieldPermissions` grant (keyed by `CustomRecordFields` id) does **not**
|
|
306
|
+
carry over. This is exactly why the `c_serviceAddressId` grant did not cover the standard field
|
|
307
|
+
and the launch-blocker migration above was needed.
|
|
292
308
|
- **`Core.RecordFields` has no `foreignRecordId` column** — FK resolution for `serviceAddressId`
|
|
293
309
|
is entirely **model-side** (the `_Model_Client_Entitlement` FK declaration). The RecordField row
|
|
294
310
|
only carries type/identifier/childPolicy/precision, mirroring sibling FKs `saleItemId`/`vendorId`.
|
|
@@ -297,6 +313,17 @@ live carrier waterfall is opt-in via `RUN_LIVE=1` (defaults off). Verified **18/
|
|
|
297
313
|
|
|
298
314
|
## Change history
|
|
299
315
|
|
|
316
|
+
- 2026-07-23 — **READ-ACL grant BUILT — launch blocker resolved** (TRUE-79533, committed `b74f42a`).
|
|
317
|
+
Added `dbchanges2/Client_Rate/2026-07-23a - EntitlementServiceAddressIdFieldPermission.sql`: a
|
|
318
|
+
READ-only (`isWritable = 0`) `AclFieldPermissions` grant for the standard `serviceAddressId`,
|
|
319
|
+
resolving field ids cross-schema (route `entitlements`), `NOT EXISTS`-guarded. Final scope
|
|
320
|
+
corrected vs. the earlier proposal: **`Client_Rate` (not a `Client/` fan-out), role 1 only** —
|
|
321
|
+
mirroring the sibling standard FK `saleItemId`'s reader role (role 1 is the sole actual reader,
|
|
322
|
+
the toga2-view service cards). Recorded the reusable platform fact that **`AclFieldPermissions`
|
|
323
|
+
has no `isReadable` column — row presence grants READ, `isWritable` additionally grants WRITE**
|
|
324
|
+
(verified in `api2/Component/Api/V2/V2.php` `getAclFieldPermissions()` ~line 5731), which is why
|
|
325
|
+
a custom→standard promotion must re-create the read grant as an `AclFieldPermissions` row.
|
|
326
|
+
(mhammontree)
|
|
300
327
|
- 2026-07-23 — **LAUNCH BLOCKER found: the standard `serviceAddressId` field has NO read ACL grant**
|
|
301
328
|
(tcox). Probe-verified on beta: `GET /v2/entitlements?fields=serviceAddressId` → 403 `EZ-2` for
|
|
302
329
|
roles 1/2/4 (`aclDatabase=CLIENT`). Standard fields are authorized via **`AclFieldPermissions`**
|
package/package.json
CHANGED