From 88a3677318116615ce80a4a2e6b5b9c3e7bea93e Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Mon, 1 Jun 2026 08:34:48 +0200 Subject: [PATCH] feat(clients): enforce unique subId per client like email Reject creating or editing a client with a subId already owned by a different client, mirroring the email-uniqueness checks against client_records in Create and Update (BulkCreate inherits via Create). The old multi-inbound model duplicated a client across inbounds sharing one subId, so this check was dropped; the first-class multi-client model makes per-client subId uniqueness correct again. Existing duplicates are left untouched; only new/edited duplicates are blocked. --- web/service/client.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/web/service/client.go b/web/service/client.go index 47cda809..c8113f00 100644 --- a/web/service/client.go +++ b/web/service/client.go @@ -475,6 +475,18 @@ func (s *ClientService) Create(inboundSvc *InboundService, payload *ClientCreate } } + if client.SubID != "" { + var subTaken int64 + if err := database.GetDB().Model(&model.ClientRecord{}). + Where("sub_id = ? AND email <> ?", client.SubID, client.Email). + Count(&subTaken).Error; err != nil { + return false, err + } + if subTaken > 0 { + return false, common.NewError("subId already in use:", client.SubID) + } + } + needRestart := false for _, ibId := range payload.InboundIds { inbound, getErr := inboundSvc.GetInbound(ibId) @@ -646,6 +658,18 @@ func (s *ClientService) Update(inboundSvc *InboundService, id int, updated model } } + if updated.SubID != "" { + var subCollision int64 + if err := database.GetDB().Model(&model.ClientRecord{}). + Where("sub_id = ? AND id <> ?", updated.SubID, id). + Count(&subCollision).Error; err != nil { + return false, err + } + if subCollision > 0 { + return false, common.NewError("Duplicate subId:", updated.SubID) + } + } + needRestart := false for _, ibId := range inboundIds { inbound, getErr := inboundSvc.GetInbound(ibId)