Fixed actor merge failing if multiple source actors have profiles for same entity.

This commit is contained in:
2026-07-01 20:45:57 +02:00
parent 244dc4fff6
commit 514f51f111

View File

@@ -616,9 +616,11 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
let mergedActorStashes = []; let mergedActorStashes = [];
try { try {
const [existingProfiles] = await Promise.all([ const [existingProfiles, sourceProfiles] = await Promise.all([
trx('actors_profiles') trx('actors_profiles')
.where('actor_id', targetActorId), .where('actor_id', targetActorId),
trx('actors_profiles')
.whereIn('actor_id', sourceActorIds),
trx('actors') trx('actors')
.update('alias_for', targetActorId) .update('alias_for', targetActorId)
.whereIn('id', sourceActorIds) .whereIn('id', sourceActorIds)
@@ -629,11 +631,19 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
.whereIn('actor_id', sourceActorIds), .whereIn('actor_id', sourceActorIds),
]); ]);
// multiple source actors may provide profiles for the same entity, but we can only assign one to the target actor; prefer the newest
const newestSourceProfileMap = Object.fromEntries(sourceProfiles
.toSorted((profileA, profileB) => profileA.updated_at - profileB.updated_at)
.map((profile) => [profile.entity_id, profile.id]));
const duplicateSourceProfiles = sourceProfiles.filter((profile) => newestSourceProfileMap[profile.entity_id] && newestSourceProfileMap[profile.entity_id] !== profile.id);
// assign source actor profiles to target actor, unless a profile for that entity is already present // assign source actor profiles to target actor, unless a profile for that entity is already present
mergedProfiles = await trx('actors_profiles') mergedProfiles = await trx('actors_profiles')
.update('actor_id', targetActorId) .update('actor_id', targetActorId)
.whereIn('actor_id', sourceActorIds) .whereIn('actor_id', sourceActorIds)
.whereNotIn('entity_id', existingProfiles.map((profile) => profile.entity_id)) .whereNotIn('entity_id', existingProfiles.map((profile) => profile.entity_id))
.whereNotIn('id', duplicateSourceProfiles.map((profile) => profile.id))
.returning('id'); .returning('id');
// find releases that have more than one source actor assigned // find releases that have more than one source actor assigned