Skip to content

Commit bc2e323

Browse files
authored
chore: cleanup project affiliations after the last member organizations row is deleted (#3941)
Signed-off-by: Uroš Marolt <uros@marolt.me>
1 parent 6d16d0d commit bc2e323

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export async function deleteMemberWorkExperience(req: Request, res: Response): P
4646

4747
await qx.tx(async (tx) => {
4848
await deleteMemberOrganizations(tx, memberId, [workExperienceId])
49-
5049
const commonMemberService = new CommonMemberService(tx, req.temporal, req.log)
5150
await commonMemberService.startAffiliationRecalculation(memberId, [
5251
memberOrg.organizationId,

services/apps/profiles_worker/src/activities/member/botSuggestion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export async function updateMemberAttributes(
8484
export async function removeMemberOrganizations(memberId: string): Promise<void> {
8585
try {
8686
const qx = pgpQx(svc.postgres.writer.connection())
87-
await deleteMemberOrganizations(qx, memberId, undefined, false)
87+
await deleteMemberOrganizations(qx, memberId, undefined, true)
8888
} catch (error) {
8989
svc.log.error({ error, memberId }, `Failed to remove member organizations!`)
9090
throw error

services/libs/data-access-layer/src/members/organizations.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,18 +335,42 @@ export async function deleteMemberOrganizations(
335335
const query = `${baseQuery} WHERE ${whereClause};`
336336

337337
await qx.tx(async (tx) => {
338+
// Capture affected org IDs before the delete — needed for the cleanup step below,
339+
// since a hard delete removes rows before we can look them up.
340+
const affectedOrgs: { organizationId: string }[] = await tx.select(
341+
`SELECT DISTINCT "organizationId" FROM "memberOrganizations" WHERE ${whereClause}`,
342+
params,
343+
)
344+
const affectedOrgIds = affectedOrgs.map((r) => r.organizationId)
345+
338346
// First delete from memberOrganizationAffiliationOverrides using the same conditions
339347
await tx.result(
340-
`DELETE FROM "memberOrganizationAffiliationOverrides"
348+
`DELETE FROM "memberOrganizationAffiliationOverrides"
341349
WHERE "memberOrganizationId" IN (
342-
SELECT "id" FROM "memberOrganizations"
350+
SELECT "id" FROM "memberOrganizations"
343351
WHERE ${whereClause}
344352
)`,
345353
params,
346354
)
347355

348356
// Then perform the soft/hard delete on memberOrganizations
349357
await tx.result(query, params)
358+
359+
// Clean up segment affiliations for orgs that no longer have any active work experiences
360+
if (affectedOrgIds.length > 0) {
361+
await tx.result(
362+
`DELETE FROM "memberSegmentAffiliations" msa
363+
WHERE msa."memberId" = $(memberId)
364+
AND msa."organizationId" IN ($(orgIds:csv))
365+
AND NOT EXISTS (
366+
SELECT 1 FROM "memberOrganizations" mo
367+
WHERE mo."memberId" = $(memberId)
368+
AND mo."organizationId" = msa."organizationId"
369+
AND mo."deletedAt" IS NULL
370+
)`,
371+
{ memberId, orgIds: affectedOrgIds },
372+
)
373+
}
350374
})
351375
}
352376

0 commit comments

Comments
 (0)