diff --git a/backend/src/api/public/v1/members/work-experiences/deleteMemberWorkExperience.ts b/backend/src/api/public/v1/members/work-experiences/deleteMemberWorkExperience.ts index 67ca87e14e..1b6305b3a8 100644 --- a/backend/src/api/public/v1/members/work-experiences/deleteMemberWorkExperience.ts +++ b/backend/src/api/public/v1/members/work-experiences/deleteMemberWorkExperience.ts @@ -46,7 +46,6 @@ export async function deleteMemberWorkExperience(req: Request, res: Response): P await qx.tx(async (tx) => { await deleteMemberOrganizations(tx, memberId, [workExperienceId]) - const commonMemberService = new CommonMemberService(tx, req.temporal, req.log) await commonMemberService.startAffiliationRecalculation(memberId, [ memberOrg.organizationId, diff --git a/services/apps/profiles_worker/src/activities/member/botSuggestion.ts b/services/apps/profiles_worker/src/activities/member/botSuggestion.ts index 7e75044e3e..bde90b3475 100644 --- a/services/apps/profiles_worker/src/activities/member/botSuggestion.ts +++ b/services/apps/profiles_worker/src/activities/member/botSuggestion.ts @@ -84,7 +84,7 @@ export async function updateMemberAttributes( export async function removeMemberOrganizations(memberId: string): Promise { try { const qx = pgpQx(svc.postgres.writer.connection()) - await deleteMemberOrganizations(qx, memberId, undefined, false) + await deleteMemberOrganizations(qx, memberId, undefined, true) } catch (error) { svc.log.error({ error, memberId }, `Failed to remove member organizations!`) throw error diff --git a/services/libs/data-access-layer/src/members/organizations.ts b/services/libs/data-access-layer/src/members/organizations.ts index 636bb87068..83c150ca89 100644 --- a/services/libs/data-access-layer/src/members/organizations.ts +++ b/services/libs/data-access-layer/src/members/organizations.ts @@ -335,11 +335,19 @@ export async function deleteMemberOrganizations( const query = `${baseQuery} WHERE ${whereClause};` await qx.tx(async (tx) => { + // Capture affected org IDs before the delete — needed for the cleanup step below, + // since a hard delete removes rows before we can look them up. + const affectedOrgs: { organizationId: string }[] = await tx.select( + `SELECT DISTINCT "organizationId" FROM "memberOrganizations" WHERE ${whereClause}`, + params, + ) + const affectedOrgIds = affectedOrgs.map((r) => r.organizationId) + // First delete from memberOrganizationAffiliationOverrides using the same conditions await tx.result( - `DELETE FROM "memberOrganizationAffiliationOverrides" + `DELETE FROM "memberOrganizationAffiliationOverrides" WHERE "memberOrganizationId" IN ( - SELECT "id" FROM "memberOrganizations" + SELECT "id" FROM "memberOrganizations" WHERE ${whereClause} )`, params, @@ -347,6 +355,22 @@ export async function deleteMemberOrganizations( // Then perform the soft/hard delete on memberOrganizations await tx.result(query, params) + + // Clean up segment affiliations for orgs that no longer have any active work experiences + if (affectedOrgIds.length > 0) { + await tx.result( + `DELETE FROM "memberSegmentAffiliations" msa + WHERE msa."memberId" = $(memberId) + AND msa."organizationId" IN ($(orgIds:csv)) + AND NOT EXISTS ( + SELECT 1 FROM "memberOrganizations" mo + WHERE mo."memberId" = $(memberId) + AND mo."organizationId" = msa."organizationId" + AND mo."deletedAt" IS NULL + )`, + { memberId, orgIds: affectedOrgIds }, + ) + } }) }