refactor(service): move all client mutation methods to ClientService

Moves the client mutation surface out of InboundService and into
ClientService. These methods all operate on a single client (identity
fields, traffic limits, expiry, ip limit, enable state, telegram tg id)
and didn't belong on the inbound aggregate.

Moved (12 methods): AddInboundClient, UpdateInboundClient, DelInboundClient,
DelInboundClientByEmail, checkEmailsExistForClients, SetClientTelegramUserID,
checkIsEnabledByEmail, ToggleClientEnableByEmail, SetClientEnableByEmail,
ResetClientIpLimitByEmail, ResetClientExpiryTimeByEmail,
ResetClientTrafficLimitByEmail.

Each method now takes an explicit *InboundService for the helpers that
legitimately stay on InboundService (GetInbound, GetClients, runtimeFor,
AddClientStat / UpdateClientStat / DelClientStat, DelClientIPs /
UpdateClientIPs, emailUsedByOtherInbounds, getAllEmailSubIDs,
GetClientInboundByEmail / GetClientInboundByTrafficID,
GetClientTrafficByEmail).

Stays on InboundService: ResetClientTrafficByEmail and
ResetClientTraffic(id, email) — these mutate xray_client_traffic rows,
not client identity, so they're inbound-side bookkeeping.

Callers updated: tgbot (6 calls), ldap_sync_job (1 call),
InboundService internal (writeBackClientSubID, CopyInboundClients,
AddInbound's email-uniqueness check), ClientService Create/Update/
Delete/Attach/Detach.

Also removes a dead resetAllClientTraffics controller handler whose
route was already gone after the previous /clients API migration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MHSanaei 2026-05-17 10:48:28 +02:00
parent 960bd3c832
commit d4ddf702de
No known key found for this signature in database
GPG key ID: 7E4060F2FBE5AB7A
5 changed files with 1031 additions and 1070 deletions

View file

@ -261,24 +261,6 @@ func (a *InboundController) resetAllTraffics(c *gin.Context) {
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.resetAllTrafficSuccess"), nil)
}
// resetAllClientTraffics resets traffic counters for all clients in a specific inbound.
func (a *InboundController) resetAllClientTraffics(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.inboundUpdateSuccess"), err)
return
}
err = a.inboundService.ResetAllClientTraffics(id)
if err != nil {
jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err)
return
} else {
a.xrayService.SetToNeedRestart()
}
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.resetAllClientTrafficSuccess"), nil)
}
// importInbound imports an inbound configuration from provided data.
func (a *InboundController) importInbound(c *gin.Context) {
inbound := &model.Inbound{}
@ -372,4 +354,3 @@ func (a *InboundController) setFallbackChildren(c *gin.Context) {
a.xrayService.SetToNeedRestart()
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.inboundUpdateSuccess"), nil)
}

View file

@ -222,7 +222,7 @@ func (j *LdapSyncJob) batchSetEnable(ib *model.Inbound, emails []string, enable
restartNeeded := false
changed := 0
for _, email := range emails {
ok, needRestart, err := j.inboundService.SetClientEnableByEmail(email, enable)
ok, needRestart, err := j.clientService.SetClientEnableByEmail(&j.inboundService, email, enable)
if err != nil {
logger.Warningf("Batch set enable failed for %s in inbound %s: %v", email, ib.Tag, err)
continue

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -629,7 +629,7 @@ func (t *Tgbot) OnReceive() {
if checkAdmin(message.From.ID) {
for _, sharedUser := range message.UsersShared.Users {
userID := sharedUser.UserID
needRestart, err := t.inboundService.SetClientTelegramUserID(message.UsersShared.RequestID, userID)
needRestart, err := t.clientService.SetClientTelegramUserID(&t.inboundService, message.UsersShared.RequestID, userID)
if needRestart {
t.xrayService.SetToNeedRestart()
}
@ -900,7 +900,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 3 {
limitTraffic, err := strconv.Atoi(dataArray[2])
if err == nil {
needRestart, err := t.inboundService.ResetClientTrafficLimitByEmail(email, limitTraffic)
needRestart, err := t.clientService.ResetClientTrafficLimitByEmail(&t.inboundService, email, limitTraffic)
if needRestart {
t.xrayService.SetToNeedRestart()
}
@ -1109,7 +1109,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
}
}
needRestart, err := t.inboundService.ResetClientExpiryTimeByEmail(email, date)
needRestart, err := t.clientService.ResetClientExpiryTimeByEmail(&t.inboundService, email, date)
if needRestart {
t.xrayService.SetToNeedRestart()
}
@ -1306,7 +1306,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 3 {
count, err := strconv.Atoi(dataArray[2])
if err == nil {
needRestart, err := t.inboundService.ResetClientIpLimitByEmail(email, count)
needRestart, err := t.clientService.ResetClientIpLimitByEmail(&t.inboundService, email, count)
if needRestart {
t.xrayService.SetToNeedRestart()
}
@ -1520,7 +1520,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
return
}
needRestart, err := t.inboundService.SetClientTelegramUserID(traffic.Id, EmptyTelegramUserID)
needRestart, err := t.clientService.SetClientTelegramUserID(&t.inboundService, traffic.Id, EmptyTelegramUserID)
if needRestart {
t.xrayService.SetToNeedRestart()
}
@ -1541,7 +1541,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
)
t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
case "toggle_enable_c":
enabled, needRestart, err := t.inboundService.ToggleClientEnableByEmail(email)
enabled, needRestart, err := t.clientService.ToggleClientEnableByEmail(&t.inboundService, email)
if needRestart {
t.xrayService.SetToNeedRestart()
}
@ -3115,7 +3115,7 @@ func (t *Tgbot) clientInfoMsg(
}
enabled := ""
isEnabled, err := t.inboundService.checkIsEnabledByEmail(traffic.Email)
isEnabled, err := t.clientService.checkIsEnabledByEmail(&t.inboundService, traffic.Email)
if err != nil {
logger.Warning(err)
enabled = t.I18nBot("tgbot.wentWrong")