Files
twenty/packages/twenty-server
Thomas des Francs 41d1b478b0 Fix Opportunity email timeline relation traversal (#22064)
## Summary
- Stop the related-person path walker from traversing system objects
while deriving timeline people.
- Keep direct `person` terminal paths valid so CRM relations still
resolve.
- Add a regression test covering the bad Opportunity owner -> workspace
member -> message participant path.

## Root Cause
PR #21684 introduced generic relation traversal for email and calendar
timelines. That traversal walks relation paths from the current record
to `person`, then the Emails tab loads message threads for those derived
people.

For Opportunities, the traversal was too broad because it could enter
internal/system objects. In particular, it could follow:

`opportunity.owner -> workspaceMember.messageParticipants ->
messageParticipant.person`

That path does not describe people related to the Opportunity. It
describes people who appeared in messages involving the Opportunity
owner. As a result, an Opportunity owned by Josh could show threads from
Josh's broader mailbox activity, which matches the customer report:
recently communicated people appeared in the Opportunity Emails tab even
though they were not specifically related to that Opportunity.

## Behavior Before
On an Opportunity record, the Emails tab could include message threads
for:
- the Opportunity point of contact;
- people related through the Opportunity company;
- people reached through internal/system relations, including the owner
workspace member's message participants.

The last category was the regression. It made the Opportunity Emails tab
look like a broad inbox for the owner instead of a timeline for people
related to the CRM record.

## Behavior After
The traversal still allows valid CRM person paths, including:

`opportunity.pointOfContact -> person`

and non-system CRM paths such as:

`opportunity.company -> company.people -> person`

But it now stops before traversing system objects such as
`workspaceMember` and `messageParticipant`. This blocks the bad
owner-mailbox expansion path:

`opportunity.owner -> workspaceMember.messageParticipants ->
messageParticipant.person`

Email sync is unchanged. This only changes which synced emails are
displayed on a record timeline.

## Video


https://github.com/user-attachments/assets/26de4cee-06d9-4f42-b91e-32e60a260b5b

## Validation
- `yarn nx jest twenty-server
src/engine/core-modules/related-person-ids/utils/__tests__/find-relation-paths-to-person.util.spec.ts
--runInBand`
- Focused `oxlint` and `oxfmt` on the touched files.
- GitHub `server-lint-typecheck` passes on the updated branch.
- Browser verification on local Apple seed workspace: fixed relation set
renders `Inbox 280`; the excluded owner-derived path would have resolved
`300` threads.
2026-06-24 12:06:37 +02:00
..