toga-ai 1.0.1111 → 1.0.1112
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/tools/features/compass-user-persona-admin.md +52 -7
- package/knowledge/clients/compass-canada/profile.md +5 -2
- package/knowledge/clients/compass-usa/profile.md +4 -2
- package/knowledge/clients/compass-usa/workflows/granting-persona-bundle-access.md +2 -2
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ project: Tools
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-
|
|
9
|
+
updated: 2026-10-22
|
|
10
10
|
owners: [ajean, bala]
|
|
11
11
|
files:
|
|
12
12
|
- tools/_/app/compass.php
|
|
@@ -28,14 +28,16 @@ related:
|
|
|
28
28
|
- ../../../clients/compass-usa/features/persona-model-and-levy-gating.md
|
|
29
29
|
- ../../../clients/compass-usa/features/cost-centers.md
|
|
30
30
|
- ../../../clients/compass-usa/workflows/granting-persona-bundle-access.md
|
|
31
|
+
- ../../../clients/compass-usa/workflows/granting-api-access.md
|
|
32
|
+
- ../../../2.0/apps/_underscore/features/acl-permission-chain.md
|
|
31
33
|
---
|
|
32
34
|
|
|
33
35
|
## Summary
|
|
34
36
|
|
|
35
37
|
Two pages in the Tools `developers` nav folder that let staff do, in a browser, the Compass
|
|
36
38
|
requests that used to mean "email a developer, who writes a `dbchanges2` SQL file": **activate /
|
|
37
|
-
deactivate a Compass user**, **grant a persona**,
|
|
38
|
-
phone number and cost center**. Both tenants are covered by one tenant switcher — **US**
|
|
39
|
+
deactivate a Compass user**, **grant a persona**, (as of 2026-09-04) **fix a user's email,
|
|
40
|
+
phone number and cost center**, and (2026-10-22, TRUE-82890) **grant a 2.0 ACL role**. Both tenants are covered by one tenant switcher — **US**
|
|
39
41
|
(`Client_Compass`) and **Canada** (`Client_CompassCanada`).
|
|
40
42
|
|
|
41
43
|
**This is the first thing in `tools` that WRITES to a client tenant database.** Until now the app
|
|
@@ -48,9 +50,9 @@ field-editing work (email / phone / cost center) is PR **tools#14**, branch
|
|
|
48
50
|
## Key files / entry points
|
|
49
51
|
|
|
50
52
|
- **`tools/_/app/compass.php`** — `App_Compass`, all data access for both pages (search, persona
|
|
51
|
-
resolution, activate/deactivate, grant,
|
|
53
|
+
resolution, activate/deactivate, grant, the three field setters, and the role grant).
|
|
52
54
|
- **`tools/mvc/compass/users/{get,post}.php`** — user search + activate/deactivate + grant persona
|
|
53
|
-
+ edit email / phone / cost center.
|
|
55
|
+
+ edit email / phone / cost center + Roles card / `addRole` action.
|
|
54
56
|
- **`tools/mvc/compass/personas/{get,post}.php`** — inspect one persona and who reaches it.
|
|
55
57
|
- **`tools/_/app/nav.php`** — the two nav entries, inside the existing `developers` folder.
|
|
56
58
|
- **`tools/config.production.ini`** — `[database_compass]` / `[database_compasscanada]`, plus the
|
|
@@ -67,6 +69,8 @@ field-editing work (email / phone / cost center) is PR **tools#14**, branch
|
|
|
67
69
|
4. **Inspect a persona** and list who reaches it, from all three sources.
|
|
68
70
|
5. **Grant a persona** — one `INSERT` into `Users_Personas`.
|
|
69
71
|
6. **Edit email, phone number and cost center** (2026-09-04, PR tools#14).
|
|
72
|
+
7. **Grant a role** — Roles card + "Grant role" form; one `Users_Roles` insert (2026-10-22,
|
|
73
|
+
TRUE-82890). See below.
|
|
70
74
|
|
|
71
75
|
The "why" column is the point of the tool. Answering "who has persona N" from `Users_Personas`
|
|
72
76
|
alone badly under-reports on Compass, because most users hold their catalogue through their
|
|
@@ -113,6 +117,37 @@ rows — see [Cost Centers](../../../clients/compass-usa/features/cost-centers.m
|
|
|
113
117
|
**before/after persona diff** to be shown and confirmed, because a location change moves the user's
|
|
114
118
|
sector and therefore their catalogue.
|
|
115
119
|
|
|
120
|
+
### Role grant (TRUE-82890)
|
|
121
|
+
|
|
122
|
+
`App_Compass::roles()`, `role()`, `rolesForUser()`, `hasRole()`, `addUserToRole()`, plus
|
|
123
|
+
`isSensitiveRole()` / `isBlockedRole()` / `roleNameIn()` over the consts `SENSITIVE_ROLE_NAMES` /
|
|
124
|
+
`BLOCKED_ROLE_NAMES`. Post action `addRole` in `users/post.php`.
|
|
125
|
+
|
|
126
|
+
1. **Additive only.** Inserts one `Users_Roles` row; never replaces Base / Compass Base (roles
|
|
127
|
+
resolve as a union — removing one takes access away). **No remove action** — undo is hand SQL.
|
|
128
|
+
2. **Blocked: `API`, `Refresh API`, `Public`.** These are API-key / anonymous roles bound through
|
|
129
|
+
`Apis_Roles`, not roles for people. Hidden from the dropdown AND refused in both `post.php` and
|
|
130
|
+
`addUserToRole()`.
|
|
131
|
+
3. **High-access roles need a confirm checkbox:** `Admin`, `SuperUser`, `Developer`,
|
|
132
|
+
`Agilant - Administrators`, or any role with `coreRoleId > 1`. Name match is trimmed and
|
|
133
|
+
case-blind. The audit note records `[high-access confirmed]`.
|
|
134
|
+
4. **Resolve the posted `roleId` against that tenant's `Roles` table** — ids differ per tenant
|
|
135
|
+
(see gotcha). Never hardcode.
|
|
136
|
+
5. **Duplicate-safe insert:** `INSERT ... SELECT ... WHERE NOT EXISTS` + `affectedRows()`.
|
|
137
|
+
`Users_Roles` has **no unique key on `(userId, roleId)`**, so a double-click would otherwise
|
|
138
|
+
add a second row.
|
|
139
|
+
6. **Audit row first** (`logChange()`, before the insert); `logFailureRow` on failure.
|
|
140
|
+
|
|
141
|
+
**Survives the night.** The worker2 PEOPLE cron (`Worker/Client/Compass/PeopleFile.php`) only
|
|
142
|
+
INSERTS `Users_Roles` rows (Base + Compass Base for everyone, Manager for anyone who is some
|
|
143
|
+
user's `supervisorUserId`) and never deletes one — unlike email / phone / cost center /
|
|
144
|
+
activation, which it overwrites.
|
|
145
|
+
|
|
146
|
+
**Takes effect at the user's next login.** api2 puts the user's roles into the login JWT; a
|
|
147
|
+
signed-in user keeps the old set until they log in again. No ACL cache to clear.
|
|
148
|
+
|
|
149
|
+
Not browser-tested at write time (no local tools server on the developer's Mac).
|
|
150
|
+
|
|
116
151
|
### Access gating is deliberately tighter than the folder
|
|
117
152
|
|
|
118
153
|
Both pages `requireAuth(['Development Team'])` — narrower than the `developers` folder's own
|
|
@@ -147,8 +182,8 @@ reuse the **existing `[database_true]` account** — same client cluster, only `
|
|
|
147
182
|
### Schema footprint: none
|
|
148
183
|
|
|
149
184
|
The tool creates and alters **nothing**. It reads/writes only `Users`, `Contacts` (+ its primary
|
|
150
|
-
email/phone children), `Users_Personas`, `
|
|
151
|
-
names, reads `Core.ClientEmailDomains` / `Core.Clients`, and inserts into `Logs_<Tenant>.Record`.
|
|
185
|
+
email/phone children), `Users_Personas`, `Users_Roles` (insert only), `Locations_Personas`,
|
|
186
|
+
`Locations`, reads `Personas` / `Roles` for names, reads `Core.ClientEmailDomains` / `Core.Clients`, and inserts into `Logs_<Tenant>.Record`.
|
|
152
187
|
|
|
153
188
|
## Decisions
|
|
154
189
|
|
|
@@ -172,9 +207,19 @@ names, reads `Core.ClientEmailDomains` / `Core.Clients`, and inserts into `Logs_
|
|
|
172
207
|
`c_erpSystemEntityId` is also copied into `c_hrEmpDirectoryKey` and treated as unique per
|
|
173
208
|
employee. Same one-way-durability shape as the activation gotcha. Detail:
|
|
174
209
|
[Cost Centers](../../../clients/compass-usa/features/cost-centers.md).
|
|
210
|
+
- **2026-10-22 — Role grant: every tenant role except `API`, `Refresh API`, `Public` (ajean,
|
|
211
|
+
TRUE-82890).** Developer first chose "all roles", then blocked those three after the CTO review
|
|
212
|
+
flagged them. Additive only, no remove action.
|
|
175
213
|
|
|
176
214
|
## Gotchas
|
|
177
215
|
|
|
216
|
+
- **⚠ `Roles` ids differ per Compass tenant.** Prod `Client_Compass`: Base 1, Developer 2, API 3,
|
|
217
|
+
Admin 4, SuperUser 5, Contractor 6, Compass Base 7, Manager 8, Agilant - Administrators 9,
|
|
218
|
+
Public 10, ODP Vendor Items Manager 11, Refresh Orders 12, View Orders 14, Fulfil and Ship 15,
|
|
219
|
+
View Vendor Items 16, Refresh API 17. Prod `Client_CompassCanada`: Base 1, Developer 2, API 3,
|
|
220
|
+
Public 4, Admin 5, SuperUser 6, Contractor 7, Compass Base 8, Manager 9,
|
|
221
|
+
Agilant - Administrators 10, Refresh Orders 11. Match by name or resolve per tenant.
|
|
222
|
+
|
|
178
223
|
- **⚠ Activating a Compass user is TEMPORARY; deactivating is durable.** Because the
|
|
179
224
|
`c_isKeepActive` flag was dropped from scope, the nightly PEOPLE importer will deactivate anyone
|
|
180
225
|
absent from that day's file — so an activation only sticks if the person is actually in the file.
|
|
@@ -19,7 +19,7 @@ project: _Underscore
|
|
|
19
19
|
client: compass-canada
|
|
20
20
|
type: profile
|
|
21
21
|
status: active
|
|
22
|
-
updated: 2026-10-
|
|
22
|
+
updated: 2026-10-22
|
|
23
23
|
owners: [jcardinal, bala, tcox, apeterson, ajean, mhammontree, rgirish]
|
|
24
24
|
files: []
|
|
25
25
|
related:
|
|
@@ -29,6 +29,7 @@ related:
|
|
|
29
29
|
- workflows/grand-and-toy-asn-backfill.md
|
|
30
30
|
- workflows/copying-a-us-user-into-the-canada-tenant.md
|
|
31
31
|
- features/persona-model.md
|
|
32
|
+
- ../../1.0/apps/tools/features/compass-user-persona-admin.md
|
|
32
33
|
- ../../2.0/apps/api2/features/cxml-shipnotice-gateway.md
|
|
33
34
|
- ../compass-usa/features/approval-decision-flow.md
|
|
34
35
|
- ../compass-usa/features/stranded-approval-reassignment.md
|
|
@@ -266,7 +267,9 @@ to but distinct from Compass USA. Like Compass USA it spans the **2.0** commerce
|
|
|
266
267
|
Canada: 1 Base, 7 **Contractor**, 8 **Compass Base**, 9 Manager. USA: 1 Base, 7 **Compass Base**,
|
|
267
268
|
8 Manager. USA grants the fulfillment records to roles 3 + 7; Canada grants most of them to role 1
|
|
268
269
|
only. Nearly every logged-in Canada user carries role 1, so this is usually invisible — but ~10
|
|
269
|
-
users hold Compass Base without Base and still hit the gap.
|
|
270
|
+
users hold Compass Base without Base and still hit the gap. To grant one Canada user a role, use
|
|
271
|
+
tools `/compass/users` (Canada tenant) — it resolves the id per tenant; see
|
|
272
|
+
[Compass user/persona admin](../../1.0/apps/tools/features/compass-user-persona-admin.md).
|
|
270
273
|
- **Canada was NOT damaged by the 2026-08-31 cross-client item merge, and is structurally
|
|
271
274
|
immune.** It was **not** in the `duplicate_items_merge_ALL_CLIENTS.sql` client list; it has a
|
|
272
275
|
**single catalog** ("compass"), 0 part numbers in multiple catalogs, and 0 duplicate part
|
|
@@ -23,7 +23,7 @@ project: _Underscore
|
|
|
23
23
|
client: compass-usa
|
|
24
24
|
type: profile
|
|
25
25
|
status: active
|
|
26
|
-
updated: 2026-10-
|
|
26
|
+
updated: 2026-10-22
|
|
27
27
|
owners: [jcardinal, bala, tcox, apeterson, dfranks, akhokhani, ajean, rgirish]
|
|
28
28
|
files: []
|
|
29
29
|
related:
|
|
@@ -219,7 +219,9 @@ separate, related client (see its own profile).
|
|
|
219
219
|
not `id`, and **`Users` has no `username` column** — it is `c_hrEmpUsername`, stored lowercase.
|
|
220
220
|
Super user = `Roles.id 5` added **additively** via `Users_Roles`, never replacing Base /
|
|
221
221
|
Compass Base. **Kit add-on bundles (`BundleItems.childBundleId`) need their own persona grant**
|
|
222
|
-
and stay `isActive = 0` by design (TRUE-82981, 2026-10-21).
|
|
222
|
+
and stay `isActive = 0` by design (TRUE-82981, 2026-10-21). A single role grant (USA or Canada)
|
|
223
|
+
is now self-serve in tools `/compass/users` (Roles card; `API` / `Refresh API` / `Public`
|
|
224
|
+
blocked) — see [Compass user/persona admin](../../1.0/apps/tools/features/compass-user-persona-admin.md).
|
|
223
225
|
- [Prod ↔ dev-sandbox persona comparison](workflows/persona-population-env-comparison.md) — the
|
|
224
226
|
full-population diff technique, the **join-on-email** rule (`Users.id` means different people per
|
|
225
227
|
environment), and the drift bundles (188/191/242) that mimic a catalogue grant.
|
|
@@ -6,7 +6,7 @@ project: Database Changes
|
|
|
6
6
|
client: compass-usa
|
|
7
7
|
type: workflow
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-10-
|
|
9
|
+
updated: 2026-10-22
|
|
10
10
|
owners: [bala, ajean]
|
|
11
11
|
files:
|
|
12
12
|
- dbchanges2/Client_Compass/2026-08-26a - CompassCreativeStudioPersona.sql
|
|
@@ -72,7 +72,7 @@ The `personaId <> @personaId` exclusion matters: by the time this phase runs, th
|
|
|
72
72
|
**`Client_Compass.Users` has no `username` column** — the natural first query fails with `Unknown column 'username'`. The Compass login / personnel username lives in **`c_hrEmpUsername`**, stored **lowercase**: people quote it uppercase ("KINGK01") but the row says `kingk01`. Look users up by `email` or `c_hrEmpUsername` (lowercased), which is also how the nightly PEOPLE cron matches them — see [PEOPLE-File User Lifecycle](../features/people-file-user-lifecycle.md).
|
|
73
73
|
|
|
74
74
|
### Making someone a super user
|
|
75
|
-
There is **no `isSuperUser` flag on `Users`** — it is a role row. `Client_Compass.Roles.id` **5**, name **`SuperUser`** (113 holders as of 2026-08-26), granted **additively** through `Users_Roles (userId, roleId)`, which
|
|
75
|
+
There is **no `isSuperUser` flag on `Users`** — it is a role row. `Client_Compass.Roles.id` **5**, name **`SuperUser`** (113 holders as of 2026-08-26), granted **additively** through `Users_Roles (userId, roleId)`, which has **no** unique key on the pair (guard the insert with `WHERE NOT EXISTS`). A single role grant needs no SQL: use the tools `/compass/users` Roles card — [Compass user/persona admin](../../../1.0/apps/tools/features/compass-user-persona-admin.md). **SuperUser is never a replacement for the base roles.** The established prod pattern for a Compass super user is **Base (1) + SuperUser (5) + Compass Base (7)**, optionally **+ Manager (8)**. Role permissions resolve as a **union** (see [ACL Permission Chain](../../../2.0/apps/_underscore/features/acl-permission-chain.md)), so adding role 5 while removing 1 or 7 takes access *away*.
|
|
76
76
|
|
|
77
77
|
### Verify the way the ACL actually resolves personas
|
|
78
78
|
A user's **effective** persona set is three UNIONed sources, not just `Users_Personas`:
|
package/package.json
CHANGED