Przeglądaj źródła

fix(clients): avoid duplicate ClientRecord when email is changed on edit

SyncInbound (invoked from UpdateInboundClient during a client edit)
looks up the ClientRecord row by the email present in the inbound's
settings. After an email change the lookup misses the original row,
hits the gorm.ErrRecordNotFound branch, and inserts a fresh
ClientRecord with the new email. The original row stays in place with
its inbound link cleared, so the clients list shows both — the
original as an orphan and the new one as if it had just been created.

Rename the existing ClientRecord row to the new email up front, before
the inbound loop runs. SyncInbound then finds and updates the same
row instead of creating a duplicate. A pre-check rejects renames that
would collide with another client's email so the unique index keeps
its meaning.
MHSanaei 11 godzin temu
rodzic
commit
5eb80eca8e
1 zmienionych plików z 21 dodań i 0 usunięć
  1. 21 0
      web/service/client.go

+ 21 - 0
web/service/client.go

@@ -595,6 +595,27 @@ func (s *ClientService) Update(inboundSvc *InboundService, id int, updated model
 		updated.CreatedAt = existing.CreatedAt
 	}
 
+	// Rename the ClientRecord row up front when the email changes. SyncInbound
+	// (invoked from UpdateInboundClient below) looks up by email — without
+	// renaming first it would treat the new email as a brand-new client,
+	// insert a duplicate ClientRecord, and leave the original orphaned.
+	if updated.Email != existing.Email {
+		var collisionCount int64
+		if err := database.GetDB().Model(&model.ClientRecord{}).
+			Where("email = ? AND id <> ?", updated.Email, id).
+			Count(&collisionCount).Error; err != nil {
+			return false, err
+		}
+		if collisionCount > 0 {
+			return false, common.NewError("Duplicate email:", updated.Email)
+		}
+		if err := database.GetDB().Model(&model.ClientRecord{}).
+			Where("id = ?", id).
+			Update("email", updated.Email).Error; err != nil {
+			return false, err
+		}
+	}
+
 	needRestart := false
 	for _, ibId := range inboundIds {
 		inbound, getErr := inboundSvc.GetInbound(ibId)