toga-ai 1.0.1083 → 1.0.1085
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/clients/prudential/profile.md +8 -1
- package/knowledge/clients/rate/INDEX.md +2 -1
- package/knowledge/clients/rate/features/monthly-reconciliation-report.md +2 -1
- package/knowledge/clients/rate/features/saml-sso.md +24 -7
- package/knowledge/clients/rate/profile.md +2 -1
- package/knowledge/clients/rate/workflows/active-subscriptions-report-data.md +45 -0
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@ project: _Underscore
|
|
|
17
17
|
client: prudential
|
|
18
18
|
type: profile
|
|
19
19
|
status: active
|
|
20
|
-
updated: 2026-10-
|
|
20
|
+
updated: 2026-10-19
|
|
21
21
|
owners: ["jcardinal", "rgirish", "bala", "mhammontree"]
|
|
22
22
|
files: []
|
|
23
23
|
related:
|
|
@@ -121,6 +121,13 @@ The order-created cron branches on this id; the shipped/delivered crons branch o
|
|
|
121
121
|
The 15-minute `prudential_auth_rejection_alert.php` cron now alerts on them — see
|
|
122
122
|
features/service-request-auth-rejection-alert.md.
|
|
123
123
|
|
|
124
|
+
- **Daily "Prudential REQ's Processing Report" recipients are hardcoded.** Sent by 1.0
|
|
125
|
+
`worker/crons/notifications/reports/prudential_exception_report.php` (NOT the sibling
|
|
126
|
+
`reports/prudential/` folder), scheduled in `worker/schedules/cron.worker.notification.json` as
|
|
127
|
+
"Prudential Exception Report (9:00 AM)". Recipients = the `$emailTo` PHP array near the top of the
|
|
128
|
+
file (a hardcoded list of togatech.com addresses, all TO, no CC); no DB table or setting. To add or
|
|
129
|
+
remove someone: edit that array, deploy worker `_production` (CodePipeline `Worker`). (TRUE-82925)
|
|
130
|
+
|
|
124
131
|
- **SR number race (TRUE-82209: ServiceNow bursts → 1062 `Duplicate entry 'SR…'` → 400 `EV-10`, SR lost).** Fixed by
|
|
125
132
|
per-client record numbers from `RecordNumbers` (TRUE-82715; SR series continues); the `usleep` stopgap in `_Model_Prudential_ServiceRequest::prePost()`
|
|
126
133
|
is removed. Load-test with a distinct contact + serial per call and `customer.uuid` set. See
|
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
| [Rate Monthly Reconciliation Report](features/monthly-reconciliation-report.md) | 1.0 | Monthly cron that emails an Excel reconciliation of Rate subscription orders + PayPal payments; open when changing the report columns, filters, or recipients. |
|
|
9
9
|
| [Rate SalesOrder → NetSuite CashSale Export (postPost)](features/netsuite-cashsale-export.md) | 2.0 | How a Rate SalesOrder postPost writes a NetSuite CashSale (ship-to address + line-item internalId resolution); open when touching Rate's NetSuite export. |
|
|
10
10
|
| [Rate PayPal Subscription Purchase & Webhook Pipeline](features/paypal-subscription-purchase-webhook.md) | 2.0 | How Rate PayPal subscription purchases are created (browser primary, webhook fallback) and how the worker2 webhook handles lifecycle events; open before touchin |
|
|
11
|
-
| [Rate SAML SSO](features/saml-sso.md) | 2.0 | How Rate users sign in via Azure AD SAML through the TOGa gateway, plus assertion attributes and the loan-officer upsert
|
|
11
|
+
| [Rate SAML SSO](features/saml-sso.md) | 2.0 | How Rate users sign in via Azure AD SAML through the TOGa gateway, plus assertion attributes and the loan-officer upsert (and why the LO is usually missing); op |
|
|
12
12
|
| [Service Card Entitlement Display](features/service-card-entitlements.md) | 2.0 | How Rate's home/services pages render one service card per purchased entitlement (per-entitlement, own pinned address for warranty); open when touching service |
|
|
13
13
|
| [Rate Service-Purchase Confirmation Emails (Tech / Warranty)](features/service-purchase-emails.md) | 2.0 | How Rate purchase-confirmation emails (tech vs warranty) are triggered from the entitlement postPost and sent off-thread from DB-stored templates; open when edi |
|
|
14
14
|
| [Rate Tech-Support Subscription Cancellation (portal self-service)](features/subscription-cancellation.md) | 2.0 | Portal self-service cancellation of a Rate tech-support subscription (cancel at PayPal, wind down to period end); open before touching the cancel flow, the two- |
|
|
15
15
|
| [Rate Whole Home Warranty Per-Address Purchase Guard](features/whole-home-warranty-purchase-guard.md) | 2.0 | The `prePost` guard enforcing one active Whole Home Warranty per validated address (global), via USPS DPV + unit-level dedup; open before touching the WH guard, |
|
|
16
16
|
| [Rate](profile.md) | 2.0 | Rate client profile (mortgage/lending; home warranty + home tech support on TOGa View, SAML SSO); open when starting any Rate work. |
|
|
17
|
+
| [Rate — Fill a customer-sent active-subscriptions report from Client_Rate](workflows/active-subscriptions-report-data.md) | 2.0 | How to fill missing columns (address, loan officer, payments) in a report Rate sends us, by hand from prod `Client_Rate`, and how to match their rows; open when |
|
|
17
18
|
| [Rate — Annual SSL Certificate Renewal (4 Home Warranty / Home Tech Support domains)](workflows/annual-ssl-certificate-renewal.md) | 2.0 | How to generate the four Rate CSRs each year, what to send the GR System team, and what never to send; open when Rate's certs are near expiry. |
|
|
18
19
|
| [Rate — Backfill a Missed PayPal Sale (Toga + NetSuite reconciliation)](workflows/paypal-sale-backfill-and-reconciliation.md) | 2.0 | How to put a PayPal sale that Toga or NetSuite missed back into both systems, by hand; open when reconciling Rate PayPal vs Toga vs NetSuite or when a webhook w |
|
|
@@ -7,13 +7,14 @@ client: rate
|
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
9
|
updated: 2026-09-16
|
|
10
|
-
owners: ["rgirish"]
|
|
10
|
+
owners: ["rgirish", "bala"]
|
|
11
11
|
files:
|
|
12
12
|
- worker/crons/notifications/reports/rate/send_monthly_rate_purchases_report.php
|
|
13
13
|
- worker/schedules/cron.worker.notification.json
|
|
14
14
|
related:
|
|
15
15
|
- clients/rate/features/saml-sso.md
|
|
16
16
|
- clients/rate/profile.md
|
|
17
|
+
- clients/rate/workflows/active-subscriptions-report-data.md
|
|
17
18
|
---
|
|
18
19
|
Monthly cron that emails an Excel reconciliation of Rate subscription orders + PayPal payments; open when changing the report columns, filters, or recipients.
|
|
19
20
|
|
|
@@ -5,17 +5,19 @@ project: SAML SSO Gateway
|
|
|
5
5
|
client: rate
|
|
6
6
|
type: client-feature
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-
|
|
9
|
-
owners: ["rgirish"]
|
|
8
|
+
updated: 2026-10-19
|
|
9
|
+
owners: ["rgirish", "bala"]
|
|
10
10
|
files:
|
|
11
11
|
- _underscore/Model/Rate/ClientAuthentication.php
|
|
12
12
|
- saml/Controller/Index.php
|
|
13
13
|
- toga2-view/src/hooks/useAuthenticationFlow.ts
|
|
14
|
+
- toga2-view/src/routes.tsx
|
|
14
15
|
related:
|
|
15
16
|
- 2.0/apps/saml/architecture.md
|
|
16
17
|
- 2.0/apps/saml/features/rate-user-provisioning.md
|
|
18
|
+
- clients/rate/workflows/active-subscriptions-report-data.md
|
|
17
19
|
---
|
|
18
|
-
How Rate users sign in via Azure AD SAML through the TOGa gateway, plus assertion attributes and the loan-officer upsert; open when debugging Rate login or
|
|
20
|
+
How Rate users sign in via Azure AD SAML through the TOGa gateway, plus assertion attributes and the loan-officer upsert (and why the LO is usually missing); open when debugging Rate login, user provisioning, or loan officer data.
|
|
19
21
|
|
|
20
22
|
## Summary
|
|
21
23
|
Rate uses Azure AD as its IdP (`login.rate.com`). Users sign in at Rate's portal, which redirects to the TOGa SAML gateway at `saml.togahub.com/acs`. On success the gateway redirects the browser back to the Rate frontend with a `?saml=` encrypted payload.
|
|
@@ -23,7 +25,7 @@ Rate uses Azure AD as its IdP (`login.rate.com`). Users sign in at Rate's portal
|
|
|
23
25
|
## How it works
|
|
24
26
|
|
|
25
27
|
### SAML assertion attributes
|
|
26
|
-
Rate's Azure AD sends these attributes in the assertion:
|
|
28
|
+
Rate's Azure AD sends these attributes in the assertion (`ClientAuthentication.php` ~L19-23 reads only these):
|
|
27
29
|
| Attribute key | Description | Required |
|
|
28
30
|
|---|---|---|
|
|
29
31
|
| `borrowerID` | Borrower UUID — used as `c_borrowerId` to identify/create users | Yes |
|
|
@@ -32,7 +34,7 @@ Rate's Azure AD sends these attributes in the assertion:
|
|
|
32
34
|
| `lastName` | Last name | No (null-safe) |
|
|
33
35
|
| `phoneNumber` | Phone number | No (null-safe) |
|
|
34
36
|
|
|
35
|
-
`borrowerID` is a UUID string (not numeric).
|
|
37
|
+
`borrowerID` is a UUID string (not numeric). No loan officer attribute is sent.
|
|
36
38
|
|
|
37
39
|
### Frontend SAML landing (`useAuthenticationFlow.ts`)
|
|
38
40
|
1. If `?saml=` is in the URL: strip it immediately via `window.history.replaceState` (prevents stale payload replay on refresh), then call `/v2/auth/encrypted-user-uuid`.
|
|
@@ -40,15 +42,30 @@ Rate's Azure AD sends these attributes in the assertion:
|
|
|
40
42
|
3. On error: navigate to `/login`.
|
|
41
43
|
|
|
42
44
|
### Loan officer upsert
|
|
43
|
-
|
|
45
|
+
Source: the loan officer reaches us **only** as `loid` (short numeric, e.g. `38623`) + `loname` query params on the landing link Rate sends the borrower. `routes.tsx` (~L52-57) saves every non-`saml` query param to localStorage `urlParameters`. The raw assertion / RelayState / landing URL is never stored.
|
|
46
|
+
|
|
47
|
+
After successful auth, if `urlParameters` contains `loid` + `loname` (`useAuthenticationFlow.ts` ~L72-115):
|
|
44
48
|
1. Fetch the user's Contact to get their Customer UUID.
|
|
45
|
-
2. Search `Contacts` by `c_loid` — PUT to update name if found; POST to create with `
|
|
49
|
+
2. Search `Contacts` by `c_loid` (global, not per customer) — PUT to update name if found; POST to create with `contactTypeId = 1` 'Loan Officer' (UUID `d1f67efc-a984-aebc-42f5-5313f44f52ed`) linked to the customer.
|
|
50
|
+
|
|
51
|
+
No `loid` in the link → no `/v2/contacts?...c_loid` call, no loan officer row. Prod 2026-10-19: only 9 loan officer Contacts in `Client_Rate` (first 2026-06-14) vs 734 customers.
|
|
52
|
+
|
|
53
|
+
Options for more coverage (not built):
|
|
54
|
+
- Ask Rate to add a loan officer attribute to the assertion next to `borrowerID`; read it in `ClientAuthentication.php`.
|
|
55
|
+
- Backfill: send Rate the `Customers.c_borrowerId` list; Rate maps borrower → loan officer.
|
|
46
56
|
|
|
47
57
|
## Gotchas
|
|
48
58
|
- **`?saml=` replay** — the frontend strips the param immediately after processing. Before this fix, refreshing replayed the stale payload → EZ-1 "Invalid User".
|
|
49
59
|
- **New users silently not created (Apr 2 – Jun 11 2026)** — `_Database::register()` auto-starts a lazy transaction; the saml gateway never called `transactionCommit()`, so all new user INSERTs were rolled back silently. Fixed by adding `_Database::transactionCommit()` before the redirect in `saml/Controller/Index.php`.
|
|
50
60
|
- **Both saml and _underscore must be deployed together** — saml pulls `_underscore` at EB build time. A fix in `_underscore` requires a saml redeploy to take effect.
|
|
61
|
+
- **Loan officer never linked to a second borrower (bug, not fixed).** The `c_loid` lookup is global; if the LO exists it only PUTs `firstName`/`lastName`. `Contacts.customerId` stays the first borrower, so later borrowers of the same LO show none. One Contact row = one customer, so the model cannot hold one LO for many borrowers as-is; a fix needs a link table or a per-customer LO row.
|
|
62
|
+
- **`borrowerId` is not the loan officer id.** `Customers.c_borrowerId` / `Users.c_borrowerId` is Rate's IdP UUID, one per customer (prod 2026-10-19: 734 customers, 734 distinct). LO ids are short numerics in `Contacts.c_loid`. The SSO default role `roleId = 1` is *named* 'Loan Officer' (`ClientAuthentication.php` ~L74) — it is only the access role.
|
|
63
|
+
- **Missing LOs cannot be recovered from our side** — nothing that carried them is persisted. Only Rate can supply them.
|
|
51
64
|
|
|
52
65
|
## Related
|
|
53
66
|
- [SAML architecture](2.0/apps/saml/architecture.md)
|
|
54
67
|
- [Rate user provisioning](2.0/apps/saml/features/rate-user-provisioning.md)
|
|
68
|
+
- [Rate active-subscriptions report data](clients/rate/workflows/active-subscriptions-report-data.md)
|
|
69
|
+
|
|
70
|
+
## Change history
|
|
71
|
+
- 2026-10-19 — Documented loan officer source (landing-link `loid` only), the global-lookup link gap, and borrowerId vs `c_loid` (TRUE-82942) (bala)
|
|
@@ -14,7 +14,7 @@ project: SAML SSO Gateway
|
|
|
14
14
|
client: rate
|
|
15
15
|
type: profile
|
|
16
16
|
status: active
|
|
17
|
-
updated: 2026-10-
|
|
17
|
+
updated: 2026-10-19
|
|
18
18
|
owners: ["rgirish", "bala", "mhammontree", "tcox"]
|
|
19
19
|
files: []
|
|
20
20
|
related:
|
|
@@ -29,6 +29,7 @@ related:
|
|
|
29
29
|
- clients/rate/features/home-warranty-terms-content.md
|
|
30
30
|
- clients/rate/workflows/annual-ssl-certificate-renewal.md
|
|
31
31
|
- clients/rate/workflows/paypal-sale-backfill-and-reconciliation.md
|
|
32
|
+
- clients/rate/workflows/active-subscriptions-report-data.md
|
|
32
33
|
---
|
|
33
34
|
Rate client profile (mortgage/lending; home warranty + home tech support on TOGa View, SAML SSO); open when starting any Rate work.
|
|
34
35
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Rate — Fill a customer-sent active-subscriptions report from Client_Rate"
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
project: SAML SSO Gateway
|
|
5
|
+
client: rate
|
|
6
|
+
type: workflow
|
|
7
|
+
status: active
|
|
8
|
+
updated: 2026-10-19
|
|
9
|
+
owners: ["bala"]
|
|
10
|
+
files:
|
|
11
|
+
- worker/crons/notifications/reports/rate/send_monthly_rate_purchases_report.php
|
|
12
|
+
related:
|
|
13
|
+
- ../profile.md
|
|
14
|
+
- ../features/monthly-reconciliation-report.md
|
|
15
|
+
- ../features/saml-sso.md
|
|
16
|
+
- ../features/service-card-entitlements.md
|
|
17
|
+
- ../workflows/paypal-sale-backfill-and-reconciliation.md
|
|
18
|
+
---
|
|
19
|
+
How to fill missing columns (address, loan officer, payments) in a report Rate sends us, by hand from prod `Client_Rate`, and how to match their rows; open when Rate asks for subscription data or names in their own template.
|
|
20
|
+
|
|
21
|
+
## Summary
|
|
22
|
+
Rate sends a PayPal-based template (customer name, email, product, start date, ...) and asks us to fill gaps. Pull from `Client_Rate` (read-only), match each row carefully, and flag disagreements instead of overwriting. Loan officer is usually not available — see [SAML SSO](../features/saml-sso.md) *Loan officer upsert*.
|
|
23
|
+
|
|
24
|
+
## How it works
|
|
25
|
+
|
|
26
|
+
### Join path
|
|
27
|
+
- `Subscriptions` → `Entitlements` (`Entitlements.subscriptionId`) → `Contacts` (`Entitlements.contactId`) → `Customers` (`Contacts.customerId`).
|
|
28
|
+
- Address: `Entitlements.serviceAddressId` → `Addresses` + `States.code` (column is `code`, not `abbreviation`). `Contacts.primaryContactAddressId` points at the same address.
|
|
29
|
+
- Payments: `Entitlements_SalesOrders` → `SalesOrders` → `SalesOrders_Payments` → `Payments`.
|
|
30
|
+
- Loan officer: `Contacts` with `contactTypeId = 1` and `c_loid`, owned by the customer (`customerId`). Rarely present.
|
|
31
|
+
|
|
32
|
+
### Matching a report row to our data
|
|
33
|
+
1. Match on name + address + start date, not email alone.
|
|
34
|
+
2. The report email (PayPal email) can differ from `Users.email` / `ContactEmailAddresses` (seen: one letter off; a different gmail).
|
|
35
|
+
3. `Customers.name` can be a different household member than the name in the report.
|
|
36
|
+
4. Fill only proven matches. List unmatched rows for the requester.
|
|
37
|
+
|
|
38
|
+
## Gotchas
|
|
39
|
+
- **Premium Tech Support ($9.97) entitlements have no address** — the tech support checkout never collects one. Only Whole Home Warranty ($89.97) has one. A blank address there is correct, not missing data.
|
|
40
|
+
- **`Subscriptions.isActive` can disagree with Rate's PayPal-based template.** Flag it; do not change either side.
|
|
41
|
+
- **`Logs_Rate.Api` is ~3.9M rows.** Broad `LIKE` scans on `requestPayload` / `route` over months time out (300s). Always filter a narrow `dtStamp` window plus `userId`.
|
|
42
|
+
- The [monthly reconciliation report](../features/monthly-reconciliation-report.md) cron uses the same joins; reuse its SQL as a starting point.
|
|
43
|
+
|
|
44
|
+
## Change history
|
|
45
|
+
- 2026-10-19 — Created from the TRUE-82942 Rate active-subscriptions data request (bala)
|
package/package.json
CHANGED