Skip to content

Commit 6218794

Browse files
committed
fix: resolve pr comments
1 parent 82c510a commit 6218794

3 files changed

Lines changed: 54 additions & 98 deletions

File tree

backend/src/database/repositories/memberOrganizationRepository.ts

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -47,52 +47,6 @@ class MemberOrganizationRepository {
4747
return results as IMemberOrganization[]
4848
}
4949

50-
static async removeMemberRole(role: IMemberOrganization, options: IRepositoryOptions) {
51-
const seq = SequelizeRepository.getSequelize(options)
52-
const transaction = SequelizeRepository.getTransaction(options)
53-
54-
let deleteMemberRole = `DELETE FROM "memberOrganizations"
55-
WHERE
56-
"organizationId" = :organizationId and
57-
"memberId" = :memberId`
58-
59-
const replacements = {
60-
organizationId: role.organizationId,
61-
memberId: role.memberId,
62-
} as any
63-
64-
if (role.dateStart === null) {
65-
deleteMemberRole += ` and "dateStart" is null `
66-
} else {
67-
deleteMemberRole += ` and "dateStart" = :dateStart `
68-
replacements.dateStart = (role.dateStart as Date).toISOString()
69-
}
70-
71-
if (role.dateEnd === null) {
72-
deleteMemberRole += ` and "dateEnd" is null `
73-
} else {
74-
deleteMemberRole += ` and "dateEnd" = :dateEnd `
75-
replacements.dateEnd = (role.dateEnd as Date).toISOString()
76-
}
77-
78-
if (role.id) {
79-
await seq.query(
80-
`DELETE FROM "memberOrganizationAffiliationOverrides" WHERE "memberOrganizationId" = :roleId`,
81-
{
82-
replacements: { roleId: role.id },
83-
type: QueryTypes.DELETE,
84-
transaction,
85-
},
86-
)
87-
}
88-
89-
await seq.query(deleteMemberRole, {
90-
replacements,
91-
type: QueryTypes.DELETE,
92-
transaction,
93-
})
94-
}
95-
9650
static async findNonIntersectingRoles(
9751
primaryId: string,
9852
secondaryId: string,

services/libs/data-access-layer/src/member_organization_affiliation_overrides/index.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,3 @@ export async function findPrimaryWorkExperiencesOfMember(
160160
)
161161
return overrides
162162
}
163-
164-
export async function deleteAffiliationOverrides(
165-
qx: QueryExecutor,
166-
memberId: string,
167-
memberOrganizationIds: string[],
168-
): Promise<void> {
169-
await qx.result(
170-
`
171-
DELETE FROM "memberOrganizationAffiliationOverrides"
172-
WHERE "memberId" = $(memberId)
173-
AND "memberOrganizationId" IN ($(memberOrganizationIds:csv))
174-
`,
175-
{ memberId, memberOrganizationIds },
176-
)
177-
}

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

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77

88
import {
99
changeOverride,
10-
deleteAffiliationOverrides,
1110
findMemberAffiliationOverrides,
1211
findOrganizationAffiliationOverrides,
1312
} from '../member_organization_affiliation_overrides'
@@ -424,35 +423,51 @@ export async function findNonIntersectingRoles(
424423
}
425424

426425
export async function removeMemberRole(qx: QueryExecutor, role: IMemberOrganization) {
427-
if (role.id) {
428-
await deleteAffiliationOverrides(qx, role.memberId, [role.id])
429-
}
430-
431-
let deleteMemberRole = `DELETE FROM "memberOrganizations"
432-
WHERE
433-
"organizationId" = $(organizationId) and
434-
"memberId" = $(memberId)`
426+
const conditions = ['"organizationId" = $(organizationId)', '"memberId" = $(memberId)']
435427

436428
const replacements: Record<string, unknown> = {
437429
organizationId: role.organizationId,
438430
memberId: role.memberId,
439431
}
440432

441433
if (role.dateStart === null) {
442-
deleteMemberRole += ` and "dateStart" is null `
434+
conditions.push('"dateStart" IS NULL')
443435
} else {
444-
deleteMemberRole += ` and "dateStart" = $(dateStart) `
436+
conditions.push('"dateStart" = $(dateStart)')
445437
replacements.dateStart = (role.dateStart as Date).toISOString()
446438
}
447439

448440
if (role.dateEnd === null) {
449-
deleteMemberRole += ` and "dateEnd" is null `
441+
conditions.push('"dateEnd" IS NULL')
450442
} else {
451-
deleteMemberRole += ` and "dateEnd" = $(dateEnd) `
443+
conditions.push('"dateEnd" = $(dateEnd)')
452444
replacements.dateEnd = (role.dateEnd as Date).toISOString()
453445
}
454446

455-
await qx.result(deleteMemberRole, replacements)
447+
const whereClause = conditions.join(' AND ')
448+
449+
await qx.tx(async (tx) => {
450+
// Delete affiliation overrides first using subquery
451+
await tx.result(
452+
`
453+
DELETE FROM "memberOrganizationAffiliationOverrides"
454+
WHERE "memberOrganizationId" IN (
455+
SELECT id FROM "memberOrganizations"
456+
WHERE ${whereClause}
457+
)
458+
`,
459+
replacements,
460+
)
461+
462+
// Then delete the role
463+
await tx.result(
464+
`
465+
DELETE FROM "memberOrganizations"
466+
WHERE ${whereClause}
467+
`,
468+
replacements,
469+
)
470+
})
456471
}
457472

458473
export async function addMemberRole(
@@ -615,6 +630,22 @@ function transformRoleToTargetEntity(
615630
}
616631
}
617632

633+
function areDatesEqual(dateA: Date | string | null, dateB: Date | string | null): boolean {
634+
if (dateA === null && dateB === null) return true
635+
if (dateA === null || dateB === null) return false
636+
return new Date(dateA).getTime() === new Date(dateB).getTime()
637+
}
638+
639+
function isSamePrimaryRole(a: IMemberOrganization, b: IMemberOrganization): boolean {
640+
const isSameMember = a.memberId === b.memberId
641+
const isSameOrganization = a.organizationId === b.organizationId
642+
const isSameTitle = a.title === b.title
643+
const hasSameStartDate = areDatesEqual(a.dateStart, b.dateStart)
644+
const hasSameEndDate = areDatesEqual(a.dateEnd, b.dateEnd)
645+
646+
return isSameMember && isSameOrganization && isSameTitle && hasSameStartDate && hasSameEndDate
647+
}
648+
618649
export async function mergeRoles(
619650
qx: QueryExecutor,
620651
primaryRoles: IMemberOrganization[],
@@ -759,42 +790,28 @@ export async function mergeRoles(
759790
return item.role.memberId === addRole.memberId && item.role.title === addRole.title
760791
})
761792

762-
let overrideToApply: IMemberOrganizationAffiliationOverride | undefined
763793
if (relevantOverrides.length > 0) {
764794
// Prefer the override from the primary role if it exists
765795
const primaryOverride = relevantOverrides.find((item) =>
766796
primaryRoles.some((primaryRole) => primaryRole.id === item.role.id),
767797
)
768798

769799
// If we found a primary override, use it, otherwise, use the first one
770-
overrideToApply = primaryOverride?.override || relevantOverrides[0]?.override
771-
}
800+
const overrideToApply = primaryOverride?.override || relevantOverrides[0]?.override
772801

773-
if (overrideToApply) {
774-
await changeOverride(qx, {
775-
...overrideToApply,
776-
memberId: mergeStrat.targetMemberId(addRole),
777-
memberOrganizationId: newRoleId,
778-
})
802+
if (overrideToApply) {
803+
await changeOverride(qx, {
804+
...overrideToApply,
805+
memberId: mergeStrat.targetMemberId(addRole),
806+
memberOrganizationId: newRoleId,
807+
})
808+
}
779809
}
780810
} else {
781811
// Role already exists (duplicate), need to transfer override to existing role
782812

783813
// Find the existing role in primary that matches this addRole
784-
const existingPrimaryRole = primaryRoles.find(
785-
(pr) =>
786-
pr.memberId === addRole.memberId &&
787-
pr.organizationId === addRole.organizationId &&
788-
pr.title === addRole.title &&
789-
((pr.dateStart === null && addRole.dateStart === null) ||
790-
(pr.dateStart &&
791-
addRole.dateStart &&
792-
new Date(pr.dateStart).getTime() === new Date(addRole.dateStart).getTime())) &&
793-
((pr.dateEnd === null && addRole.dateEnd === null) ||
794-
(pr.dateEnd &&
795-
addRole.dateEnd &&
796-
new Date(pr.dateEnd).getTime() === new Date(addRole.dateEnd).getTime())),
797-
)
814+
const existingPrimaryRole = primaryRoles.find((pr) => isSamePrimaryRole(pr, addRole))
798815

799816
if (existingPrimaryRole) {
800817
// Find overrides from secondary roles that should be transferred

0 commit comments

Comments
 (0)