Repository navigation
feat(ui): the timeline's Changes chip holds the audit's field changes only; the CRM opens field history on its four main objects - #30294
Merged
Conversation
crm_lead, crm_account, crm_contact and crm_opportunity declare enable.trackHistory, so their record pages show each field change with its before and after values. Claude-Session: https://claude.ai/code/session_01QSeKYnE9YNkSZen7sijLA3 Co-authored-by: Claude <noreply@anthropic.com>
… is shown RecordDetailView hands its trackHistory gate (historyEnabled) to the stream through RecordFieldHistoryContext; record:activity drops the changes chip while it is false and falls back to all when the chosen chip goes away. Claude-Session: https://claude.ai/code/session_01QSeKYnE9YNkSZen7sijLA3 Co-authored-by: Claude <noreply@anthropic.com>
…ory; changeset Claude-Session: https://claude.ai/code/session_01QSeKYnE9YNkSZen7sijLA3 Co-authored-by: Claude <noreply@anthropic.com>
… only; activity events sit under Activity Ruling C on the record timeline: an item is a field-history entry when it is a field_change read from the audit log (source 'sys_audit_log'). The stream's Changes chip and the panel's changes_only hold those and nothing else; the activity rows that share the field_change presentation (created, updated, deleted, assigned, shared) sit under Activity whatever the history flag. ACTIVITY_TYPE_TO_FEED_TYPE is unchanged. Claude-Session: https://claude.ai/code/session_01WGufzic59DvGAbu7U78pZt Co-authored-by: Claude <noreply@anthropic.com>
…nd README follow ruling C Claude-Session: https://claude.ai/code/session_01WGufzic59DvGAbu7U78pZt Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#1 · os-support-ai · session_01WGufzfE4V9fzZgJLrLDmMC 维护者速读(席位终稿)
席位核对 · ACCEPT · head
|
This was referenced Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Yibo Wang · project thread
Fixes #30074
Supersedes #30158
Clause-②: no
Metadata-protocol: none
维护者速读
enable.trackHistory,未开启历史的对象不显示「变更」筛选。ACTIVITY_TYPE_TO_FEED_TYPE映射表;回滚即撤销本 PR。注意:在非默认记录页上(自取sys_activity的面板),下拉选「字段变更」今后为空,因为那里不读审计(见 Acceptance notes)。ui/packages/plugin-detail/src/recordTimelineStream.ts(新判定isFieldHistoryEntry与filterTimelineStream)、ui/packages/plugin-detail/src/RecordActivityTimeline.tsx(面板changes_only同规则)、ui/packages/plugin-detail/src/__tests__/recordTimelineStream-27055.test.tsx(翻转的「四个筛选」pin 与新 pin)。pnpm --dir ui exec vitest run packages/plugin-detail/src/__tests__/recordTimelineStream-27055.test.tsx,预期全部通过;或pnpm dev:crm后新建一条线索并改公司名,打开动态页签:「变更」里是「公司 旧 → 新」,「活动」里是「创建了 线索…」。What changes
Resumed from
claude/issue-30074-crm-track-history@8c5b89c9(draft PR #30158, option A as built), merged withorigin/mainat9b8a5867, then the ruling C delta on top.isFieldHistoryEntry(item)inrecordTimelineStream.ts: an item is a field-history entry when it is afield_changeread from the audit log (source: 'sys_audit_log', whichauditEntriesToFeedItemsstamps).filterTimelineStreamuses it: Changes holds those only, Activity holds everything that is neither a comment nor one of those. Thesys_activityrows that share thefield_changepresentation (created,updated,deleted,assigned,shared) are therefore Activity, whatever the history flag.ACTIVITY_TYPE_TO_FEED_TYPEis not edited.RecordActivityTimeline'schanges_onlydropdown filter uses the same predicate, so the panel and the stream agree on what a change is.crm_lead,crm_account,crm_contact,crm_opportunitydeclareenable: { trackHistory: true };RecordFieldHistoryContextplustimelineStreamFilters()hide the Changes chip while the record shows no field history, a stream left on Changes falls back to All, andRecordDetailViewhands over itshistoryEnabled..changeset/30074-crm-track-history.md(from feat(ui): open field history on the CRM's four main objects; the timeline's Changes chip follows trackHistory #30158) amended to ruling C (patch,Clause-②: no,Metadata-protocol: none); plugin-detail README says what Changes holds.File surface: #30158's 13 files plus two existing plugin-detail test files whose pins read the old classification (
renderers/__tests__/record-activity.test.tsx,renderers/__tests__/recordChatterFilterModeMentions-8968.test.tsx); see Tests. No server, REST or spec change.Tests
All readings on head
93bbdd78, the final commit.recordTimelineStream-27055.test.tsx): the activitycreatedrow now sits under Activity, Changes holds the audit change alone, and every entry lands under exactly one of Activity / Discussion / Changes.changes_onlykeeps the same rule as the stream.record-activity.test.tsx: its "filterMode seeds which slice" pin seededchanges_onlyand expected the activityupdatedrow, which ruling C moves out; it now seedstasks_only(still proves the seed), and a new pin assertschanges_onlyholds no activity event.recordChatterFilterModeMentions-8968.test.tsx: its field-change fixture row gainssource: 'sys_audit_log', the stamp of the one producer offieldChangesin the tree (auditEntriesToFeedItems); its assertions are unchanged.scripts/ablation-replace.mjsonrecordTimelineStream.ts, anchoritem.type === 'field_change' && item.source === 'sys_audit_log'replaced byitem.type === 'field_change'(the subject resolves tosrcthrough theui/vitest.config.mtsaliases, so no dist leg): anchor 1 to 0, blob16c475ce1d79toaee54ae67d0a; 6 tests red, exactly the flipped and new pins; the 8968 file green (its row is a real field change either way). Restored: blob equals HEAD16c475ce1d79,git diff HEADempty.objectstack dev --seed-admin --fresh, Vite console, zh-CN): a newcrm_lead(history on) edited once through the data API: chips 全部 / 活动 / 讨论 / 变更; 变更 shows 「公司 Ruling C Ltd → Ruling C Holdings」 and the creation's field values; 活动 shows 「创建了 线索 "Live Check Lead"」 only. A newcrm_activity(history off) edited once: chips 全部 / 活动 / 讨论, no 变更; 活动 shows 「更新了 活动 …:主题」 and 「创建了 活动 …」. On the history-on lead theupdatedactivity row steps aside because the audit says the same update with values (mergeTimelineStream, unchanged).Test readings
@object-ui/plugin-detailwhole package plus the app-shell pin fileRecordDetailView.recordPageTiers-26678.test.tsx: Test Files 370 passed, 1 skipped (371); Tests 3292 passed, 18 skipped (3310).@object-ui/plugin-detailexit 0;@object-ui/app-shellexit 0 after the full build (bothtsc --noEmitandtsc -p tsconfig.test.json). A first app-shell run before the full build failed on unbuilt@object-ui/*declarations (TS2307), not on this diff.Acceptance notes
changes_onlyoff the default record page. Off the synthesized record page therecord:activitypanel holdssys_activityrows only and reads no audit, so under ruling C its 字段变更 slice is empty there; before, it listed the activitycreated/updatedrows. This follows the ruling's "same rule for the panel" and is pinned; whether that panel should offer the option at all where no audit is read is left to the seat.auditEntriesToFeedItemskeeps any audit entry with changes, the create entry included, although its doc says the creation is the activity stream's own row. Under ruling C the audit half sits under 变更 and the activity half under 活动. Compact rows did name the actor in this run (「· Dev Admin · 刚刚」).mainmoved 14 commits after the merge at9b8a5867; none touches a path in this diff (git diff --name-only HEAD...origin/mainagainst the 15 paths: zero hits) andgit merge-treeis clean, so the branch was not re-merged. CI runs the merge ref.Verification
Gates from
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, derived at93bbdd78(53 commands).Gate readings
--ran: "53 derived famil(ies) accounted for — 53 run, 0 NOT-MEASURED (a DERIVED zero — all 53 recorded an exit code and none of them is 3)".node scripts/check-sdui-manifest.mjsexit 0;pnpm --dir ui exec vitest run scripts/: Test Files 170 passed, 2 skipped (172); Tests 4985 passed, 2 skipped.pnpm --dir ui run check:new-line-citations: 0 new citations, exit 0.check-platform-checklistnot owed: no export renamed or removed (isFieldHistoryEntryis added to the module, not to the package entry).Generated by Claude Code
#30158 closed as superseded by the seat.