toga-ai 1.0.216 → 1.0.218
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/architecture.md +4 -0
- package/knowledge/1.0/apps/test/features/goagilant-to-togatech-email-migration.md +134 -0
- package/knowledge/2.0/apps/_underscore/INDEX.md +1 -0
- package/knowledge/2.0/apps/_underscore/features/assortment-name-translation.md +86 -0
- package/knowledge/INDEX.md +2 -2
- package/knowledge/clients/compass-canada/profile.md +4 -0
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
| [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
9
|
| [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
10
|
| [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 |
|
|
11
|
+
| [@goagilant.com → @togatech.com Email-Domain Migration (1.0 + 2.0)](features/goagilant-to-togatech-email-migration.md) | Reference + technique for migrating the company email domain `@goagilant.com` → `@togatech.com` across **both** platforms. | migrate_goagilant_to_togatech_2026-06-26.sql, migrate_goagilant_to_togatech_LEGACY_2026-06-26.sql |
|
|
11
12
|
| [TableView Builder (2.0 TableViews SQL generator)](features/tableview-builder.md) | `team/tableViewBuilder/` generates SQL `INSERT` statements for the **2.0 `TableViews`**, `TableViewFields`, and `TableViewJoins` tables from a plain SQL `SELECT | test/team/tableViewBuilder/TableViewGenerator.php, test/team/tableViewBuilder/index.php, test/team/tableViewBuilder/Instructions.md |
|
|
12
13
|
| [Talos Knowledge Base Pipeline (Uploader + Processor)](features/talos-kb-pipeline.md) | `team/talos/` holds the two-script web tooling that feeds the **TOGa Talos** (TOGa IQ) AI knowledge bases. | test/team/talos/kb_uploader.php, test/team/talos/kb_processor.php, test/team/talos/kb_processor.ini |
|
|
13
14
|
| [TOGa 2.0 Client Onboarding SQL Generator](features/toga2-client-onboarding-sql.md) | `team/generate_toga2_onboarding_sql.php` generates the SQL needed to **onboard a new client** onto the 2.0 platform. | test/team/generate_toga2_onboarding_sql.php |
|
|
@@ -21,6 +21,7 @@ related:
|
|
|
21
21
|
- ./features/url-domain-markdown-document.md
|
|
22
22
|
- ./features/dev-generators.md
|
|
23
23
|
- ./features/talos-kb-pipeline.md
|
|
24
|
+
- ./features/goagilant-to-togatech-email-migration.md
|
|
24
25
|
---
|
|
25
26
|
|
|
26
27
|
## Summary
|
|
@@ -83,6 +84,7 @@ manually against the target database; they do not execute changes themselves.
|
|
|
83
84
|
| `generate_toga2_user_access_sql.php` | 1.0 | 2.0 client DBs | [toga2-user-cross-client-access-sql](./features/toga2-user-cross-client-access-sql.md) |
|
|
84
85
|
| `generate_password.php`, `uuid.php` | 1.0 | dev utility | [dev-generators](./features/dev-generators.md) |
|
|
85
86
|
| `talos/kb_uploader.php`, `talos/kb_processor.php` | standalone | S3 + AWS Bedrock KBs | [talos-kb-pipeline](./features/talos-kb-pipeline.md) |
|
|
87
|
+
| `migrate_goagilant_to_togatech_*.sql` | standalone | 2.0 `Client_` DBs + 1.0 schemas | [goagilant-to-togatech-email-migration](./features/goagilant-to-togatech-email-migration.md) |
|
|
86
88
|
|
|
87
89
|
**Retired / not documented:** `team/DOA_gitbook/` is being retired.
|
|
88
90
|
|
|
@@ -91,3 +93,5 @@ manually against the target database; they do not execute changes themselves.
|
|
|
91
93
|
- 2026-06-16 — Initial capture of the `team/` folder. Registered repo in `registry.json`.
|
|
92
94
|
- 2026-06-22 — Un-retired `team/DOA_talos/` → `team/talos/`; documented its uploader +
|
|
93
95
|
processor in [talos-kb-pipeline](./features/talos-kb-pipeline.md).
|
|
96
|
+
- 2026-06-26 — Documented the @goagilant.com → @togatech.com email-domain migration SQL
|
|
97
|
+
artifacts in [goagilant-to-togatech-email-migration](./features/goagilant-to-togatech-email-migration.md).
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "@goagilant.com → @togatech.com Email-Domain Migration (1.0 + 2.0)"
|
|
3
|
+
framework: "1.0"
|
|
4
|
+
repo: test
|
|
5
|
+
project: Test
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-06-26
|
|
10
|
+
owners: [bala]
|
|
11
|
+
files:
|
|
12
|
+
- migrate_goagilant_to_togatech_2026-06-26.sql
|
|
13
|
+
- migrate_goagilant_to_togatech_LEGACY_2026-06-26.sql
|
|
14
|
+
related:
|
|
15
|
+
- ../architecture.md
|
|
16
|
+
- ./2-0-deployment-client-sql.md
|
|
17
|
+
- ../../../2.0/apps/_underscore/features/email-template-sending.md
|
|
18
|
+
- ../../../2.0/apps/_underscore/features/per-client-database-connections.md
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Summary
|
|
22
|
+
|
|
23
|
+
Reference + technique for migrating the company email domain `@goagilant.com` →
|
|
24
|
+
`@togatech.com` across **both** platforms. Two standalone SQL artifacts (run manually
|
|
25
|
+
against the right cluster, not framework code) were produced:
|
|
26
|
+
|
|
27
|
+
- `migrate_goagilant_to_togatech_2026-06-26.sql` — 2.0 prod, per-tenant `Client_` DBs.
|
|
28
|
+
- `migrate_goagilant_to_togatech_LEGACY_2026-06-26.sql` — 1.0 legacy.
|
|
29
|
+
|
|
30
|
+
The durable value is the **email-column blast-radius map** for each environment and the
|
|
31
|
+
**two collision gotchas** that make a blanket find/replace unsafe. Use this before any
|
|
32
|
+
future email-domain change.
|
|
33
|
+
|
|
34
|
+
## Where @goagilant.com emails live
|
|
35
|
+
|
|
36
|
+
### 2.0 prod (per-tenant `Client_` DBs, prod-client cluster)
|
|
37
|
+
|
|
38
|
+
Value columns that actually held `@goagilant.com` data:
|
|
39
|
+
|
|
40
|
+
| Column | Notes |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `Users.email` | **UNIQUE** — identity logins. See Client_True gotcha. |
|
|
43
|
+
| `ContactEmailAddresses.emailAddress` | |
|
|
44
|
+
| `EmailTemplates.sendFromEmailAddress` | Present in **all 32 clients**; outbound `From:` — deliverability-sensitive (sender-verification gate below). |
|
|
45
|
+
| `IntegrationsEmail.fromEmailAddress` | Outbound `From:` — deliverability-sensitive. |
|
|
46
|
+
| `SalesOrderEmailAddresses.emailAddress` | Composite UNIQUE `(salesOrderId, emailAddress)`. |
|
|
47
|
+
| `EmailTemplateOutgoingEmailAddresses.emailAddress` | Composite UNIQUE. |
|
|
48
|
+
|
|
49
|
+
Columns that exist but held **zero** `@goagilant.com` data (skip):
|
|
50
|
+
`Campaigns.bookingEmailAddress`, `LocationEmailAddresses.emailAddress`,
|
|
51
|
+
`IntegrationsEmailOutgoingEmailAddresses.emailAddress`.
|
|
52
|
+
|
|
53
|
+
`ContactAttempts.c_contactEmail` exists **only** in `Client_True` (BDR).
|
|
54
|
+
|
|
55
|
+
Tenants with `Users.email` hits included Compass, CompassCanada, Managelife, Quad, Growrk,
|
|
56
|
+
Nychh, Prudential, Aig, Endeavorhealth, Erau, Masonite, Rate, Spglobal, Towfoundation, Wje,
|
|
57
|
+
Wmchealth, Ynhh, plus True (special-cased).
|
|
58
|
+
|
|
59
|
+
### 1.0 legacy
|
|
60
|
+
|
|
61
|
+
| Table | Hits | Notes |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `TOGA.Users.email` | 1117 goagilant | Main platform login. **NOT unique** (PRIMARY on `id` only). togatech migration already ~half done: 1077 togatech rows exist; 7 goagilant overlap a togatech local-part. |
|
|
64
|
+
| `TOGA_<tenant>.ClientUsers.email` | 0 goagilant | Client-portal logins — clean across all 14 tenants. |
|
|
65
|
+
| `TOGA_<tenant>.Contacts.emailAddress` | ~255 | CRM. `relayEmailAddress` = 0 everywhere. |
|
|
66
|
+
| `Vision.Users` | 343 | Sibling-app login, 0 togatech twins. |
|
|
67
|
+
| `RetailServices.DashboardUsers` | 6 | 0 togatech twins. |
|
|
68
|
+
| `ITADPortal.Users` | 3 | 0 togatech twins. |
|
|
69
|
+
| `TOGaDeskAdmin.users` | 2 | 0 togatech twins. |
|
|
70
|
+
|
|
71
|
+
**Not migrated** (high-volume ancillary, out of scope): helpdesk `TOGaDeskSupport.tickets`
|
|
72
|
+
(15725), `Common` directory (~3700), RetailServices customer data, Netsuite/Store. The
|
|
73
|
+
**Advisor** and **GoAgilant (WordPress)** schemas are not queryable via the toga-db MCP tool
|
|
74
|
+
and were not assessed here.
|
|
75
|
+
|
|
76
|
+
## How it works (safe-rename technique)
|
|
77
|
+
|
|
78
|
+
Swap **only** the 14-char domain suffix, preserving the local-part exactly:
|
|
79
|
+
|
|
80
|
+
```sql
|
|
81
|
+
UPDATE SomeTable
|
|
82
|
+
SET col = CONCAT(LEFT(col, CHAR_LENGTH(col) - 14), '@togatech.com')
|
|
83
|
+
WHERE col LIKE '%@goagilant.com';
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Why not `REPLACE()`: `REPLACE` is case-sensitive (misses `@GoAgilant.com`) and can touch a
|
|
87
|
+
mid-string match. `LEFT`/`CONCAT` on the trailing 14 chars touches only the domain and keeps
|
|
88
|
+
apostrophes/odd local-parts intact (e.g. `do'connell@`). The `LIKE` is the natural
|
|
89
|
+
case-insensitive guard for the match.
|
|
90
|
+
|
|
91
|
+
For the non-unique 1.0 `TOGA.Users`, a guarded variant uses `NOT EXISTS` against a
|
|
92
|
+
materialized derived table of existing `@togatech.com` addresses, so the 7 would-be
|
|
93
|
+
duplicate logins are skipped rather than creating colliding identities.
|
|
94
|
+
|
|
95
|
+
## Scope (explicit developer instructions)
|
|
96
|
+
|
|
97
|
+
- **2.0:** exclude `Client_True.Users` (see gotcha); still migrate True's other email tables.
|
|
98
|
+
- **1.0:** scoped to **USERS + CONTACTS only** — explicitly exclude `Customers`,
|
|
99
|
+
`SMBContracts` (contracts/work orders), and send-from in 1.0.
|
|
100
|
+
- **Never** touch any `*Logs*` schemas.
|
|
101
|
+
|
|
102
|
+
## Sender-address gate (deliverability)
|
|
103
|
+
|
|
104
|
+
`EmailTemplates.sendFromEmailAddress` (~118 rows across all 2.0 clients) and
|
|
105
|
+
`IntegrationsEmail.fromEmailAddress` change the outbound `From:` domain. These were gated
|
|
106
|
+
as a separate step pending `togatech.com` sender verification (SPF/DKIM/DMARC). The domain
|
|
107
|
+
was **confirmed verified 2026-06-26**, so the sender-address step is cleared to run. Do not
|
|
108
|
+
flip a `From:` domain ahead of sender verification — it breaks deliverability.
|
|
109
|
+
|
|
110
|
+
## Gotchas
|
|
111
|
+
|
|
112
|
+
- **Client_True (2.0) UNIQUE twins.** `Users.email` is UNIQUE. Of 343 `@goagilant.com`
|
|
113
|
+
users, **325 already have a pre-staged `@togatech.com` twin** (twins mostly never logged
|
|
114
|
+
in, `dtLastLogin` NULL — a togatech cutover was partially staged). A blanket rename
|
|
115
|
+
collides on the UNIQUE constraint (fails, or with `IGNORE` **silently skips 325**). Of the
|
|
116
|
+
18 no-twin rows, ~13 are service/SFTP/support accounts (`odpsftp@`, `staplessftp@`,
|
|
117
|
+
`support@`, …) whose rename could break integrations. **Decision:** exclude
|
|
118
|
+
`Client_True.Users.email` from the migration; migrate only True's 64 non-identity rows
|
|
119
|
+
(ContactEmailAddresses 56, Campaigns 1, ContactAttempts 1, EmailTemplates.sendFromEmailAddress
|
|
120
|
+
6), which carry no UNIQUE-on-email risk.
|
|
121
|
+
- **Legacy `TOGA.Users` is non-unique and half-migrated.** PRIMARY is on `id` only, so a
|
|
122
|
+
rename can produce duplicate login emails. 1077 togatech rows already exist and 7 goagilant
|
|
123
|
+
rows overlap a togatech local-part — use the `NOT EXISTS`-guarded variant to skip those 7.
|
|
124
|
+
- **Run against the right cluster.** 2.0 lives in per-tenant `Client_` DBs on the prod-client
|
|
125
|
+
cluster; 1.0 in `TOGA` / `TOGA_<tenant>` / sibling-app schemas. Review the generated SQL
|
|
126
|
+
before executing — these are manual-run artifacts, nothing auto-executes.
|
|
127
|
+
|
|
128
|
+
## Change history
|
|
129
|
+
|
|
130
|
+
- 2026-06-26 — Initial capture. Mapped 2.0 + 1.0 email columns, recorded the Client_True
|
|
131
|
+
UNIQUE-twin and legacy non-unique-login collision gotchas, the LEFT/CONCAT safe-rename
|
|
132
|
+
technique, scope exclusions, and the cleared sender-verification gate. (bala)
|
|
133
|
+
</content>
|
|
134
|
+
</invoke>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|-----|---------|-------|
|
|
5
5
|
| [_underscore Framework Architecture](architecture.md) | `_underscore` is the shared PHP backend framework for **all 2.0 applications**. | _underscore/_underscore.php, _underscore/Loader.php, _underscore/Framework.php, _underscore/Model.php, _underscore/Database.php, _underscore/Query.php, _underscore/Route.php, _underscore/Component.php |
|
|
6
6
|
| [ACL Permission Chain (Record & Field Authorization)](features/acl-permission-chain.md) | Authorization in the 2.0 API is **metadata-driven**: whether a role may Create/Read/Update/Delete a record is decided by rows across **four linked tables**, not | api2/Component/Api/V2/V2.php, _underscore/Model/Core/Page.php, dbchanges2/Client/2026-06-03- BLANK_CLIENT_DATABASE.sql, dbchanges2/Client/2026-06-23b - ItemTranslationsAcl.sql |
|
|
7
|
+
| [Assortment Name Translation (AssortmentTranslations sidecar)](features/assortment-name-translation.md) | Serves Assortment (product-grouping) **names** in multiple languages by adding a per-language **sidecar** table `AssortmentTranslations`, reusing the platform's | _underscore/Model/Client/AssortmentTranslation.php, dbchanges2/Client/2026-06-26a - AssortmentTranslations.sql, dbchanges2/Core/2026-06-26a - AssortmentTranslationsRecord.sql, dbchanges2/Client/2026-06-26b - AssortmentTranslationsAcl.sql |
|
|
7
8
|
| [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/ItemFulfillments/TrackingNumber.php, _underscore/Component/Library/LabelPdf/LabelPdf.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 |
|
|
8
9
|
| [Client Email Template Sending](features/email-template-sending.md) | `_Model_Client_EmailTemplate` sends a stored, client-defined email template by UUID. | _underscore/Model/Client/EmailTemplate.php, _underscore/Model/Client/EmailTemplateOutgoingEmailAddress.php, _underscore/Email.php |
|
|
9
10
|
| [Forecast.Sales NetSuite import engine (real-time webhook)](features/forecast-sale-import.md) | Real-time importer that takes a NetSuite **sale** record and writes its lines into `Forecast.Sales` (the Forecast2 revenue table). | _underscore/Component/Forecast/SaleImport/SaleImport.php, _underscore/Component/Forecast/Db/Db.php, worker2/Worker/Netsuite/Invoice.php, worker2/Worker/Netsuite/CashSale.php, worker2/Worker/Netsuite/CreditMemo.php, worker2/Worker/Netsuite/CashRefund.php, worker2/Worker/Netsuite/JournalEntry.php, worker2/Worker/Netsuite/Opportunity.php, worker2/Worker/Netsuite/SalesOrder.php, dbchanges2/Forecast/2026-06-26a - Add journalEntry to Sales transaction type enum.sql, test/@dave/test_invoice_lifecycle.php, test/@dave/test_je_lifecycle.php, test/@dave/test_creditmemo_lifecycle.php, test/@dave/test_cashsale_lifecycle.php, test/@dave/test_cashrefund_lifecycle.php, test/@dave/NetSuite/api-message-queue/ue_api_msg_queue_enqueue.js, test/@dave/NetSuite/api-message-queue/dev_ue_api_msg_queue_enqueue.js |
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Assortment Name Translation (AssortmentTranslations sidecar)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: _underscore
|
|
5
|
+
project: _Underscore
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-06-26
|
|
10
|
+
owners: ["bala"]
|
|
11
|
+
files:
|
|
12
|
+
- _underscore/Model/Client/AssortmentTranslation.php
|
|
13
|
+
- dbchanges2/Client/2026-06-26a - AssortmentTranslations.sql
|
|
14
|
+
- dbchanges2/Core/2026-06-26a - AssortmentTranslationsRecord.sql
|
|
15
|
+
- dbchanges2/Client/2026-06-26b - AssortmentTranslationsAcl.sql
|
|
16
|
+
related:
|
|
17
|
+
- ../../api2/features/language-translation-layer.md
|
|
18
|
+
- ./acl-permission-chain.md
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Summary
|
|
22
|
+
|
|
23
|
+
Serves Assortment (product-grouping) **names** in multiple languages by adding a per-language
|
|
24
|
+
**sidecar** table `AssortmentTranslations`, reusing the platform's existing translation mechanism.
|
|
25
|
+
English stays in `Assortments.name`; the sidecar holds only non-English overlays. Because the
|
|
26
|
+
translation layer is fully metadata-driven (see
|
|
27
|
+
[Language Translation Layer](../../api2/features/language-translation-layer.md)), wiring this up
|
|
28
|
+
required **no api2 code change** — only a new table, model, Core record registration, ACL grant,
|
|
29
|
+
and a single field link. Compass Canada's French (fr-CA) assortment names are seeded as the first
|
|
30
|
+
consumer.
|
|
31
|
+
|
|
32
|
+
## Key files / entry points
|
|
33
|
+
|
|
34
|
+
- `_underscore/Model/Client/AssortmentTranslation.php` — the sidecar model (`_Model_Client_AssortmentTranslation`).
|
|
35
|
+
- `dbchanges2/Client/2026-06-26a - AssortmentTranslations.sql` — the sidecar table (every client DB).
|
|
36
|
+
- `dbchanges2/Core/2026-06-26a - AssortmentTranslationsRecord.sql` — Core record + fields + the field link.
|
|
37
|
+
- `dbchanges2/Client/2026-06-26b - AssortmentTranslationsAcl.sql` — Base-role ACL grant (every client DB).
|
|
38
|
+
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
The mechanism itself is the data-driven translation layer documented in
|
|
42
|
+
[Language Translation Layer](../../api2/features/language-translation-layer.md) — this feature only
|
|
43
|
+
**registers a new translatable field** into it:
|
|
44
|
+
|
|
45
|
+
1. **Sidecar table.** `Client.AssortmentTranslations` holds non-English overlays for assortment names.
|
|
46
|
+
English remains in `Assortments.name`; a null/absent sidecar row falls back to English.
|
|
47
|
+
2. **Model.** `_Model_Client_AssortmentTranslation` is the ORM model for the sidecar.
|
|
48
|
+
3. **Core record registration.** `Core.Records` registers route `assortment-translations` →
|
|
49
|
+
model `\_Model_Client_AssortmentTranslation` (record id **332**, `aclDatabase = 'CLIENT'`), with
|
|
50
|
+
`Core.RecordFields` rows for `id`, `uuid`, `assortmentId`, `languageId`, and `name`.
|
|
51
|
+
4. **The field link (what makes it translate automatically).** The translatable `Assortments.name`
|
|
52
|
+
RecordField gets its `Core.RecordFields.translationRecordFieldId` set to the sidecar's `name`
|
|
53
|
+
RecordField. The api2 V2 layer reads `translationRecordFieldId` for every field and automatically
|
|
54
|
+
returns the sidecar value for the caller's resolved language (falling back to English when absent) —
|
|
55
|
+
so assortment names now translate **without any api2 code change**.
|
|
56
|
+
5. **ACL.** A full ACL chain grants the **Base** role read/write on the new record. Because the
|
|
57
|
+
record's `aclDatabase = 'CLIENT'`, the grant lives in each client DB — see
|
|
58
|
+
[ACL Permission Chain](./acl-permission-chain.md).
|
|
59
|
+
|
|
60
|
+
## Data model
|
|
61
|
+
|
|
62
|
+
- `Client.AssortmentTranslations` — `id, uuid, dtCreated, dtUpdated, assortmentId (FK Assortments),
|
|
63
|
+
languageId (FK Languages), name`; `UNIQUE(assortmentId, languageId)`. English stays in `Assortments`;
|
|
64
|
+
sidecar holds only non-English overlays (null → English fallback).
|
|
65
|
+
- `Core.Records` **332** = `assortment-translations` (`aclDatabase = 'CLIENT'`); `Core.RecordFields`
|
|
66
|
+
for id/uuid/assortmentId/languageId/name.
|
|
67
|
+
- `Assortments.name` RecordField → `translationRecordFieldId` points at the sidecar `name` RecordField.
|
|
68
|
+
|
|
69
|
+
## Client variations
|
|
70
|
+
|
|
71
|
+
- **Compass Canada** seeds fr-CA assortment names (16 rows) into `AssortmentTranslations`. The French
|
|
72
|
+
text was extracted from the existing bilingual `Assortments.name` values (stored as `"English/French"`),
|
|
73
|
+
and a companion migration cleans `Assortments.name` back to English-only so the base value is pure
|
|
74
|
+
English and the French overlay lives only in the sidecar. See the Compass Canada profile.
|
|
75
|
+
|
|
76
|
+
## Change history
|
|
77
|
+
|
|
78
|
+
- 2026-06-26 — Initial build: `AssortmentTranslations` sidecar table + `_Model_Client_AssortmentTranslation`
|
|
79
|
+
model + `Core.Records` 332 registration + `translationRecordFieldId` link on `Assortments.name` + Base-role
|
|
80
|
+
ACL chain. Reuses the existing metadata-driven translation layer, so no api2 code change was needed.
|
|
81
|
+
Compass Canada French (fr-CA) assortment names seeded, with `Assortments.name` cleaned to English-only. (bala)
|
|
82
|
+
|
|
83
|
+
## Related docs
|
|
84
|
+
|
|
85
|
+
- [Language Translation Layer](../../api2/features/language-translation-layer.md)
|
|
86
|
+
- [ACL Permission Chain](./acl-permission-chain.md)
|
package/knowledge/INDEX.md
CHANGED
|
@@ -10,13 +10,13 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
10
10
|
- **togaview** (TOGa View) — 6 doc(s) → [1.0/apps/togaview/INDEX.md](1.0/apps/togaview/INDEX.md)
|
|
11
11
|
- **webhook** (Webhook) — 1 doc(s) → [1.0/apps/webhook/INDEX.md](1.0/apps/webhook/INDEX.md)
|
|
12
12
|
- **walmarttechservices** (Walmart Tech Services) — 1 doc(s) → [1.0/apps/walmarttechservices/INDEX.md](1.0/apps/walmarttechservices/INDEX.md)
|
|
13
|
-
- **test** (Test) —
|
|
13
|
+
- **test** (Test) — 12 doc(s) → [1.0/apps/test/INDEX.md](1.0/apps/test/INDEX.md)
|
|
14
14
|
- **toga** (TOGa) — 2 doc(s) → [1.0/apps/toga/INDEX.md](1.0/apps/toga/INDEX.md)
|
|
15
15
|
- **tools** (Tools) — 5 doc(s) → [1.0/apps/tools/INDEX.md](1.0/apps/tools/INDEX.md)
|
|
16
16
|
|
|
17
17
|
## 2.0 framework
|
|
18
18
|
|
|
19
|
-
- **_underscore** (_Underscore) _(framework core)_ —
|
|
19
|
+
- **_underscore** (_Underscore) _(framework core)_ — 17 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
|
|
20
20
|
- **worker2** (Worker) — 17 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
|
|
21
21
|
- **api2** (API) — 7 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
|
|
22
22
|
- **dbchanges2** (Database Changes) _(framework core)_ — 3 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
|
|
@@ -44,5 +44,9 @@ to but distinct from Compass USA. Like Compass USA it spans the **2.0** commerce
|
|
|
44
44
|
## Notes
|
|
45
45
|
- Customer language preference: `UserGlobalSettings.settingId = 2` (`en` / `fr-CA`); customer-
|
|
46
46
|
facing emails are sent in EN or FR accordingly.
|
|
47
|
+
- Assortment (product-grouping) names are served in fr-CA via the `AssortmentTranslations` sidecar
|
|
48
|
+
(16 rows seeded). French was extracted from the old bilingual `"English/French"` `Assortments.name`
|
|
49
|
+
values, which were then cleaned to English-only. See
|
|
50
|
+
[Assortment Name Translation](../../2.0/apps/_underscore/features/assortment-name-translation.md).
|
|
47
51
|
- The 2026-06-08 ASN → ItemFulfillment work was for **Compass USA**, not Compass Canada.
|
|
48
52
|
- Related: [Compass USA](../compass-usa/profile.md).
|
package/package.json
CHANGED