3x-ui/database
MHSanaei b40f869f2a
Some checks are pending
CI / go-test (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / frontend (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (push) Waiting to run
fix(node): keep client/inbound edits working when a node is offline (#4923, #4931)
Node-backed client and inbound edits no longer hard-fail when the backing node is offline or disabled. Edits commit to the panel DB immediately and reconcile to the node when it reconnects (eventual consistency); the panel is the single source of truth for desired config.

- Add Node.ConfigDirty/ConfigDirtyAt; mark a node dirty when an edit commits without reaching it (cleared via CAS on ConfigDirtyAt after a full reconcile).
- nodePushPlan() reads node state fresh from the DB, skips the push for offline/disabled nodes (no 10s hang), and treats push failures as non-fatal across every mutation path (client add/update/del + bulk + attach/detach; inbound add/update/del/toggle/resetTraffic).
- ReconcileNode() pushes the panel's desired config to a node on reconnect (refreshing the remote tag cache first) and prunes node-side orphans; runs before the traffic pull in the node sync job.
- While a node is dirty the traffic pull applies only up/down deltas and node-initiated disables, never overwriting desired config from a stale node snapshot.
- Surface a non-blocking 'saved; will sync on reconnect' warning to the UI.

Validated with a two-panel Docker E2E: client delete/update, attach/detach, and inbound add/delete all reconcile correctly offline -> reconnect.
2026-06-05 02:26:57 +02:00
..
model fix(node): keep client/inbound edits working when a node is offline (#4923, #4931) 2026-06-05 02:26:57 +02:00
db.go fix(api-token): hash tokens at rest and show plaintext only once 2026-06-03 22:57:50 +02:00
db_seed_test.go feat(inbounds): support Unix domain socket path in Listen field (#4429) 2026-06-02 00:37:20 +02:00
dialect.go fix(nodes): use GREATEST for last_online merge on PostgreSQL 2026-05-29 02:04:02 +02:00
dump_sqlite.go feat(migrate-db): SQLite <-> .dump conversion and Download Migration in Overview 2026-06-04 15:32:22 +02:00
dump_sqlite_test.go feat(migrate-db): SQLite <-> .dump conversion and Download Migration in Overview 2026-06-04 15:32:22 +02:00
migrate_data.go fix(migrate-db): drop legacy client_traffics FK before Postgres copy (#4882) 2026-06-04 16:57:09 +02:00
migrate_data_test.go fix(migrate-db): preserve false-valued columns in SQLite to Postgres copy 2026-06-03 14:28:14 +02:00