fix: prefer company over uni on overlap during affiliation (CM-1216)#4188
Merged
Conversation
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts member activity affiliation to prioritize the email domain present on an activity’s username as the strongest routing signal, aiming to prevent “university vs company” overlap cases from incorrectly affiliating to universities when there’s no email-domain evidence.
Changes:
- Added DAL support for fetching verified primary domains per organization and introduced a heuristic to prefer company affiliations over university affiliations during timeline overlaps.
- Updated affiliation resolution to (a) route by activity email domain when present, and (b) otherwise fall back to timestamp-based member organization timelines with a company-over-university preference.
- Updated ingest-time activity processing to derive the affiliation domain from the activity username (when it is a valid email) rather than from the member’s verified email identities.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| services/libs/data-access-layer/src/organizations/identities.ts | Adds org-domain fetch + overlap preference helper used by affiliation logic. |
| services/libs/data-access-layer/src/members/segments.ts | Changes work-experience query to enforce verified-domain matching when an activity domain is provided. |
| services/libs/data-access-layer/src/member-organization-affiliation/types.ts | Extends timeline items with domain-based routing fields. |
| services/libs/data-access-layer/src/member-organization-affiliation/index.ts | Adds domain-partitioned refresh passes to keep email-domain activities disjoint from timeline-based passes. |
| services/libs/common_services/src/services/common.member.service.ts | Updates per-activity affiliation decision flow to prioritize activity email domain and apply company-over-university preference. |
| services/apps/data_sink_worker/src/service/activity.service.ts | Switches ingest-time domain extraction to use the activity username (when it’s a valid email). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
ulemons
reviewed
Jun 10, 2026
ulemons
previously approved these changes
Jun 10, 2026
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
| timestamp: string, | ||
| emailDomain?: string, | ||
| orgDomain?: string, | ||
| ): Promise<IWorkExperienceData[] | null> { |
Comment on lines
+336
to
+339
| memberOrgDomains = await fetchManyOrganizationVerifiedPrimaryDomains( | ||
| qx, | ||
| organizationIds as string[], | ||
| ) |
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.
Summary
Affiliation logic now treats the email on an activity as the primary signal for determining which organization should be credited for that activity. When an activity does not contain an organization email, overlapping university and company affiliations are resolved in favor of the company.
This behavior now applies consistently during both ingest (
data_sink_worker) and bulk refresh (refreshMemberOrganizationAffiliations).Context
Member activities can be affiliated to an organization based on work history (
memberOrganizations), manual segment rules, and other fallback logic. That generally worked well for simple timelines, but broke down in a couple of cases:user@company.com,user@school.edu), but date-based affiliation logic resolved the activity to a different organization.The email used on an activity is first-party evidence of which organization the activity was performed on behalf of. It should take precedence over enrichment-derived timelines and generic tie-breakers (stint length, org size, source rank), unless a manual affiliation override has been configured.
What changed
Ingest (
findAffiliation)Affiliation resolution now follows this order:
memberOrganizationwhose organization has a matching verifiedprimary-domain.Only the email present on the activity username is considered. Member profile emails are not used as a substitute when the activity itself does not contain an email.
Bulk refresh (
prepareMemberOrganizationAffiliationTimeline)Bulk refresh now mirrors the same behavior used during ingest.
To avoid activities being processed twice, refresh runs in two passes:
Manual segment affiliations continue to take precedence through the existing segment-scoped timeline and
skipManualAffiliationSegmentsguards.Expected behavior
@company.com,@school.edu)