fix(node): show the activated first-use deadline on the Clients page

With "start after first use" on a node inbound, the node activates the
absolute deadline and the master adopts it into client_traffics via the
sync CASE merge — but the client record (what the Clients page reads) was
only refreshed by SyncInbound from the snapshot's settings JSON. A node
whose JSON still carried the negative duration (stale conversion, older
node build, or a mixed local+node attachment) kept rewriting the record
back to "not started" even though the DB held the real deadline (#5714).

Lift the activated deadline from client_traffics onto still-negative
client records at the end of every node sync, after SyncInbound has run.
Intentional resets back to delayed start are unaffected: editing a client
also resets client_traffics to the negative duration, so the lift's
expiry_time > 0 guard never matches.

Closes #5714
This commit is contained in:
MHSanaei
2026-07-02 09:36:07 +02:00
parent e5b56c9444
commit 8dd3b31ee8
2 changed files with 57 additions and 0 deletions
+15
View File
@@ -191,6 +191,17 @@ func mergeActivationExpiry(existing, node int64) int64 {
return node
}
// liftActivatedClientRecordExpiries copies a node-activated deadline from
// client_traffics onto client records still holding the negative duration (#5714).
func liftActivatedClientRecordExpiries(tx *gorm.DB) error {
return tx.Exec(
`UPDATE clients
SET expiry_time = (SELECT ct.expiry_time FROM client_traffics ct WHERE ct.email = clients.email AND ct.expiry_time > 0 LIMIT 1)
WHERE clients.expiry_time < 0
AND EXISTS (SELECT 1 FROM client_traffics ct WHERE ct.email = clients.email AND ct.expiry_time > 0)`,
).Error
}
func (s *InboundService) SetRemoteTraffic(nodeID int, snap *runtime.TrafficSnapshot, dirty bool) (bool, error) {
var structuralChange bool
err := submitTrafficWrite(func() error {
@@ -847,6 +858,10 @@ func (s *InboundService) setRemoteTrafficLocked(nodeID int, snap *runtime.Traffi
}
}
if err := liftActivatedClientRecordExpiries(tx); err != nil {
logger.Warning("setRemoteTraffic: lift activated expiries failed:", err)
}
if err := tx.Commit().Error; err != nil {
return false, err
}