You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// The identity disappeared between INSERT and SELECT — unusual race condition.
237
+
// Cannot safely resolve; schedule orphan deletion and throw.
238
+
this.log.error(
239
+
{orphanMemberId: id, identity },
240
+
'Verified identity not found after conflict detection — scheduling orphan deletion',
241
+
)
242
+
awaitthis.scheduleOrphanMemberDeletion(id)
243
+
thrownewApplicationError(
244
+
`Identity conflict during member creation: owner not found for identity (${identity.platform}, ${identity.value}, ${identity.type})`,
245
+
)
246
+
}elseif(owner===id){
247
+
// Successfully inserted for the orphan — will be moved to the existing member below
248
+
orphanVerifiedIdentities.push(identity)
249
+
}elseif(!existingMemberId){
250
+
// First conflicting owner found
251
+
existingMemberId=owner
252
+
}elseif(existingMemberId!==owner){
253
+
// A second conflicting owner — two existing members each own a different verified
254
+
// identity of this incoming member, so the data source asserts they are the same
255
+
// person. Auto-merge the second into the first.
256
+
this.log.warn(
257
+
{
258
+
orphanMemberId: id,
259
+
primaryMemberId: existingMemberId,
260
+
secondaryMemberId: owner,
261
+
identity,
262
+
},
263
+
'Multiple conflicting verified identities belong to different existing members — merging automatically',
264
+
)
265
+
letmerged: boolean
266
+
try{
267
+
merged=awaitmergeIfAllowed(
268
+
this.pgQx,
269
+
this.temporal,
270
+
this.log,
271
+
existingMemberId,
272
+
owner,
273
+
)
274
+
}catch(mergeErr){
275
+
this.log.error(
276
+
mergeErr,
277
+
{
278
+
orphanMemberId: id,
279
+
primaryMemberId: existingMemberId,
280
+
secondaryMemberId: owner,
281
+
},
282
+
'Auto-merge of conflicting members failed — scheduling orphan deletion',
283
+
)
284
+
awaitthis.scheduleOrphanMemberDeletion(id)
285
+
thrownewApplicationError(
286
+
`Identity conflict during member creation: auto-merge of members ${existingMemberId} and ${owner} failed for identity (${identity.platform}, ${identity.value}, ${identity.type})`,
287
+
)
288
+
}
289
+
if(!merged){
290
+
this.log.error(
291
+
{
292
+
orphanMemberId: id,
293
+
primaryMemberId: existingMemberId,
294
+
secondaryMemberId: owner,
295
+
},
296
+
'Auto-merge prevented by noMerge record — scheduling orphan deletion',
297
+
)
298
+
awaitthis.scheduleOrphanMemberDeletion(id)
299
+
thrownewApplicationError(
300
+
`Identity conflict during member creation: members ${existingMemberId} and ${owner} are marked as no-merge but share identity (${identity.platform}, ${identity.value}, ${identity.type})`,
301
+
)
302
+
}
303
+
// existingMemberId (primary) survives; owner (secondary) was absorbed
304
+
this.log.info(
305
+
{
306
+
orphanMemberId: id,
307
+
survivingMemberId: existingMemberId,
308
+
mergedMemberId: owner,
309
+
identity,
310
+
},
311
+
'Auto-merge of conflicting members succeeded',
312
+
)
313
+
}
314
+
// else: owner === existingMemberId — same member owns this identity too, nothing to do
315
+
}
316
+
317
+
if(existingMemberId){
318
+
// Move any verified identities that were inserted for the orphan to the existing
319
+
// member so they are not lost when the orphan is cascade-deleted.
320
+
// UPDATE memberId rather than INSERT to avoid unique constraint violations.
// insertedCount < data.identities.length but no conflicting owner found — unexpected
363
+
this.log.error(
364
+
{memberId: id},
365
+
'Identity conflict during member creation but existing member not found — scheduling orphan deletion',
366
+
)
367
+
awaitthis.scheduleOrphanMemberDeletion(id)
368
+
thrownewApplicationError(
369
+
`Identity conflict during member creation for member ${id}: inserted ${insertedCount} of ${data.identities.length} identities but found no conflicting owner`,
0 commit comments