yiekheng fe8e14b7a0 fix(bot): swallow leaked close from previous pairing attempt
Repro: scan QR window once → click Back → click Pair again → instantly
see 'Pairing timed out' (sometimes for several attempts in a row).

Root cause: when handleStartPairing hits a still-running session it
calls await sessionManager.stop(accountId) and immediately attaches a
fresh listener. session.close() resolves before sessionManager broadcasts
the close event to listeners (handleEvent has several awaits between
close arriving and the listener fan-out). The new listener was already
attached by then and saw the OLD session's close as if it were the new
session timing out — flipped the row to unpaired and pushed
session.timeout to the UI.

Fix: track a per-account 'pairingWarmingUp' Set. The new attempt enters
warming-up the moment its listener attaches; clears on the first qr or
open (those events can only come from the freshly-started session). A
close that arrives while still warming is logged and ignored. abandonPair
also clears the flag for safety.

Also drop the redundant Admin card from /settings — the Admin nav entry
on the sidebar/drawer already routes admins to /settings/users, the
extra card was duplicate UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 19:02:10 +08:00
..
2026-05-09 16:12:53 +08:00
2026-05-09 16:12:53 +08:00
2026-05-10 14:35:26 +08:00
2026-05-10 14:35:26 +08:00