Skip to content

fix(campaign-member): un-shadow the Basic Information field group (#715) - #1007

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-715-campaign-member-highlight-shadow
Aug 7, 2026
Merged

fix(campaign-member): un-shadow the Basic Information field group (#715)#1007
yinlianghui merged 1 commit into
mainfrom
claude/issue-715-campaign-member-highlight-shadow

Conversation

@yinlianghui

@yinlianghui yinlianghui commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Fixes #715

现象

crm_campaign_memberbasic(Basic Information)字段组四个字段全部被详情页页头提走,组标签只在表单上出现,详情页永不渲染 —— 详情页正文只剩 "Response Tracking" 一个组,表单与详情的分组结构不一致。

fresh origin/main(acc37e6)+ @objectstack/* 17.0.0-rc.3 上复现,前提成立,warning 与 issue 所述逐字一致:

⚠ object "crm_campaign_member": crm_campaign_member: every field in group "basic"
  (member_number, crm_campaign, crm_lead, crm_contact) is hoisted into the detail
  highlight strip (or is the record title) — the group renders on forms but never
  on detail pages
    field-group-shadowed  at objects[2].fieldGroups

根因

详情页把「记录标题 + highlightFields 的前四项」提升进页头高亮条,并从正文中移除。本对象两侧恰好完全重合:

  • nameField: 'member_number' —— 记录标题;
  • highlightFields 前三项 crm_campaign / crm_lead / crm_contact —— 高亮条。

于是 basic 组的全部四个成员都被提走,正文里一个都不剩,组因此为空而不渲染。response 组没这个问题:它还有四个字段没被提升。

取舍

修在字段组一侧,不动高亮条 —— 这一侧是被逼出来的,不是随手选的。

highlightFields 在本对象上是双承载的:除了详情页高亮条,它还是活动记录相关列表的列来源。相关列表取子对象的 highlightFields 减去它所限定的那个 lookup(上限六列),而本对象根本没有 view 元数据 —— 这是仓内已实测并由 test/view-references.test.ts 钉住的结论(#944)。所以若按 issue「落点分析」里那条思路把 crm_lead / crm_contact 从高亮条摘掉,活动详情页的成员面板就会只剩 Status / Response Date 两列、看不到人 —— 正是 #944 立单要防的退化。

因此改动落在组一侧,与仓内既有口径一致 —— crm_taskassignment 组(#582)当初也是这么解的:把字段挪到它本该归属的组,高亮条原封不动。

具体:added_dateresponse 迁到 basic。这不是为了凑一个字段,它本来就更该在这儿 —— 它记录的是成员关系何时建立(报名时间戳),而不是此人如何响应;response 组留下的是完整的响应生命周期(First Opened / First Clicked / Response Date / Has Responded)。

修复后详情页:标题 CM-00042;高亮条 Campaign / Lead / Contact / Status;正文 Basic Information(Added Date)+ Response Tracking(四项)。表单同样两组,结构一致。

未动的面(范围栅栏): highlightFields 一字未改,活动的成员相关列表列(Lead / Contact / Status / Response Date)与成员页头完全不变;content/docs/ 一字未动,#961 的文档宣称面不受影响;lint 配置未动。两个组的 key 都仍在使用,四个语言包无需改动。

验证

pnpm verify 六门全绿(exit 0):

结果
validate ✓ Validation passed (1380ms)
typecheck pass
lint 12 warning(s), 14 suggestion(s) —— 由 13 降至 12,field-group-shadowed 归零
hygiene ✓ source hygiene clean(含控制字节扫描)
build ✓ Build complete,4 条 author-time warning 均为既有 approval 类
test Test Files 77 passed (77) / Tests 1823 passed + 1 skipped (1824)

余下 12 条 warning 全部是既有的 naming/namespace-prefix(AGENTS.md 已注明为规则误报,另案 objectstack#5510),与本单无关。

新增守卫 + 反向验证。 test/field-groups-coverage.test.ts 里补了第三项检查:「没有字段组被高亮条整组吞掉」。该文件本来就已经复刻了平台 validateSemanticRoles 三条规则中的另外两条(field-group-undeclared / field-group-empty),原因写在文件头:这类缺陷 os validate 两边都满意。补这一条把三条补齐,理由同样成立且更强 —— 实测 objectstack lint 在只有 warning 时 exit code 为 0,所以 field-group-shadowed 再犯时 pnpm verify 不会红(见下方范围外记录)。

反向验证方向在跑之前先行判定为常规「变红」(该守卫读的是谓词而非计数):把 added_date 改回 group: 'response',新检查必须红且消息与平台规则的字段清单一致。实测符合预判:

AssertionError: groups shadowed by the highlight strip:
  crm_campaign_member: group "basic" (member_number, crm_campaign, crm_lead, crm_contact)
  is entirely title-or-strip — it renders on forms and never on detail pages
Tests  1 failed | 20 passed (21)

改回 basic 后 21 passed。

范围外记录(本 PR 不修)

  1. objectstack lint 只报不挡门。 实测 pnpm exec objectstack lint --skip-i18n; echo $? 在 13 条 warning 下仍返回 0,故 pnpm verify 中的 lint 门对 warning 类缺陷无约束力。未改 lint 配置(公共面),改为在仓内补测试守卫。
  2. object/missing-name-field 疑似平台规则缺陷(与 ADR-0079 自相矛盾)。 该规则判定 hasNameField = !!primaryField || !!titleFormat || 存在 name 类字段,从不读 nameField;而同一 lint 包的 validate-record-title 又把 titleFormat 判为 ADR-0079 已废弃、要求迁移到 nameField。结果是:照平台自己的迁移建议做的应用反而多出一条 "records will display as raw IDs" 建议。本仓 6 条该建议中,crm_campaign_member(member_number)、crm_event_attendee(attendee_number)、crm_contract(contract_number)、crm_forecast(display_title)四个对象均已显式声明 nameField,属误报;仅两个 line item 对象是真的没有。属平台侧(objectstack),已检索 objectstack / hotcrm 未见在办单。

Every field in `crm_campaign_member`'s `basic` group was hoisted out of the
detail body: `member_number` is the record title, and `crm_campaign` /
`crm_lead` / `crm_contact` are the first three highlightFields. A detail page
drops the title and the leading four strip entries from the body, so the group
kept its heading on forms and rendered nowhere on detail pages — `os lint`
reported it as `field-group-shadowed`, the one such warning on main.

Fixed on the GROUP side, not the strip, and that side is forced rather than
chosen: `highlightFields` is also what curates the members panel on a campaign's
detail page (a related list falls back to the child's highlightFields minus the
lookup it is scoped by, and this object ships no view at all). Dropping the two
party lookups from the strip would have left that panel showing Status /
Response Date and no person — the degradation #944 measured and
test/view-references.test.ts pins.

So `added_date` moves from `response` to `basic`, which is where it reads
anyway: it stamps when the MEMBERSHIP was created, not how the person responded.
Response Tracking keeps the lifecycle (First Opened, First Clicked, Response
Date, Has Responded). Same resolution as crm_task's shadowed `assignment` group
(#582): move the field to the group it belongs to, leave the strip alone.

Guarded in test/field-groups-coverage.test.ts, which already replicates the
other two `validateSemanticRoles` rules for the same reason: `os lint` exits 0
on warnings, so nothing in `pnpm verify` fails when this one comes back.
Reverting `added_date` to `response` turns the new check red with the platform
rule's own field list.

verify: exit 0 — validate ✓, typecheck ✓, lint 13 → 12 warnings
(field-group-shadowed gone), hygiene ✓, build ✓, 1823 passed | 1 skipped.
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hotcrm Ignored Ignored Aug 6, 2026 6:46pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants