fix(inbounds): keep stored client lifecycle and counters on inbound save

Invariant: saving an inbound's configuration never changes a client's
enable, expiry, quota or renewal state, nor the inbound's own traffic
counters. The inbound modal posts back the whole settings.clients list it
loaded when it opened, and UpdateInbound stored it, synced it into the
client records and wrote it into client_traffics. Any client renewed,
depleted or reset while the modal was open was reverted - a renewed client
came back disabled with its old expiry. The row itself was read before the
serialized tx and saved whole, so traffic the poll added in between was
rolled back and a depleted inbound could be re-enabled.

UpdateInbound now re-reads the row inside the writer and, for clients the
inbound already holds, keeps enable, expiryTime, totalGB, reset, resetDay,
resetWeekday and resetMax from it; those change through the client
endpoints. A master's node-sync push stays authoritative. Existing clients'
lifecycle fields are no longer editable through the inbound JSON editor or
/inbounds/update, which the API docs now state.
This commit is contained in:
MHSanaei
2026-09-28 02:23:32 +02:00
parent 17d7dd46b5
commit 1110caaa65
7 changed files with 164 additions and 11 deletions
@@ -60,10 +60,12 @@ _openapi:
at most once.
url: '#delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once'
- depth: 2
title: Replace an inbound’s configuration. Body shape mirrors /add. Heavy on
inbounds with thousands of clients — prefer /setEnable for enable-only
flips.
url: '#replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips'
title: Replace an inbound’s configuration. Body shape mirrors /add. Clients the
inbound already holds keep their stored enable, expiryTime, totalGB,
reset, resetDay, resetWeekday and resetMax — change those through the
/panel/api/clients endpoints. Heavy on inbounds with thousands of
clients — prefer /setEnable for enable-only flips.
url: '#replace-an-inbounds-configuration-body-shape-mirrors-add-clients-the-inbound-already-holds-keep-their-stored-enable-expirytime-totalgb-reset-resetday-resetweekday-and-resetmax--change-those-through-the-panelapiclients-endpoints-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips'
- depth: 2
title: Toggle only the enable flag without serialising the whole settings JSON.
Recommended for UI switches on large inbounds.
@@ -151,10 +153,12 @@ _openapi:
failures are reported per id and the rest still proceed. Restarts xray
at most once.
id: delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
- content: Replace an inbound’s configuration. Body shape mirrors /add. Heavy on
inbounds with thousands of clients — prefer /setEnable for enable-only
flips.
id: replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
- content: Replace an inbound’s configuration. Body shape mirrors /add. Clients
the inbound already holds keep their stored enable, expiryTime,
totalGB, reset, resetDay, resetWeekday and resetMax — change those
through the /panel/api/clients endpoints. Heavy on inbounds with
thousands of clients — prefer /setEnable for enable-only flips.
id: replace-an-inbounds-configuration-body-shape-mirrors-add-clients-the-inbound-already-holds-keep-their-stored-enable-expirytime-totalgb-reset-resetday-resetweekday-and-resetmax--change-those-through-the-panelapiclients-endpoints-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
- content: Toggle only the enable flag without serialising the whole settings
JSON. Recommended for UI switches on large inbounds.
id: toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds