Подтверждение адреса
Форма сохранила R001 как заявку pending. Теперь рассмотрим подтверждение адреса: ограниченное действие, которое связывает заявку с доступом к указанному ящику и принятым обещанием. Результат урока — карта CONF-01 с допустимым переходом, истёкшим запросом и повтором. Реальные письма и ссылки подтверждения не создаются.
В синтетическом ProfessorWeb используем тот же адрес и добавим R003 для случая истечения. Все события имеют сценарное происхождение, а не журнал действий людей. Папка lesson-03 архива серии содержит состояния и текст подтверждающего сообщения. Это не серверный обработчик и не готовая система подписки.
Ограниченный запрос
Будущий запрос подтверждения должен быть связан с конкретной заявкой, целью и версией обещания. Если токен относится к другому адресу или старой версии, нельзя использовать его произвольно. Для учебной модели введём ID CONF-R001-1, срок жизни 24 часа и признак использования. Двадцать четыре часа — выбранный параметр проекта, не универсальное требование почтовых систем.
В приложение не помещаем рабочий секрет. Поле token отсутствует, есть только token_ref как редакторский идентификатор. При настоящей реализации понадобятся случайное непредсказуемое значение, безопасное хранение и проверка срока. Их нельзя заменить коротким ID из статьи. В этом уроке мы объясняем состояние, не предлагаем готовую криптографическую или серверную реализацию.
| Условие | Ожидаемое решение |
|---|---|
| Актуальная заявка, срок не истёк, действие допустимо | confirmed |
| Истёкший запрос | Оставить неподтверждённым, предложить новую заявку |
| Повтор принятого действия | Сообщить прежний результат без нового запуска |
| Уже произошла отписка | Не восстанавливать старой ссылкой |
В подтверждающем сообщении повторим, что запрошено: подборка уроков по теме web с частотой не выше weekly. Человек должен понимать, какое действие подтверждает. Текст не содержит рекламную подборку и не объявляет его активным заранее. Если адрес введён другим человеком, получатель может проигнорировать запрос. В нашем проекте неподтверждённая заявка не получает обычные выпуски.
Модель перехода
В синтетическом сценарии R001 подтверждает заявку через два часа после создания. Проверяем связь с текущей заявкой, срок и отсутствие остановки. Ожидаемое состояние confirmed, событие EV-R001-confirmed и использованный запрос. Это описанный переход на данных, а не настоящий клик и не выполненный HTTP-запрос. Глобальная пометка fictional сохраняется в каждом состоянии.
R003 получает учебную заявку с тем же обещанием, но действует через тридцать часов. Она становится expired, а подборка недопустима. Истёкший запрос не нужно превращать в подтверждение ради удобства. Можно предложить новую добровольную заявку. При этом старая история сохраняется настолько, насколько требует принятый процесс хранения; конкретные сроки хранения в реальном проекте определяются отдельно.
Повтор подтверждения R001 не создаёт вторую активную подписку и не запускает приветственную серию второй раз. В модели событие имеет устойчивый ID, а переход уже завершён. Такой результат называют повторяемым безопасным действием по смыслу состояния. Мы не доказываем, что будущая распределённая система обеспечит единственную отправку: для неё понадобятся отдельные технические механизмы.
Если перед повтором произошла отписка, приоритет имеет более новое явное прекращение. Старая ссылка не должна восстанавливать confirmed. Для возвращения нужен новый выбор в актуальной форме. Это правило защищает человека от неожиданного возобновления сообщений. В сценарии CONF-01 ветка описана отдельно, хотя реальная отписка будет подробно рассмотрена позднее.
Просмотр и действие
Автоматическое открытие URL не всегда является осознанным действием получателя: ссылки могут просматриваться защитными инструментами. Поэтому проект должен отдельно определить, какое действие завершает подтверждение. В нашей редакторской модели страница просмотра показывает условия, а подтверждение выполняется явным действием. Техническая защита такого обработчика не реализована; нельзя считать макет достаточным решением этой проблемы.
Не помещайте полный адрес и личные сведения в публичный URL. Учебная ссылка использует вымышленный домен и демонстрационную метку без секрета. При будущей реализации значение должно быть ограниченным и непредсказуемым, а журналы не должны раскрывать его без необходимости. Мы принимаем это как проектное требование к отдельной технической работе, не как уже выполненное свойство текущего сайта.
После успешного перехода интерфейс сообщает конкретный результат: «Адрес подтверждён для подборки уроков по выбранным темам». Не добавляем утверждение о доставке следующего письма в основную папку: подтверждение не доказывает доставляемость. Не говорим, что все интересы человека известны: выбрана только тема web. Точный текст сохраняет границы события.
При недопустимом запросе ответ объясняет восстановление: «Срок запроса истёк. Создайте новую заявку, если хотите получать подборку». Не показываем лишнее состояние чужих контактов. В учебном приложении сообщения разделены по сценарию, а публичная безопасность будущего сервиса требует отдельной реализации и предметной сверки. Этот урок не подключает реальные страницы подтверждения.
Данные после шага
В after.json добавлены CONF-01, результат R001 и истёкшее состояние R003. Исходная заявка первого контакта сохранена в предыдущем решении, поэтому можно увидеть историю. Текущий результат учитывается по последней редакционной записи, а не по старому pending из формы. Следующая глава нормализует эти сведения в отдельные объекты контакта, подписки и событий.
Проверьте карту на изменённом условии: срок ещё действует, но версия обещания уже заменена. Нельзя молча подтверждать новый набор условий по старому запросу. Процесс должен либо сохранить действие в рамках старого обещания, либо предложить новый согласованный выбор. В нашей модели выбираем второе, если изменилось назначение. Ожидаемый результат — отсутствие неожиданного расширения подписки.
Связь запроса с целью важна и при нескольких рассылках. Если человек подтверждает учебную подборку, то же действие не должно активировать новости продукта или партнёрские предложения. В нашей карте CONF-R001-1 относится только к lesson_updates. Новая цель потребует собственного выбора и отдельного основания. Даже общий контактный ID не объединяет согласия автоматически. По этому варианту можно проверить, достаточно ли точно описаны объект подтверждения и текст сообщения.
Подтверждение даёт основание для конкретной коммуникации, но не завершает настройку рассылки. Потребуются данные предпочтений, исключения, подготовка письма и инфраструктура. Сейчас готовы только модель переходов и локальные тексты. Такое разделение помогает строить процесс постепенно, не выдавая один успешный учебный переход за полный работающий почтовый сервис.