fix(16): WR-02 discriminate P2002 target in group rename branch

syncBoundGroupsForTenant()'s rename write updates name and ldapDn in one
call, so a P2002 there can come from either @@unique([tenantId, name])
or @@unique([tenantId, ldapDn]). The catch previously reported every
P2002 as a name collision unconditionally; it now inspects
err.meta.target the same way importGroupsByDn() already does for its
own create() call, so a non-name unique violation is no longer
mislabelled and sent the admin down the wrong troubleshooting path.
This commit is contained in:
2026-08-06 16:57:34 +02:00
parent dd59bf592f
commit 19717954d6
2 changed files with 55 additions and 2 deletions
+14 -1
View File
@@ -1317,8 +1317,21 @@ export class LdapService {
result.groupsRenamed++;
} catch (updateError: any) {
if (updateError?.code === 'P2002') {
// WR-02 (16-REVIEW.md): this update() writes BOTH name and
// ldapDn in one call — @@unique([tenantId, name]) AND
// @@unique([tenantId, ldapDn]) are both potential triggers
// of a P2002 here, so the collision is only actually a name
// collision when updateError.meta.target says so. Mirrors
// the discrimination importGroupsByDn() already does above
// for its own create() call.
const target = updateError?.meta?.target;
const targetsName = Array.isArray(target)
? target.includes('name')
: String(target ?? '').includes('name');
result.errors.push(
`Gruppe ${group.name}: Umbenennung nach '${name}' kollidiert mit einer bestehenden Gruppe`,
targetsName
? `Gruppe ${group.name}: Umbenennung nach '${name}' kollidiert mit einer bestehenden Gruppe`
: `Gruppe ${group.name}: Aktualisierung kollidiert mit einer bestehenden Bindung (${JSON.stringify(target)})`,
);
} else {
throw updateError;