Предпочтения и отписка
Доставка зависит от инфраструктуры, но допустимость сообщения начинается с выбора человека. Теперь добавим управление темами, частотой и остановкой. Результатом урока станет PREF-01 с двумя независимыми действиями: изменение предпочтения и прекращение подборки. Для R001 рассмотрим остановку после подготовки приветственного шага, чтобы увидеть влияние на очередь.
Все состояния синтетические. Реальной страницы настроек или обработчика нет. В lesson-11 архива лежат тексты интерфейса и схема заголовков one-click. Адреса демонстрационные, сообщения не отправлялись, подписки настоящих людей не менялись.
Тема и прекращение
Смена web на seo меняет релевантность будущих подборок, но не обязательно прекращает цель lesson_updates. Отписка от всех уроков меняет состояние на unsubscribed и запрещает дальнейшие редакционные сообщения этой цели. Интерфейс должен объяснять разницу. Кнопка «сохранить темы» не должна незаметно означать новое согласие на всё, а остановка не должна требовать выбрать ещё одну тему.
В нашей модели человек может изменить частоту в пределах поддерживаемых режимов. Weekly и monthly соответствуют разным правилам слотов. Если режим не реализован, нельзя показывать его как уже работающую возможность. Локальный макет содержит оба, но техническая реализация отсутствует. Ожидаемый результат действия должен совпадать с объяснением, а не только с набором красивых переключателей.
| Действие | Состояние подписки | Последствие |
|---|---|---|
| Смена темы | confirmed сохраняется | Пересчитать релевантность |
| Смена частоты | confirmed сохраняется | Пересмотреть будущие слоты |
| Остановка lesson_updates | unsubscribed | Отменить редакционные шаги |
| Новый выбор после остановки | Новая заявка | Не использовать старое подтверждение |
В синтетической ветке R001 прекращает подборку. W02, W03 и NEWS-01 становятся недопустимыми. Сохранённый ранее сегмент не отменяет это действие. История продолжает объяснять, почему контакт был кандидатом и почему перестал им быть. Темы можно сохранить в ограниченной истории по правилам проекта, но их наличие не разрешает отправку.
Ссылка и действие
Обычная ссылка в теле ведёт на страницу управления или ручной остановки будущего проекта. Её просмотр не должен случайно подписывать или возобновлять сообщения. Для нашей модели предполагается явное действие остановки на странице. Точный серверный обработчик, защита и интерфейс не реализованы. Демо-путь unsubscribe/demo-r001 лишь показывает назначение и не является рабочим секретом.
One-click в почтовом интерфейсе — отдельный механизм. RFC 8058 описывает заголовки List-Unsubscribe с HTTPS-адресом и List-Unsubscribe-Post: List-Unsubscribe=One-Click. При согласованном действии получателя почтовая система отправляет POST. Сообщение должно иметь DKIM-подпись, покрывающую оба заголовка. Этот механизм не создаётся добавлением обычной HTML-ссылки.
В приложение положим только схему этих полей с вымышленным URL. Нет DKIM-подписи, принимающего endpoint и настоящего идентификатора. Поэтому схема не является готовым отправляемым письмом и не удовлетворяет требованиям автоматически. Для будущей реализации нужен непрогнозируемый ограниченный идентификатор адресата и списка, обработка POST без зависимости от cookie и отдельная предметная проверка.
Путь one-click не должен требовать входа в кабинет или выбора адреса заново. Он связан с конкретной подпиской. Ручная страница предпочтений может иметь другой интерфейс, но не заменяет почтовое действие. В модели отделяем /unsubscribe/one-click/demo-r001 как описание будущего назначения и preferences/demo-r001 как редакторский макет управления. Ни один из них не подключён к сайту.
Идемпотентная остановка
Повтор остановки возвращает тот же смысл: подборка уже прекращена. Он не создаёт новую заявку и не отправляет повторное приветствие. У события есть ID и область lesson_updates. Если человек перестал получать эту цель, будущий ответ на отдельное обращение рассматривается по другому назначению, а не автоматически запрещается или разрешается всем флагом. Правовые условия реального ответа требуют отдельного разбора.
Не делайте обязательным вопрос «почему вы уходите», прежде чем прекратить сообщения. В проектной модели причина необязательна и не влияет на остановку. Можно предложить её отдельно после результата, но нельзя удерживать человека ради статистики. Показатель отписок описывает выбор, а не нарушение со стороны читателя. Реальных отписок в лаборатории нет.
При смене адреса нельзя передать подтверждение новому ящику вместе с предпочтениями. Это действие возвращается к модели третьего урока. Если интерфейс объединяет настройки и контакт, он должен явно различать последствия каждого изменения. В нашем PREF-01 адрес не меняется; пример посвящён темам и остановке. Такое ограничение сохраняет один связный результат.
Отписка влияет и на уже подготовленное содержание. HTML и text/plain могут оставаться локальными образцами, но задача отправки для R001 отменяется. Не нужно удалять учебный шаблон из редакции: он не является персональным действием сам по себе. Разделение объекта письма и операции для контакта помогает сохранить полезный материал и одновременно уважить запрет.
Ожидаемая запись
В after.json появляется PREF-01, новое состояние R001: unsubscribed и список отменяемых карточек. Остальные контакты не меняются. Предыдущий DATA-01 остаётся историческим срезом; актуальное решение остановки применяется поверх него. Позже при нормализации нужно материализовать этот переход в текущую модель, а не читать старый статус без истории.
В artifact.md находятся подписи и сообщения результата. one-click-plan.md отдельно указывает, каких технических частей нет. Это полезная граница приложения: редактор видит требование и содержание, разработчик — будущий механизм, читатель — отсутствие настоящего обработчика. Нельзя объявить one-click проверенным, потому что он описан словами.
Для будущего журнала управления достаточно сохранить ID события, цель и результат, не копируя токен one-click в открытый отчёт. Секрет маршрута нужен обработчику, но не редакторскому объяснению. Если человек переслал письмо, доступ к ссылке может оказаться у другого получателя; поэтому такой механизм даёт право только ограниченного действия остановки, а не просмотра всей карточки контакта. В учебном плане никакого права доступа вообще нет, потому что обработчик отсутствует. Этот вариант помогает проверить границу между предпочтениями, прекращением и личными данными ещё до технической реализации.
Проверьте изменённый вариант: R001 только меняет web на seo. Тогда серия web пересматривается по релевантности, но подписка остаётся подтверждённой. Если нажата остановка, отменяются все lesson_updates независимо от темы. Такая разница станет важной в CRM, где тот же контакт может обратиться с вопросом без возобновления рассылки. Следующая глава создаст отдельную модель обращения.