-
Notifications
You must be signed in to change notification settings - Fork 731
feat: source-priority tiebreaker in affiliation timeline builder (CM-1106) #4055
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
25bcf9a
97f5dd7
4e39c64
f29056f
99097ff
2004aa2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| import _ from 'lodash' | ||
| import { v4 as uuid } from 'uuid' | ||
|
|
||
| import { getLongestDateRange } from '@crowd/common' | ||
| import { getLongestDateRange, getMemberOrganizationSourceRank } from '@crowd/common' | ||
| import { getServiceChildLogger } from '@crowd/logging' | ||
| import { | ||
| IChangeAffiliationOverrideData, | ||
|
|
@@ -81,7 +81,16 @@ async function prepareMemberOrganizationAffiliationTimeline( | |
| return withDates[0] | ||
| } | ||
|
|
||
| // 2. get the two orgs with the most members, and return the one with the most members if there's no draw | ||
| // 2. among dated rows, pick the best source tier (ui > email-domain > enrichment-*) | ||
| if (withDates.length > 1) { | ||
| const sourceRank = (row: AffiliationItem) => | ||
| getMemberOrganizationSourceRank((row as MemberOrganizationWithOverrides).source) | ||
| const bestRank = Math.min(...withDates.map(sourceRank)) | ||
| orgs = withDates.filter((row) => sourceRank(row) === bestRank) | ||
| if (orgs.length === 1) return orgs[0] | ||
|
skwowet marked this conversation as resolved.
Comment on lines
+86
to
+90
|
||
| } | ||
|
skwowet marked this conversation as resolved.
|
||
|
|
||
| // 3. get the two orgs with the most members, and return the one with the most members if there's no draw | ||
| // only compare member orgs (manual affiliations don't have memberCount) | ||
| const memberOrgsOnly = orgs.filter( | ||
| (row: AffiliationItem) => 'segmentId' in row && !!row.segmentId, | ||
|
|
@@ -93,7 +102,7 @@ async function prepareMemberOrganizationAffiliationTimeline( | |
| } | ||
| } | ||
|
|
||
| // 3. there's a draw, return the one with the longer date range | ||
| // 4. there's a draw, return the one with the longer date range | ||
| return getLongestDateRange(orgs) | ||
| } | ||
| } | ||
|
|
@@ -243,6 +252,7 @@ async function prepareMemberOrganizationAffiliationTimeline( | |
| mo."dateStart", | ||
| mo."dateEnd", | ||
| mo."createdAt", | ||
| mo."source", | ||
| coalesce(ovr."isPrimaryWorkExperience", false) as "isPrimaryWorkExperience", | ||
| coalesce(a.total_count, 0) as "memberCount" | ||
| FROM "memberOrganizations" mo | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This computes
getMemberOrganizationSourceRank(r.source)twice per row (once forbestRank, once for filtering). Consider computing ranks once (e.g., map to{row, rank}) to avoid duplicated work and guarantee consistent ranking if the function changes.