Repository navigation
feat(seed): the lead Activity tab shows logged interactions out of the box (#1258) - #1959
Merged
Merged
Conversation
… logged interactions (#1258) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X8U3asekbiC7yWoEPWR4Dg
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X8U3asekbiC7yWoEPWR4Dg
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
os-warren
marked this pull request as ready for review
September 25, 2026 13:30
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.
Fixes #1258
Route A (maintainer ruling 5386129833): the lead Activity tab now shows logged interactions out of the box, through the platform's ActivityPointer (
sys_activity). No app-side imitation object and no extra writer.What changed
src/sales/data/activity.seed.ts: a newleadInteractionPointersdataset onsys_activity. It is derived from the sameEVENT_SPECSthat seed thecrm_eventrows. Each pointer is the rowlog_call/log_meetingwould have written for a held lead event:type: 'completed'(thetaskfeed kind the tab filters to), the action's own summary format,object_name/record_idpointing at the lead by email,source_object/source_idpointing at the event by subject, and the action'smetadatashape. Only call/meeting events (the two writers that exist) younger than the 14d telemetry retention are included.last_contacted_date: today()for their later call, so no recency clock moves.src/sales/data/index.tsandobjectstack.composition.ts: the dataset is exported and registered inCrmSeedDataright after the event attendees, because it resolves against leads and events seeded earlier.test/seed-consistency.test.ts: thesys_*guard block is deleted on purpose. Its own comment asked for this: "If a future platform release makes an ActivityPointer target seedable, delete this test deliberately — do not widen it". objectstack#11339 did that, and the 17.4.0 pin carries it. A positive pin replaces it. Every pointer must name a seeded lead and a held event on that same lead, withtype: 'completed', inside 14 days. Every held lead call or meeting inside the window must have its pointer. At least 3 pointers across at least 2 leads.hotcrm: patch).Measurement first (17.4.0, booted app, fresh DB)
I re-measured the three 17.1.0 blockers in the old guard comment before writing the final seeds. First I booted with a scratch version of the dataset (2 rows), then again with the final 4 rows. Commands:
rm -rf .objectstack/data && pnpm build && objectstack start -p 4158. I read the rows from sqlite and checked them in the browser.timestamp,type,summary,metadata,object_name,source_objectall stored, although every field isreadonly: truerecord_idstored the literal natural keyrecord_id= the lead's runtime id (pxDFU7RFoMejXWbp= lisa.t@…,Cmp7aiCyo4Dr81PH= dkim@…).source_id= the event's runtime id (all 4 matchcrm_event.idby subject)sys_activity__r20260925behind thesys_activityview. Seeds usedaysAgo(1..9), and the builder filters out anything 14d or oldernew, planned call only) and Noah Patel both show Activity (0) / No activity recorded. The console's query wasGET /api/v1/data/sys_activity?filter=["and",["object_name","=","crm_lead"],["record_id","=",LEAD_ID]], and it answered 200 for all foursource_id, 0 nullrecord_id(the composite['source_object','source_id']key dedupes on resolved ids)Verification (at e0563de)
pnpm verifychain, one step at a time, exit codes captured before any pipe:validate 0 · typecheck 0 · lint 0 · lint:i18n-gate 0 · hygiene 0 · hygiene:tokens 0 · build 0 · test 0 (
Test Files 172 passed (172),Tests 3688 passed | 1 skipped (3689)).Reverse check of the new pin, with the fix committed first. I deleted the
leadInteractionPointers,registration line fromobjectstack.composition.ts(grep count 1, then 0). Expected direction: red. Observed: red,Tests 2 failed | 36 passed (38). The two that failed were "seeds a handful…" and "every held call or meeting … has its pointer". The per-row test stays green with zero rows, as expected, because the first test guards it. Restored withgit checkout HEAD -- objectstack.composition.tsunder a trap, andgit diff HEADcame back empty.Token ratchet before and after (base aa61e1d vs this branch): all 12 ceilings are unchanged and green. Seed data is outside the ratchet by ruling (
src/*/data). Its out-of-scope line moved from ~95,777 to ~96,270 tokens.objectstack.composition.tsis outsidesrc/, so the ratchet does not measure it.Acceptance notes
src/sales/data/index.ts"if registration is needed", butCrmSeedDatais assembled inobjectstack.composition.ts, because the replay order interleaves packages. So the registration is a one-line addition there, plus the import. No open PR touches that file.record_id/source_idnull. The loader's later seed pass filled them about 30s later (created_at13:17:03,updated_at13:17:33). This is the platform loader's deferral, not something this repo shapes. A tab opened in the first seconds after first boot can read empty. Noted only.actor_id/actor_nameare not authored). That is the same doctrine asowner_id.sys_activityretention is 14d, so on a long-running demo instance these rows age out. A replay boot re-evaluatesdaysAgo(), but it did not rewrite the existing rows in my replay measurement (updated_atunchanged).Generated by Claude Code