@@ -8,14 +8,19 @@ import {
88 MemberField ,
99 deleteMemberOrganizations ,
1010 fetchManyMemberOrgsWithOrgData ,
11+ fetchMemberOrganizations ,
1112 findMemberById ,
1213 optionsQx ,
1314 updateMemberOrganization ,
1415} from '@crowd/data-access-layer'
15- import { IMemberOrganization } from '@crowd/types'
16+ import { IMemberOrganization , IMemberRoleWithOrganization } from '@crowd/types'
1617
1718import { ok } from '@/utils/api'
18- import { toMemberWorkExperience } from '@/utils/mapper'
19+ import {
20+ getOverlappingEmailDomainMemberOrganizations ,
21+ groupMemberOrganizations ,
22+ toMemberWorkExperience ,
23+ } from '@/utils/mapper'
1924import { validateOrThrow } from '@/utils/validation'
2025
2126const paramsSchema = z . object ( {
@@ -40,13 +45,25 @@ export async function verifyMemberWorkExperience(req: Request, res: Response): P
4045 throw new NotFoundError ( 'Member not found' )
4146 }
4247
43- const orgsMap = await fetchManyMemberOrgsWithOrgData ( qx , [ memberId ] )
44- const memberOrg = ( orgsMap . get ( memberId ) ?? [ ] ) . find ( ( mo ) => mo . id === workExperienceId )
48+ const memberOrgs = await fetchMemberOrganizations ( qx , memberId )
49+ const memberOrg = memberOrgs . find ( ( mo ) => mo . id === workExperienceId )
4550
4651 if ( ! memberOrg ) {
4752 throw new NotFoundError ( 'Work experience not found' )
4853 }
4954
55+ const overlappingEmailDomainRows = getOverlappingEmailDomainMemberOrganizations (
56+ memberOrgs ,
57+ memberOrg ,
58+ )
59+
60+ const memberOrgIdsToDelete = [
61+ workExperienceId ,
62+ ...overlappingEmailDomainRows . flatMap ( ( row ) => ( row . id ? [ row . id ] : [ ] ) ) ,
63+ ]
64+
65+ const verifiedUpdate = { verified, verifiedBy }
66+
5067 let updatedMemberOrg : IMemberOrganization | undefined
5168
5269 await captureApiChange (
@@ -56,12 +73,22 @@ export async function verifyMemberWorkExperience(req: Request, res: Response): P
5673
5774 await qx . tx ( async ( tx ) => {
5875 if ( verified ) {
59- updatedMemberOrg = await updateMemberOrganization ( tx , memberId , workExperienceId , {
60- verified,
61- verifiedBy,
62- } )
76+ // Verification status belongs to the grouped work experience, not just the visible row
77+ updatedMemberOrg = await updateMemberOrganization (
78+ tx ,
79+ memberId ,
80+ workExperienceId ,
81+ verifiedUpdate ,
82+ )
83+
84+ for ( const overlappingRow of overlappingEmailDomainRows . filter (
85+ ( row ) : row is typeof row & { id : string } => ! ! row . id ,
86+ ) ) {
87+ await updateMemberOrganization ( tx , memberId , overlappingRow . id , verifiedUpdate )
88+ }
6389 } else {
64- await deleteMemberOrganizations ( tx , memberId , [ workExperienceId ] , true )
90+ // Unverifying removes the grouped work experience from both visible and hidden rows
91+ await deleteMemberOrganizations ( tx , memberId , memberOrgIdsToDelete , true )
6592 }
6693 } )
6794
@@ -76,5 +103,13 @@ export async function verifyMemberWorkExperience(req: Request, res: Response): P
76103 } ) ,
77104 )
78105
79- ok ( res , toMemberWorkExperience ( { ...memberOrg , ...updatedMemberOrg } ) )
106+ const orgsMap = await fetchManyMemberOrgsWithOrgData ( qx , [ memberId ] )
107+
108+ const responseMo : IMemberRoleWithOrganization =
109+ groupMemberOrganizations ( orgsMap . get ( memberId ) ?? [ ] ) . find (
110+ ( mo ) => mo . id === workExperienceId ,
111+ ) ??
112+ ( { ...memberOrg , ...updatedMemberOrg , verified, verifiedBy } as IMemberRoleWithOrganization )
113+
114+ ok ( res , toMemberWorkExperience ( responseMo ) )
80115}
0 commit comments