diff --git a/internal/user/contact.go b/internal/user/contact.go index ed992042..9160ac55 100644 --- a/internal/user/contact.go +++ b/internal/user/contact.go @@ -51,20 +51,22 @@ func (u *Manager) CreateContact(user *models.User) error { } if user.Email.Valid && user.Email.String != "" { - // Reuse any existing contact with this email, preferring one with ext_id if multiple exist. + // An ext_id contact owns this email - reuse it; the no-ext-id upsert below can't match it and would insert a duplicate. existing, err := u.GetContactByEmail(user.Email.String) - if err == nil { + if err == nil && existing.ExternalUserID.String != "" { user.ID = existing.ID return nil } // Other error than not found - fail. - if envErr, ok := err.(envelope.Error); !ok || envErr.ErrorType != envelope.NotFoundError { - return err + if err != nil { + if envErr, ok := err.(envelope.Error); !ok || envErr.ErrorType != envelope.NotFoundError { + return err + } } } - // No ext_id and no existing contact with email - create new. + // No ext_id contact for this email - insert new, or update the existing no-ext-id contact's name. if err := u.q.InsertContactNoExtID.QueryRow(user.Email, user.FirstName, user.LastName, password, user.AvatarURL).Scan(&user.ID); err != nil { u.lo.Error("error inserting contact", "error", err) return fmt.Errorf("insert contact: %w", err) diff --git a/internal/user/queries.sql b/internal/user/queries.sql index 839697d3..58d0adcc 100644 --- a/internal/user/queries.sql +++ b/internal/user/queries.sql @@ -169,7 +169,10 @@ RETURNING user_id; INSERT INTO users (email, type, first_name, last_name, "password", avatar_url, external_user_id, custom_attributes) VALUES ($1, 'contact', $2, $3, $4, $5, $6, $7) ON CONFLICT (external_user_id) WHERE type = 'contact' AND deleted_at IS NULL AND external_user_id IS NOT NULL -DO UPDATE SET email = EXCLUDED.email, first_name = EXCLUDED.first_name, last_name = EXCLUDED.last_name, updated_at = now() +DO UPDATE SET email = COALESCE(NULLIF(EXCLUDED.email, ''), users.email), + first_name = COALESCE(NULLIF(EXCLUDED.first_name, ''), users.first_name), + last_name = COALESCE(NULLIF(EXCLUDED.last_name, ''), users.last_name), + updated_at = now() RETURNING id; -- name: insert-contact-without-external-id