toga-ai 1.0.289 → 1.0.290
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.
|
@@ -5,9 +5,12 @@ project: _Underscore
|
|
|
5
5
|
client: shared
|
|
6
6
|
type: standard
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-07-
|
|
8
|
+
updated: 2026-07-08
|
|
9
9
|
owners: [mhammontree]
|
|
10
|
-
files:
|
|
10
|
+
files:
|
|
11
|
+
- _underscore/Query.php
|
|
12
|
+
- _underscore/Database.php
|
|
13
|
+
- _underscore/Environment.php
|
|
11
14
|
related:
|
|
12
15
|
- ../apps/_underscore/architecture.md
|
|
13
16
|
- ../apps/_underscore/features/per-client-database-connections.md
|
|
@@ -27,12 +30,22 @@ From a 2.0 app root (e.g. `worker2`): `chdir` into the app, require Composer aut
|
|
|
27
30
|
`_underscore.php`, and set `ENVIRONMENT` before bootstrap:
|
|
28
31
|
|
|
29
32
|
```php
|
|
33
|
+
putenv('ENVIRONMENT=dev-markhammontree-laptop'); // REQUIRED, before requiring _underscore.php
|
|
34
|
+
// e.g. dev-<yourname>-laptop — matches your Config/<ENVIRONMENT>.ini
|
|
30
35
|
chdir('/path/to/worker2');
|
|
31
36
|
require 'vendor/autoload.php';
|
|
32
37
|
require '_underscore.php'; // boots Loader/Config/etc.
|
|
33
|
-
// ENVIRONMENT must be set (env var / server) so _Config picks the right INI
|
|
34
38
|
```
|
|
35
39
|
|
|
40
|
+
- **`ENVIRONMENT` is mandatory.** The bootstrap uses it to select `worker2/Config/<ENVIRONMENT>.ini`.
|
|
41
|
+
If it is unset, `_underscore.php` throws *"The environment variable 'ENVIRONMENT' is required and
|
|
42
|
+
has not been set"* (`_underscore/Environment.php:12`). Set it via `putenv(...)` in the script
|
|
43
|
+
before the `require`, or export it in the shell.
|
|
44
|
+
- **On Windows the shell is PowerShell** — set env vars as `$env:VAR='x'; php script.php`, **not**
|
|
45
|
+
the bash `VAR=x php script.php` prefix. The bash-style prefix silently does nothing in
|
|
46
|
+
PowerShell, so the script falls back to its defaults (a confusing "it ran but used the wrong
|
|
47
|
+
config" failure).
|
|
48
|
+
|
|
36
49
|
## You MUST pin the client DB explicitly
|
|
37
50
|
|
|
38
51
|
`_underscore::DB_CLIENT` is a **logical alias**, not a schema name — there is no database literally
|
|
@@ -51,8 +64,41 @@ Without this, any `Model/Client/*` query resolves the unmapped alias and fails.
|
|
|
51
64
|
schema you have locally/on the target env (internal testing uses `Client_True` = TOGA Technology).
|
|
52
65
|
Remember the per-client **logs** connection trap too (see the per-client-database-connections doc).
|
|
53
66
|
|
|
67
|
+
## Commit before you read your own writes (lazy-transaction trap)
|
|
68
|
+
|
|
69
|
+
Standalone scripts run under `_underscore`'s **lazy-transaction model with a separate read
|
|
70
|
+
connection**, so a write is invisible to a later read — and to the code under test — until it is
|
|
71
|
+
committed. Concretely:
|
|
72
|
+
|
|
73
|
+
- `_Database::register(..., alias: _underscore::DB_CLIENT)` sets up a pending transaction for that
|
|
74
|
+
DB. The **first** write (via `_Query`) flips autocommit **OFF** and opens the transaction
|
|
75
|
+
(`_underscore/Query.php` ~303–304, keyed by the database value passed to `_Query`).
|
|
76
|
+
- INSERTs therefore sit **uncommitted**. A subsequent `SELECT` on the read connection returns
|
|
77
|
+
nothing, so a read-back-by-marker returns `null` and dependent FK inserts fail (classic symptom:
|
|
78
|
+
`saleItemId = 0` FK violation).
|
|
79
|
+
|
|
80
|
+
**Pattern:** after seeding base rows, call
|
|
81
|
+
`_Database::transactionCommit(_underscore::DB_CLIENT)` (`_underscore/Database.php` ~165–212). This
|
|
82
|
+
commits **and** restores `autocommit(true)`, so all later writes — and reads of them — behave
|
|
83
|
+
normally. Order your script:
|
|
84
|
+
|
|
85
|
+
1. seed base rows →
|
|
86
|
+
2. **commit** →
|
|
87
|
+
3. read ids back →
|
|
88
|
+
4. insert dependent rows →
|
|
89
|
+
5. assert →
|
|
90
|
+
6. cleanup — and **commit the cleanup too**, so the `DELETE`s persist rather than being rolled
|
|
91
|
+
back when the script exits.
|
|
92
|
+
|
|
93
|
+
This is the same lazy-transaction write-drop family noted in the `_underscore` architecture doc;
|
|
94
|
+
it bites the standalone-script/verification case specifically. Demonstrated working in
|
|
95
|
+
`test/@Mark/Rate/verify_wholehome_per_address_guard.php`.
|
|
96
|
+
|
|
54
97
|
## Rules
|
|
55
98
|
|
|
56
99
|
- Do not add or assume a PHPUnit suite for 2.0 backend work; write a `test`-repo script instead.
|
|
100
|
+
- Always set `ENVIRONMENT` before bootstrap (PowerShell: `$env:ENVIRONMENT='...'`, or `putenv`).
|
|
57
101
|
- Always pin the concrete `Client_<Id>` schema to `DB_CLIENT` (and logs/archive if the code logs).
|
|
102
|
+
- **Commit seeded rows before you read them back** — the read connection cannot see uncommitted
|
|
103
|
+
writes; commit cleanup too so it persists.
|
|
58
104
|
- Keep scripts in your per-dev `test` folder; never point them at production databases.
|
|
@@ -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/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 |
|
|
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 | A customer may hold **one active Whole Home Warranty (WH) per validated address, globally** (across all borrowers). | _underscore/Model/Rate/Entitlement.php, _underscore/Model/Client/Address.php, dbchanges2/Client_Rate/2026-07-07a - WholeHomeWarrantyPerAddressGuard.sql |
|
|
11
|
+
| [Rate Whole Home Warranty Per-Address Purchase Guard](features/whole-home-warranty-purchase-guard.md) | 2.0 | A customer may hold **one active Whole Home Warranty (WH) per validated address, globally** (across all borrowers). | _underscore/Model/Rate/Entitlement.php, _underscore/Model/Client/Address.php, dbchanges2/Client_Rate/2026-07-07a - WholeHomeWarrantyPerAddressGuard.sql, test/@Mark/Rate/verify_wholehome_per_address_guard.php |
|
|
12
12
|
| [Rate](profile.md) | 2.0 | Rate is a mortgage/lending client. | |
|
|
@@ -6,12 +6,13 @@ project: _Underscore
|
|
|
6
6
|
client: rate
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-07-
|
|
9
|
+
updated: 2026-07-08
|
|
10
10
|
owners: [mhammontree]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Model/Rate/Entitlement.php
|
|
13
13
|
- _underscore/Model/Client/Address.php
|
|
14
14
|
- dbchanges2/Client_Rate/2026-07-07a - WholeHomeWarrantyPerAddressGuard.sql
|
|
15
|
+
- test/@Mark/Rate/verify_wholehome_per_address_guard.php
|
|
15
16
|
related:
|
|
16
17
|
- clients/rate/profile.md
|
|
17
18
|
- clients/rate/features/aig-contract-creation.md
|
|
@@ -113,6 +114,17 @@ suggested-vs-entered when `success && address1`, and a "couldn't verify" toaster
|
|
|
113
114
|
[address-validation feature](../../../2.0/apps/_underscore/features/address-validation.md) for the
|
|
114
115
|
endpoint mechanics.
|
|
115
116
|
|
|
117
|
+
## Verification
|
|
118
|
+
|
|
119
|
+
A self-contained backend verification script lives at
|
|
120
|
+
`test/@Mark/Rate/verify_wholehome_per_address_guard.php` (run via PHP CLI with `ENVIRONMENT`
|
|
121
|
+
set, pinned to the real migrated **`Client_Rate`** schema — see the
|
|
122
|
+
[2.0 backend-testing standard](../../../2.0/standards/backend-testing.md)). It applies
|
|
123
|
+
`c_serviceAddressId` idempotently, seeds a token-tagged scratch WH graph (2 addresses / 2 items /
|
|
124
|
+
2 active subscriptions / 2 entitlements), then exercises the pure helpers, the dedup matrix (via
|
|
125
|
+
reflection on the private methods), and the `prePost` branches, cleaning up in a `finally`. The
|
|
126
|
+
live carrier waterfall is opt-in via `RUN_LIVE=1` (defaults off). Verified **18/18 pass**.
|
|
127
|
+
|
|
116
128
|
## Gotchas / known issues
|
|
117
129
|
|
|
118
130
|
- **TOCTOU on the uniqueness check (accepted).** The check-then-persist dedup is **not**
|
|
@@ -131,6 +143,9 @@ endpoint mechanics.
|
|
|
131
143
|
|
|
132
144
|
## Change history
|
|
133
145
|
|
|
146
|
+
- 2026-07-08 — Added a backend verification script
|
|
147
|
+
(`test/@Mark/Rate/verify_wholehome_per_address_guard.php`, 18/18 pass against the migrated
|
|
148
|
+
`Client_Rate` schema) and a Verification pointer. (mhammontree)
|
|
134
149
|
- 2026-07-07 — Built the WH per-address purchase guard (TRUE-79533): `prePost` on
|
|
135
150
|
`_Model_Rate_Entitlement` hard-blocks invalid addresses and second active WH at the same
|
|
136
151
|
normalized address (global), adopts the carrier-normalized address onto the payload, and
|
package/package.json
CHANGED