tgclient: ревью логина — 3 фатальных бага + честные терминальные шаги
...
1. (фатально) Поллер визарда никогда не работал: тик выходил по
if (!polling.value), а polling=true ставится только внутри самого
refresh — первый тик всегда пропускался, статус кода/QR не обновлялся
никогда (это и было «а нихуя не происходит»).
2. (фатально) defineModel({name:'open'}) — name игнорируется, модель
ложилась на modelValue, а родитель шлёт prop open: внешний open
никогда не доезжал в визард (watch open не срабатывал).
3. (критично) SPA-полл QR трактовал 404/410 как успех — тост «Вход
выполнен» на истёкшей/отменённой попытке. Теперь у логина честные
терминальные шаги: finalize держит строку 2 мин в 'done', ошибки
waiter'а пишут 'error' с last_error; фронт: done → success,
error/404/410 → тост об отмене + возврат к вводу телефона.
4. Осиротевшие строки после рестарта сервиса: полл и sweeper убивают
awaiting_scan без waiter и pending без RAM-клиента (410/чистка), а не
ждут 15 мин TTL.
5. connect() в login_start/login_qr_start под except — 503 как данные
вместо 500 на полумёртвых сетях.
6. Закрытие визарда (X/ESC) без успеха шлёт настоящую DELETE-отмену
(auth.cancelCode), как кнопка; кнопка отмены — loading-стейт.
7. sweeper: истёкшие строки удаляет безусловно (включая done/error),
«зависшие» старше stale_min — отменяет; done/error не трогает. Админ-
счётчик pending_logins не учитывает терминальные шаги.
8. 12 unit-тестов стейт-машины (backend/tests, фейковый Telethon):
SMS reuse/3 промаха/2FA/финализация, отмена с зависшим cancelCode,
QR success/password/recreate-fail/cancel/рестарт-осиротевшие,
sweeper-фазы. pytest/pytest-asyncio — [dev] extra.
Eugene Sukhodolskiy
committed
3 hours ago