Repository navigation
Commit d3d70d3
fix(example-showcase): label the project and invoice owner text field "Owner Email" (#28008)
domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgDFH4S5pR1C8YvYCWWsZfXx)_
Fixes #27916
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:showcase 的项目(`showcase_project`)和发票(`showcase_invoice`)上自带的文本字段
`owner` 改名显示为 "Owner Email"(中文 负责人邮箱),API 名仍是 `owner`。
- 为什么改:平台给这两个对象注入的 `owner_id`(用户查找字段)也叫 "Owner",管理员在字段列表、选择器、筛选里看到两个
"Owner",只能靠 API 名分辨;该字段在种子数据里存的就是负责人的邮箱。
- 风险与回滚:只改示例应用的两个显示标签和中英文翻译,不改字段名、数据、流程或权限规则;回滚即 revert 本 PR。
-
先看:`examples/app-showcase/src/data/objects/project.object.ts`、`examples/app-showcase/src/data/objects/invoice.object.ts`、`examples/app-showcase/src/system/translations/index.ts`。
- 两分钟验证:`pnpm dev` 打开 showcase 的项目或发票列表,点列设置或筛选,预期只看到一个 "Owner"(用户)和一个
"Owner Email"(文本)。
- 需要你做的:无,席位落地。
## What changes
`showcase_project` and `showcase_invoice` each declare a text field
`owner` labelled "Owner". The registry also injects `owner_id`, a
`sys_user` lookup labelled "Owner", so each object listed two "Owner"
fields in the field grid, pickers and filters.
The authored field is now labelled **"Owner Email"** on both objects,
with the zh-CN translation **负责人邮箱**. The label comes from what the
field holds in the seed rows:
- `showcase_project.owner` holds the provisioned persona emails
(`ADMIN_EMAIL`, `PHONE_DEMO_USER.email`, `AUDITOR_DEMO_USER.email`). The
notify flows read it as an email-shaped recipient, as the seed's header
comment explains.
- `showcase_invoice.owner` holds `ada@example.com`-style addresses. The
`showcase_contributor` row-level-security rule compares it to
`current_user.email`, and the source comment above the field already
called it "Owner email".
The API name stays `owner`, so seeded rows, flows (`record.owner`), the
RLS rule and every test that names the field are unchanged. The
translation bundle follows in both locales it carries (`en` and
`zh-CN`). The platform's zh-CN label for `owner_id` is 所有者
(`i18n-resolver` in `@objectstack/spec`), so the zh-CN labels stay
distinct too.
Files: the two object files, `src/system/translations/index.ts` (four
`owner` entries) and a patch changeset for
`@objectstack/example-showcase`. The root `.changeset/config.json`
ignores only `@object-ui/example-*`, not this package, and an earlier
showcase changeset set the precedent.
## Tests
<details><summary>Registry reading, fix and control (in-process ObjectQL
registry, the two objects registered as the app registers
them)</summary>
A throwaway vitest file, deleted after the run (`git status` clean),
registered `Project` and `Invoice` in a real `ObjectQLPlugin` registry
and printed the stored field labels.
On this branch (head 832181e):
```
READING showcase_project: owner.label="Owner Email" owner_id.label="Owner" owner_id.reference=sys_user fields-labelled-Owner=["owner_id"]
READING showcase_invoice: owner.label="Owner Email" owner_id.label="Owner" owner_id.reference=sys_user fields-labelled-Owner=["owner_id"]
```
Control: the two object files restored to the base commit 5e1342a (tree
only), with the same run:
```
READING showcase_project: owner.label="Owner" owner_id.label="Owner" owner_id.reference=sys_user fields-labelled-Owner=["owner_id","owner"]
READING showcase_invoice: owner.label="Owner" owner_id.label="Owner" owner_id.reference=sys_user fields-labelled-Owner=["owner_id","owner"]
```
The files were restored from `HEAD` afterwards. `git diff HEAD` on them
was 0 bytes and the blob hash matched `HEAD`.
</details>
<details><summary>Showcase package, on the merged head
63aaa12</summary>
- `pnpm --filter @objectstack/example-showcase run typecheck`: exit 0
- `pnpm --filter @objectstack/example-showcase exec vitest run
--maxWorkers=2`: Test Files 41 passed (41), Tests 505 passed (505)
- Run under `os-verify-lock.sh`, joined with `&&` after rebuilding the
three dependencies the merge from `main` touched: VERDICT command-exit 0
</details>
## Acceptance notes
- No test pinned the label "Owner" on either object's `owner` field. I
searched `examples/app-showcase/**`, `ui/**` (fixtures, e2e specs),
`packages/qa/dogfood`, `packages/lint` and the root folders for "Owner"
next to `showcase_project` or `showcase_invoice`. The
`ui/e2e/live/record-history-display.spec.ts` "Owner" assertions read
`showcase_account.owner_id`, not these fields. So no test reads the new
label, and no ablation applies.
-
`ui/apps/console/src/services/approvalRequestsDataSource.servedPageSummaryAmount-12534.test.tsx`
keeps an inline copy of `showcase_invoice` (its header dates the copy to
objectstack `9e0945cf4`) with `owner` labelled "Owner". It asserts
nothing about that label, and it describes a dated snapshot, so I left
it alone.
- No new test pins the label. A label is display copy, and the card's
ruling puts a platform-side guard against an authored label that matches
an injected one out of scope, as a separate triage question.
- The live `GET /api/v1/meta/object` reading was not taken. `pnpm dev --
--fresh` stopped at its prereq check because the Console's `ui/`
packages had no build output in this worktree. The in-process registry
reading above stands in for it.
## Verification
<details><summary>Derived gates, on the merged head 63aaa12</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 45 commands. Each was run with its
exit code captured before any pipe, then reconciled with `--ran`:
```
Run reconciliation — 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN.
✓ dispatch-gates --ran: 45 derived famil(ies) accounted for — 45 run, 0 NOT-MEASURED (a DERIVED zero — all 45 recorded an exit code and none of them is 3).
```
All 45 exited 0. `pnpm check:changeset-fixed` was also run (its roster
lives under `.changeset/`): exit 0. `check:dual-build-cjs-loads` first
stopped at PREREQUISITE NOT MET because seven packages outside the
showcase closure had no build output. I built those seven, and it then
passed.
CI owns the type-check lanes, the path-scheduled jobs and the repo-wide
scans.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CbDAucNyQ4UtzCJKyh)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent e199adf commit d3d70d3
4 files changed
Lines changed: 22 additions & 7 deletions
File tree
- .changeset
- examples/app-showcase/src
- data/objects
- system/translations
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
106 | | - | |
107 | | - | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
108 | 109 | | |
109 | 110 | | |
110 | 111 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
93 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
94 | 96 | | |
95 | 97 | | |
96 | 98 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
229 | | - | |
| 229 | + | |
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
| |||
383 | 383 | | |
384 | 384 | | |
385 | 385 | | |
386 | | - | |
| 386 | + | |
387 | 387 | | |
388 | 388 | | |
389 | 389 | | |
| |||
723 | 723 | | |
724 | 724 | | |
725 | 725 | | |
726 | | - | |
| 726 | + | |
727 | 727 | | |
728 | 728 | | |
729 | 729 | | |
| |||
0 commit comments