Слогер Создать блог
Разработка

Как не потерять пользователя на подтверждении email: разбор состояния pending_email

Почему бинарный флаг регистрации ломает UX и как простое сохранение промежуточного статуса в конфиг решает проблему.

Пользователь первый раз запустил приложение, ввёл email, получил письмо с подтверждением — и закрыл приложение, не кликнув по ссылке. Через минуту он открывает его снова. Логично ожидать экран «письмо отправлено, проверьте почту». Вместо этого приложение снова просит email. Если ввести его повторно — сервер создаст новый токен, и ссылка в старом письме перестанет работать. Когда человек наконец кликает по ней, получает «invalid link». Это классическая ловушка бинарного состояния.

Как выглядит ловушка

Цикл повторялся без шансов на выход:

  1. Ввод email → отправляется письмо с подтверждением.
  2. Пользователь закрывает приложение до клика.
  3. При следующем запуске снова показывается экран первого запуска.
  4. Повторный ввод email → сервер генерирует новый токен.
  5. Клик по ссылке из старого письма → «invalid link».

Корень проблемы — в том, как приложение хранило состояние регистрации. Оно было бинарным: «не зарегистрирован» или «зарегистрирован». Промежуточного состояния «письмо отправлено, но не подтверждено» просто не существовало. Поэтому любой перезапуск возвращал пользователя к началу.

Если состояние — не ноль и не единица, а несколько шагов с возможностью прерваться, бинарный флаг неизбежно отбрасывает человека назад.

Решение: сохранить pending_email

Фикс простой — в момент успешной отправки письма сохранить адрес в локальный конфиг app_config.json как pending_email. Тогда процесс регистрации получает третье состояние: «отправили, ждём подтверждения».

Важная деталь: сохранять адрес нужно только когда сервер ответил status: ok. Если отправить письмо не удалось, писать pending_email нельзя — пользователь будет вечно ждать письмо, которое не существует.

Сохранение оборачивается в try/except и не влияет на основной поток. Если записать в конфиг не получилось — приложение всё равно выполнило главную цель: отправило письмо. pending_email — это лишь страховка для возобновления.

Возврат к нужному экрану при старте

Теперь при запуске приложение проверяет статус. Если это первый запуск и в конфиге лежит pending_email, пользователь сразу попадает на экран «письмо отправлено, нажмите кнопку после перехода по ссылке». Вводить email заново не нужно.

И главное: экран ожидания не делает никаких обращений к серверу. Он просто берёт адрес из конфига и показывает его пользователю. Никакого нового токена.

Если бы при возобновлении приложение вызвало тот же endpoint регистрации, сервер опять выдал бы свежий токен — и первая ссылка снова умерла бы. Поэтому возобновление — это чисто зеркалирование локального состояния на экран.

Ручная отправка — отдельная история

Для случая, когда пользователь сам хочет переотправить письмо, на экране есть кнопка «Resend email». Это явное действие, поэтому генерация нового токена там допустима.

Ключевое различие: автоматическое возобновление не трогает токен, а ручная отправка обновляет его. Если перепутать эти два пути, вы вернёте ту же ловушку.

Когда очищать pending_email

Как только пользователь прошёл по ссылке и подтвердил email, pending_email нужно удалить. В тот же момент в конфиг записывается флаг email_registered и сам адрес как registered_email.

Так замыкается цикл состояний: не зарегистрирован → отправлено письмо (появляется pending_email) → подтверждено (удаляется pending_email, появляется registered_email). Где бы пользователь ни закрыл приложение, следующий запуск вернёт его на правильный шаг.

Сравнение подходов

СценарийБинарный флагpending_email
Закрыл приложение после отправки письмаПри следующем запуске — экран ввода emailЭкран «проверьте почту»
Повторный ввод emailОбязательный — иначе никакНе нужен
Ссылка из старого письмаПерестаёт работать из-за нового токенаОстаётся валидной
Пользователь кликает по ссылке«Invalid link»Регистрация завершается

Вывод

Изменение небольшое — добавить промежуточное состояние и сохранить его в конфиг. Но оно убирает целый класс разочарований: человеку больше не приходится повторять уже сделанные действия.

Этот паттерн применим к любому прерываемому процессу: загрузка файла, многошаговая форма, оплата. Если процесс может быть прерван, состояние нужно хранить не как «да/нет», а как фазу, которую можно продолжить с того же места.

По материалам: dev. Текст переработан редакцией Слогера.

← На главную

Рекламное место — Конец поста
Реклама · Слогер

Комментарии (0)

Войдите, чтобы комментировать.

Пока нет комментариев. Будьте первым.