Repository navigation
Commit 1e01924
fix(platform-objects): the Setup Users list and the user record highlights stop showing the legacy role scalar (#28810)
domain:server#5 · os-project-manager · session_01FEkQ5oc56xChD6Wrc4cGSt
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1XD5Csq4vbvdCSTJt7KnCqYG)_
Fixes #28105
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:Setup → 用户列表(`all_users` 视图)去掉「Platform
Role」一列;用户记录页顶部的高亮条去掉「Platform Role」一格。字段 `sys_user.role` 本身不动:仍是只读文本、仍在
Admin 分组、数据 API 照旧可读。
- **为什么改**:这一列是 better-auth 的遗留字段,平台从不写它;admin 插件开着时它给每个人都盖
`user`,种子平台管理员也是 `user`(本地实测见下)。平台管理员身份来自 ADR-0068 D2(所有者邮箱或无组织的
`admin_full_access`),不来自这一列。按裁决 D1(Ruling-ref:
6557746678)撤掉这个误导的展示面;真实身份推导的一列另立 #28793。
- **风险与回滚**:低。纯展示面改动,无类型、存储、选项或 spec 变化;已存的用户列表个性化视图不受影响(它们存自己的列)。回滚即撤销本
PR。
-
**先看**:`packages/platform-objects/src/pages/sys-user.page.ts`(`record:highlights`
的 `fields`,高亮其实住在记录页,不在对象的
`highlightFields`);`packages/platform-objects/src/identity/sys-user.object.ts`(`all_users.columns`);`packages/platform-objects/src/identity/sys-user-list-columns.test.ts`。
- **两分钟验证**:`pnpm --filter @objectstack/platform-objects exec vitest run
--maxWorkers=2 src/identity/sys-user-list-columns.test.ts
src/pages/sys-user-record-highlights.test.ts`,预期 8/8 通过(main 上 4 红)。
- **需要你做的**:无,席位落地。
## What changes
- **`all_users` list view** (`sys-user.object.ts`): columns are now
`name, email, phone_number, email_verified, banned, source, created_at`.
`role` is gone; `banned` stays (#27863). The column comment says why.
- **User record page highlights** (`pages/sys-user.page.ts`): the
`record:highlights` chip strip of `sys_user_detail` is now `email,
phone_number, email_verified`. The details grid's `hideFields` keeps
`role` (its comment now says why: not the platform role, rather than
"already promoted to highlights"), and no details section names it, so
the record page draws `role` nowhere. The page docblock no longer lists
"platform role" among the signals.
- **Unchanged, per ruling D1:** the `sys_user.role` field (`Field.text`,
readonly, `maxLength: 64`, group `Admin`, label and description), its
storage, the better-auth `defaultRole` stamp, and the ADR-0092 import /
create-user pass-through. No synchronisation of platform-admin standing
into the scalar. No `packages/spec/**` or `ui/**` edit.
- **Changeset** `.changeset/28105-sys-user-role-off-setup-screens.md`:
`patch` on `@objectstack/platform-objects` (served view and page
metadata change; no authorable value is refused, no key moves).
## Tests
- **Pin renamed and moved with the ruling.**
`identity/sys-user-list-status-role-columns.test.ts` (the #27863 pin, PR
#28065) is now `identity/sys-user-list-columns.test.ts`, since its name
named the Role column. It pins the new `all_users` columns, that no
`sys_user` list view lists `role`, that the object `highlightFields` do
not carry it, that every column is a declared field, and that `role` is
still readonly `text` in group `Admin` with no `options` (ruling 2
guard).
- **New page pin** `pages/sys-user-record-highlights.test.ts`: the
header chip strip is exactly `email, phone_number, email_verified`; no
`record:highlights` node anywhere on the page (tab children walked)
carries `role`; no `record:details` section draws it and `hideFields`
keeps it.
- **Red first, on base `d9c4cdc4e`** (both files against base sources):
4 failed / 4 passed. Red: the `all_users` columns pin, "no list view
shows role", the chip-strip pin, "no highlights node carries role".
Green on base as well as head: object `highlightFields` (already `name,
email, email_verified` on base), every column declared, the role-field
guard, the details-section check.
- **Green on head:** the two files 8/8; `@objectstack/platform-objects`
full suite and typecheck green (numbers in Verification). The existing
`pages/sys-user-details-tab.test.ts` pin of `hideFields` is unchanged
and green.
- No ablation: the change is declarative metadata, and the red-on-base
run above is the pins' negative leg.
## Acceptance notes
- **Mechanism (order assumption 1, confirmed).** The record highlight
showing `role` was not the object-level `highlightFields` (`['name',
'email', 'email_verified']` on base) but the `record:highlights` node of
the record page `sys_user_detail`. No compact layout exists
(`compactLayout` is a retired key). The claim's file surface was amended
to add the page file and its folder's tests.
- **Other readers of `sys_user.role` (order assumption 2).** No other
platform view, dashboard, report or example reads it as a column. The
`role` columns in `sys_member`, `sys_invitation`,
`sys_scim_projection_grant` and the related lists on the organization
and user pages are membership / grant roles of other objects, not this
scalar. Non-Setup readers left alone: the Console import panel's `role`
column (`ui/packages/app-shell/src/views/IdentityImportPanels.tsx`, the
ADR-0092 import pass-through), the expression-context `user.role` and
its `${user.role === 'admin'}` example in
`ui/packages/app-shell/src/providers/ExpressionProvider.tsx` (the ui
finding the seat carries), and
`packages/qa/dogfood/test/admin-ledger-decision-metadata.dogfood.test.ts`,
which reads the field label, not a list column.
- **Still reads "Platform Role".** The field's label stays `Platform
Role` (ruling 2: no field change), so the standard edit form and the
data API keep that label. Noted, not changed.
- **Saved personal list views** that copied `role` into their own column
list keep it; this PR changes only the shipped `all_users` default.
- No `content/docs/**` page pins the Users list columns (grep for the
column list, `all_users` and `Platform Role` under `content/docs`: zero
hits).
## Verification
<details><summary>Live probe, stock showcase boot, base vs
head</summary>
Commands (each leg on a fresh boot, platform-objects `dist/` rebuilt for
that leg; the base leg wrote the base blobs of the two source files over
the head copies, then restored them with `git checkout HEAD --`, `git
diff HEAD` empty and both blob hashes equal to HEAD before the head
`dist/` was rebuilt):
```
pnpm dev -- --fresh -p PORT
curl -c jar -H 'Origin: http://localhost:PORT' -H 'Content-Type: application/json' -X POST http://localhost:PORT/api/v1/auth/sign-in/email -d '{"email":"admin@objectos.ai","password":"admin123"}'
curl -b jar -H 'Origin: http://localhost:PORT' http://localhost:PORT/api/v1/meta/object/sys_user # item.listViews.all_users.columns, item.highlightFields, item.fields.role
curl -b jar -H 'Origin: http://localhost:PORT' http://localhost:PORT/api/v1/meta/page/sys_user_detail # every record:highlights node's fields
curl -b jar -H 'Origin: http://localhost:PORT' 'http://localhost:PORT/api/v1/data/sys_user?fields=id,email,role&limit=2'
```
| read | base `d9c4cdc4e` (port 4625) | head (port 4615) |
|---|---|---|
| sign-in | 200 | 200 |
| `all_users.columns` | `name, email, phone_number, email_verified,
banned, role, source, created_at` | `name, email, phone_number,
email_verified, banned, source, created_at` |
| object `highlightFields` | `name, email, email_verified` | `name,
email, email_verified` |
| page `record:highlights` (header) | `email, phone_number,
email_verified, role` | `email, phone_number, email_verified` |
| page `record:highlights` (Security tab) | `two_factor_enabled` |
`two_factor_enabled` |
| `fields.role` | text, readonly, group Admin | text, readonly, group
Admin, label Platform Role |
Head data read: `admin@objectos.ai` (the showcase's seeded dev admin)
answers `"role": "user"`; `auditor.demo@example.com` answers `"role":
null`. That is the wrong value the ruling describes, and the field stays
readable through the data API.
</details>
<details><summary>Gates, local subset, at head 280a84d (59 derived
families, all exit 0)</summary>
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on the real diff (merge base `c064d3a2`),
each run with its exit code captured before any pipe, then reconciled:
`dispatch-gates --ran: 59 derived famil(ies) accounted for — 59 run, 0
NOT-MEASURED`. `check-plugin-teardown-shape --self-test` first exited 3
on the shallow clone; after `git fetch --depth=1 origin` of its
positive-control commit it passes 48 cases.
Also at this head: `pnpm build` (117/117 tasks), `pnpm --filter
@objectstack/platform-objects typecheck` (exit 0), `pnpm --filter
@objectstack/platform-objects test` (108 files, 1503 tests passed),
`pnpm exec eslint --no-inline-config packages/platform-objects` (exit
0). `test:repo` and the full farm are CI's.
```
node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-adoption.mjs :: exit 0
node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-empty-changeset.mjs --self-test :: exit 0
node scripts/check-issue-citations.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/docs-audit/check-affected-docs.mjs :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
node scripts/release-pending-publish.mjs --self-test :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm check:changeset-gate-self-tests :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:i18n :: exit 0
pnpm check:i18n-stale-fill :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:keyed-text-bounds :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:platform-object-tenancy-census :: exit 0
pnpm check:pm-changeset-deadline-census :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:slot-lookup :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:system-context-census :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
```
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FEkQ5msFrPy8g6WzAxVUjG)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent c5ac1b6 commit 1e01924
6 files changed
Lines changed: 151 additions & 44 deletions
File tree
- .changeset
- packages/platform-objects/src
- identity
- pages
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
816 | 816 | | |
817 | 817 | | |
818 | 818 | | |
819 | | - | |
820 | | - | |
821 | | - | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
822 | 826 | | |
823 | 827 | | |
824 | 828 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
53 | 55 | | |
54 | 56 | | |
55 | 57 | | |
| |||
175 | 177 | | |
176 | 178 | | |
177 | 179 | | |
178 | | - | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
179 | 184 | | |
180 | 185 | | |
181 | 186 | | |
| |||
215 | 220 | | |
216 | 221 | | |
217 | 222 | | |
218 | | - | |
| 223 | + | |
219 | 224 | | |
220 | 225 | | |
221 | 226 | | |
| |||
0 commit comments