diff --git a/services/apps/members_enrichment_worker/src/activities/enrichment.ts b/services/apps/members_enrichment_worker/src/activities/enrichment.ts index 1d494e3e8a..8534b4a4ea 100644 --- a/services/apps/members_enrichment_worker/src/activities/enrichment.ts +++ b/services/apps/members_enrichment_worker/src/activities/enrichment.ts @@ -244,7 +244,7 @@ export async function getPriorityArray(): Promise { export async function fetchMemberDataForLLMSquashing( memberId: string, -): Promise { +): Promise { return fetchMemberDataForLLMSquashingDb(svc.postgres.reader.connection(), memberId) } @@ -601,6 +601,7 @@ export async function updateMemberUsingSquashedPayload( existingMemberData.organizations, squashedPayload.memberOrganizations, isHighConfidenceSourceSelectedForWorkExperiences, + new Set(existingMemberData.deletedOrganizations.map((o) => o.orgId)), ) // Enrichment often deletes and recreates the same orgs with identical dates. @@ -834,12 +835,16 @@ function prepareWorkExperiences( oldVersion: IMemberOrganizationData[], newVersion: IMemberEnrichmentDataNormalizedOrganization[], isHighConfidenceSourceSelectedForWorkExperiences: boolean, + deletedOrganizationIds: Set, ): IWorkExperienceChanges { // we delete all the work experiences that were not manually created or from the project registry. const toDelete = oldVersion.filter( (c) => c.source !== OrganizationSource.UI && c.source !== OrganizationSource.PROJECT_REGISTRY, ) + // never recreate an affiliation that was manually deleted — enrichment providers keep resupplying it + newVersion = newVersion.filter((e) => !deletedOrganizationIds.has(e.organizationId)) + const toCreate: IMemberEnrichmentDataNormalizedOrganization[] = [] // eslint-disable-next-line @typescript-eslint/no-explicit-any const toUpdate: Map> = new Map() diff --git a/services/libs/data-access-layer/src/old/apps/members_enrichment_worker/index.ts b/services/libs/data-access-layer/src/old/apps/members_enrichment_worker/index.ts index 51ffd36fc5..e6421d433e 100644 --- a/services/libs/data-access-layer/src/old/apps/members_enrichment_worker/index.ts +++ b/services/libs/data-access-layer/src/old/apps/members_enrichment_worker/index.ts @@ -57,7 +57,13 @@ export async function fetchMemberDataForLLMSquashing( where mo."memberId" = $(memberId) and mo."deletedAt" is null and o."deletedAt" is null - group by mo."memberId", mo."organizationId", o."displayName", mo.id) + group by mo."memberId", mo."organizationId", o."displayName", mo.id), + deleted_member_orgs as (select distinct + mo."organizationId" as "orgId" + from "memberOrganizations" mo + where mo."memberId" = $(memberId) + and mo."deletedAt" is not null + and mo.source not in ('ui', 'project-registry')) select m."displayName", m.attributes, m."manuallyChangedFields", @@ -90,7 +96,10 @@ export async function fetchMemberDataForLLMSquashing( where mo."memberId" = m.id ) else '[]'::json - end as organizations + end as organizations, + coalesce( + (select json_agg(jsonb_build_object('orgId', d."orgId") order by d."orgId") from deleted_member_orgs d), '[]'::json + ) as "deletedOrganizations" from members m where m.id = $(memberId) and m."deletedAt" is null diff --git a/services/libs/types/src/enrichment.ts b/services/libs/types/src/enrichment.ts index 831de9d529..e1b21d95a4 100644 --- a/services/libs/types/src/enrichment.ts +++ b/services/libs/types/src/enrichment.ts @@ -43,6 +43,10 @@ export interface IMemberOrganizationData { identities?: IOrganizationIdentity[] } +export interface IDeletedMemberOrganizationData { + orgId: string +} + export interface IMemberOriginalData { // members table data displayName: string @@ -55,6 +59,8 @@ export interface IMemberOriginalData { // memberOrganizations table data organizations: IMemberOrganizationData[] + // memberOrganizations rows manually deleted, source not UI/PROJECT_REGISTRY — tombstones enrichment must not recreate + deletedOrganizations: IDeletedMemberOrganizationData[] } export interface IOrganizationEnrichmentCache {