Skip to content

Commit ef99959

Browse files
authored
fix: soft delete member segment affiliations for blocked orgs (#4170)
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
1 parent 9cfc32d commit ef99959

25 files changed

Lines changed: 240 additions & 242 deletions

File tree

backend/src/api/public/v1/members/project-affiliations/patchProjectAffiliation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { NotFoundError } from '@crowd/common'
66
import { signalMemberUpdate } from '@crowd/common_services'
77
import {
88
MemberField,
9-
deleteAllMemberSegmentAffiliationsForProject,
109
fetchMemberProjectSegments,
1110
fetchMemberSegmentAffiliationsForProject,
1211
findMaintainerRoles,
@@ -15,6 +14,7 @@ import {
1514
optionsQx,
1615
} from '@crowd/data-access-layer'
1716
import type { ISegmentAffiliationWithOrg } from '@crowd/data-access-layer'
17+
import { deleteMemberSegmentAffiliations } from '@crowd/data-access-layer/src/member_segment_affiliations'
1818

1919
import { ok } from '@/utils/api'
2020
import { validateOrThrow } from '@/utils/validation'
@@ -80,7 +80,7 @@ export async function patchProjectAffiliation(req: Request, res: Response): Prom
8080
const orgIdsToRecalculate = [...new Set([...oldOrgIds, ...newOrgIds])]
8181

8282
await qx.tx(async (tx) => {
83-
await deleteAllMemberSegmentAffiliationsForProject(tx, memberId, projectId)
83+
await deleteMemberSegmentAffiliations(tx, { memberId, segmentId: projectId })
8484

8585
if (affiliations.length > 0) {
8686
await insertMemberSegmentAffiliations(

backend/src/api/public/v1/members/work-experiences/createMemberWorkExperience.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
findMemberById,
2020
optionsQx,
2121
} from '@crowd/data-access-layer'
22+
import { deleteMemberSegmentAffiliations } from '@crowd/data-access-layer/src/member_segment_affiliations'
2223
import type {
2324
IMemberOrganization,
2425
IMemberRoleWithOrganization,
@@ -104,6 +105,10 @@ export async function createMemberWorkExperience(req: Request, res: Response): P
104105
allowAffiliation: false,
105106
},
106107
])
108+
await deleteMemberSegmentAffiliations(tx, {
109+
memberId,
110+
organizationId: data.organizationId,
111+
})
107112
}
108113
})
109114

backend/src/bin/scripts/backfill-email-domain-member-organization-dates.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
updateMemberOrganization,
1313
} from '@crowd/data-access-layer'
1414
import { getDbConnection } from '@crowd/data-access-layer/src/database'
15+
import { deleteMemberSegmentAffiliations } from '@crowd/data-access-layer/src/member_segment_affiliations'
1516
import { chunkArray } from '@crowd/data-access-layer/src/old/apps/merge_suggestions_worker/utils'
1617
import { getServiceLogger } from '@crowd/logging'
1718
import { getRedisClient } from '@crowd/redis'
@@ -129,6 +130,10 @@ setImmediate(async () => {
129130
allowAffiliation: false,
130131
},
131132
])
133+
await deleteMemberSegmentAffiliations(tx, {
134+
memberId,
135+
organizationId: change.organizationId,
136+
})
132137
}
133138
} else if (change.type === 'update') {
134139
await updateMemberOrganization(tx, memberId, change.id, {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
alter table "memberSegmentAffiliations"
2+
add column if not exists "deletedAt" timestamp with time zone default null;

backend/src/database/repositories/member/memberAffiliationsRepository.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { OrganizationField, queryOrgs } from '@crowd/data-access-layer'
22
import {
3-
deleteMemberAffiliations,
3+
deleteMemberSegmentAffiliations,
44
fetchMemberAffiliations,
55
insertMemberAffiliations,
66
} from '@crowd/data-access-layer/src/member_segment_affiliations'
@@ -86,7 +86,7 @@ class MemberAffiliationsRepository {
8686
const qx = SequelizeRepository.getQueryExecutor(txOptions)
8787

8888
// Delete all member affiliations
89-
await deleteMemberAffiliations(qx, memberId)
89+
await deleteMemberSegmentAffiliations(qx, { memberId })
9090

9191
if (data?.length > 0) {
9292
// Insert multiple member affiliations

backend/src/database/repositories/member/memberOrganizationAffiliationOverridesRepository.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import {
22
changeMemberOrganizationAffiliationOverrides,
3+
fetchMemberOrganizationById,
34
findMemberAffiliationOverrides,
45
findPrimaryWorkExperiencesOfMember,
56
} from '@crowd/data-access-layer'
7+
import { deleteMemberSegmentAffiliations } from '@crowd/data-access-layer/src/member_segment_affiliations'
68
import {
79
IChangeAffiliationOverrideData,
810
IMemberOrganizationAffiliationOverride,
@@ -16,6 +18,20 @@ class MemberOrganizationAffiliationOverridesRepository {
1618
const qx = SequelizeRepository.getQueryExecutor(options)
1719

1820
await changeMemberOrganizationAffiliationOverrides(qx, [data])
21+
22+
const { allowAffiliation, memberId, memberOrganizationId } = data
23+
24+
if (allowAffiliation === false && memberId && memberOrganizationId) {
25+
const memberOrganization = await fetchMemberOrganizationById(qx, memberOrganizationId)
26+
27+
if (memberOrganization?.organizationId) {
28+
await deleteMemberSegmentAffiliations(qx, {
29+
memberId,
30+
organizationId: memberOrganization.organizationId,
31+
})
32+
}
33+
}
34+
1935
const overrides = await findMemberAffiliationOverrides(qx, data.memberId, [
2036
data.memberOrganizationId,
2137
])

backend/src/database/repositories/memberRepository.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import lodash, { chunk, uniq } from 'lodash'
22
import Sequelize, { QueryTypes } from 'sequelize'
33

4-
import { captureApiChange, memberCreateAction, memberEditProfileAction } from '@crowd/audit-logs'
4+
import {
5+
captureApiChange,
6+
memberCreateAction,
7+
memberEditAffiliationsAction,
8+
memberEditProfileAction,
9+
} from '@crowd/audit-logs'
510
import {
611
DEFAULT_TENANT_ID,
712
Error400,
@@ -25,6 +30,11 @@ import {
2530
import { findManyLfxMemberships } from '@crowd/data-access-layer/src/lfx_memberships'
2631
import { findMaintainerRoles } from '@crowd/data-access-layer/src/maintainers'
2732
import { addMemberNoMerge, removeMemberToMerge } from '@crowd/data-access-layer/src/member_merge'
33+
import {
34+
deleteMemberSegmentAffiliations,
35+
findMemberAffiliations,
36+
insertMemberAffiliations,
37+
} from '@crowd/data-access-layer/src/member_segment_affiliations'
2838
import {
2939
MemberField,
3040
fetchManyMemberIdentities,
@@ -67,7 +77,6 @@ import { AttributeData } from '../attributes/attribute'
6777

6878
import { IRepositoryOptions } from './IRepositoryOptions'
6979
import MemberAttributeSettingsRepository from './memberAttributeSettingsRepository'
70-
import MemberSegmentAffiliationRepository from './memberSegmentAffiliationRepository'
7180
import SegmentRepository from './segmentRepository'
7281
import SequelizeRepository from './sequelizeRepository'
7382
import TenantRepository from './tenantRepository'
@@ -1128,8 +1137,31 @@ class MemberRepository {
11281137
data: MemberSegmentAffiliation[],
11291138
options: IRepositoryOptions,
11301139
): Promise<void> {
1131-
const affiliationRepository = new MemberSegmentAffiliationRepository(options)
1132-
await affiliationRepository.setForMember(memberId, data)
1140+
const qx = optionsQx(options)
1141+
await captureApiChange(
1142+
options,
1143+
memberEditAffiliationsAction(memberId, async (captureOldState, captureNewState) => {
1144+
const oldOnes = await findMemberAffiliations(qx, memberId)
1145+
captureOldState(
1146+
oldOnes.map((item) => ({
1147+
segmentId: item.segmentId,
1148+
organizationId: item.organizationId,
1149+
dateStart: item.dateStart,
1150+
dateEnd: item.dateEnd,
1151+
})),
1152+
)
1153+
1154+
captureNewState(data)
1155+
1156+
await deleteMemberSegmentAffiliations(qx, { memberId })
1157+
1158+
if (data.length === 0) {
1159+
return
1160+
}
1161+
1162+
await insertMemberAffiliations(qx, memberId, data)
1163+
}),
1164+
)
11331165
}
11341166

11351167
static async getAffiliations(
@@ -1155,6 +1187,7 @@ class MemberRepository {
11551187
left join organizations o on o.id = msa."organizationId"
11561188
join segments s on s.id = msa."segmentId"
11571189
where msa."memberId" = :memberId
1190+
and msa."deletedAt" is null
11581191
`
11591192

11601193
const data = await seq.query(query, {

backend/src/database/repositories/memberSegmentAffiliationRepository.ts

Lines changed: 0 additions & 164 deletions
This file was deleted.

backend/src/services/member/memberOrganizationsService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
queryOrgs,
1818
updateMemberOrganization,
1919
} from '@crowd/data-access-layer'
20+
import { deleteMemberSegmentAffiliations } from '@crowd/data-access-layer/src/member_segment_affiliations'
2021
import { LoggerBase } from '@crowd/logging'
2122
import {
2223
IMemberOrganization,
@@ -186,6 +187,7 @@ export default class MemberOrganizationsService extends LoggerBase {
186187
allowAffiliation: false,
187188
},
188189
])
190+
await deleteMemberSegmentAffiliations(qx, { memberId, organizationId: data.organizationId })
189191
}
190192

191193
// Fetch updated list

backend/src/services/organizationService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '@crowd/data-access-layer'
1717
import { hasLfxMembership } from '@crowd/data-access-layer/src/lfx_memberships'
1818
import { applyOrganizationAffiliationPolicyToMembers } from '@crowd/data-access-layer/src/member-organization-affiliation'
19+
import { deleteMemberSegmentAffiliations } from '@crowd/data-access-layer/src/member_segment_affiliations'
1920
import {
2021
addMergeAction,
2122
queryMergeActions,
@@ -1074,6 +1075,9 @@ export default class OrganizationService extends LoggerBase {
10741075
data.isAffiliationBlocked !== existingOrg.isAffiliationBlocked
10751076
) {
10761077
await applyOrganizationAffiliationPolicyToMembers(qx, record.id, !data.isAffiliationBlocked)
1078+
if (data.isAffiliationBlocked) {
1079+
await deleteMemberSegmentAffiliations(qx, { organizationId: record.id })
1080+
}
10771081
recalculateAffiliations = true
10781082
}
10791083

0 commit comments

Comments
 (0)