P0: SMTP-транспорт для logic_email (verify, invite, reset) #68

Closed
opened 2026-08-14 16:15:14 +03:00 by cursor-ai · 6 comments
Owner

Проблема

logic_email пишет письма в io:format (verify, specialist_invite, password reset). На пилоте почта не уходит.

Влияние

Регистрация, инвайт специалиста и сброс пароля не работают без ручной подстановки токена.

Ожидаемый результат

Транспорт SMTP из конфига/env; те же три шаблона уходят на реальный адрес. Без смены API.

Критерии приёмки

  • Конфиг хост/порт/user/from; секреты не в git
  • send_verification_email / send_specialist_invite / send_password_reset идут через SMTP
  • Ошибка SMTP не роняет запрос (лог + ok/error по политике)
  • Тест без живого SMTP (mock/capture)
  • Брендинг CalenTIQ в from/subject/ссылках

Файлы (подсказка)

  • EventHubBack/src/logic/logic_email.erl

Родитель

EventHub/EventHubSpec#8 (волна 1)

Приоритет

P0

## Проблема `logic_email` пишет письма в `io:format` (verify, specialist_invite, password reset). На пилоте почта не уходит. ## Влияние Регистрация, инвайт специалиста и сброс пароля не работают без ручной подстановки токена. ## Ожидаемый результат Транспорт SMTP из конфига/env; те же три шаблона уходят на реальный адрес. Без смены API. ## Критерии приёмки - [ ] Конфиг хост/порт/user/from; секреты не в git - [ ] `send_verification_email` / `send_specialist_invite` / `send_password_reset` идут через SMTP - [ ] Ошибка SMTP не роняет запрос (лог + ok/error по политике) - [ ] Тест без живого SMTP (mock/capture) - [ ] Брендинг CalenTIQ в from/subject/ссылках ## Файлы (подсказка) - `EventHubBack/src/logic/logic_email.erl` ## Родитель https://git.sabilin.com/EventHub/EventHubSpec/issues/8 (волна 1) ## Приоритет P0
cursor-ai added the Task label 2026-08-14 16:15:14 +03:00
cursor-ai self-assigned this 2026-08-14 16:15:14 +03:00
Author
Owner

Беру Back#68 в работу.

Утверждён вариант A: gen_smtp + env SMTP_*; без хоста — log-only; ошибка SMTP не валит register/invite/reset. IFT Mailpit и секреты stage — DevOps#11 (следующая задача).

Беру Back#68 в работу. Утверждён вариант A: `gen_smtp` + env `SMTP_*`; без хоста — log-only; ошибка SMTP не валит register/invite/reset. IFT Mailpit и секреты stage — DevOps#11 (следующая задача).
Author
Owner

Вариант A реализован локально (ещё без коммита/пуша).

Код

  • gen_smtp 1.3.0 (1.2.0 не собирается на OTP 28)
  • logic_email: без SMTP_HOST — log-only; с хостом — gen_smtp_client:send; ошибка/crash → warning, ok
  • Ссылки CalenTIQ через PUBLIC_APP_URL: /verify?token=, /invites?token=, /reset-password?token=
  • Env: SMTP_PORT (587), SMTP_USER/SMTP_PASS, SMTP_FROM, SMTP_TLS
  • Проброс в docker/docker-compose.stage.yml + .env.example (пустые значения)
  • Спека: EventHubBackSpec.md (stub убран)

Тесты

rebar3 as test eunit --module=logic_email_tests — 4/4 ok (log-only, mock deliver, invite/reset URL, ошибка SMTP не валит вызов).

Живой SMTP на stage — следующая задача DevOps#11 (Mailpit IFT / секреты). Коммит Back — по явной просьбе.

Вариант A реализован локально (ещё без коммита/пуша). ### Код - `gen_smtp` **1.3.0** (1.2.0 не собирается на OTP 28) - `logic_email`: без `SMTP_HOST` — log-only; с хостом — `gen_smtp_client:send`; ошибка/crash → warning, `ok` - Ссылки CalenTIQ через `PUBLIC_APP_URL`: `/verify?token=`, `/invites?token=`, `/reset-password?token=` - Env: `SMTP_PORT` (587), `SMTP_USER`/`SMTP_PASS`, `SMTP_FROM`, `SMTP_TLS` - Проброс в `docker/docker-compose.stage.yml` + `.env.example` (пустые значения) - Спека: `EventHubBackSpec.md` (stub убран) ### Тесты `rebar3 as test eunit --module=logic_email_tests` — 4/4 ok (log-only, mock deliver, invite/reset URL, ошибка SMTP не валит вызов). Живой SMTP на stage — следующая задача DevOps#11 (Mailpit IFT / секреты). Коммит Back — по явной просьбе.
Author
Owner

HTML-шаблоны писем (дополнение к SMTP)

  • priv/email/layout.html — CalenTIQ (steel header, sage accent, coral CTA)
  • logic_email_templates — verify / invite / reset (RU subject + multipart HTML+plain)
  • Subject RFC2047 UTF-8; Dockerfile копирует priv/
  • EUnit logic_email_tests — 5/5 ok

Связка со стендами: DevOps#11 (Mailpit IFT).

## HTML-шаблоны писем (дополнение к SMTP) - `priv/email/layout.html` — CalenTIQ (steel header, sage accent, coral CTA) - `logic_email_templates` — verify / invite / reset (RU subject + multipart HTML+plain) - Subject RFC2047 UTF-8; `Dockerfile` копирует `priv/` - EUnit `logic_email_tests` — 5/5 ok Связка со стендами: DevOps#11 (Mailpit IFT).
Author
Owner

Коммит локально (без push): 69ee037 — feat(email): SMTP via gen_smtp and CalenTIQ HTML templates. Refs EventHub/EventHubBack#68

В коммите: gen_smtp 1.3.0, logic_email + HTML templates, eunit, priv/email, docker SMTP env. Пуш — по отдельной просьбе.

Коммит локально (без push): `69ee037` — feat(email): SMTP via gen_smtp and CalenTIQ HTML templates. Refs EventHub/EventHubBack#68 В коммите: gen_smtp 1.3.0, logic_email + HTML templates, eunit, priv/email, docker SMTP env. Пуш — по отдельной просьбе.
Author
Owner

Запушено на origin/master: 3d7ae0d..302e1e5 (в т.ч. SMTP/HTML 69ee037, ignore certs 302e1e5).

Запушено на `origin/master`: `3d7ae0d..302e1e5` (в т.ч. SMTP/HTML `69ee037`, ignore certs `302e1e5`).
Author
Owner

Готово

Запушено: 69ee037 (SMTP + HTML CalenTIQ) на origin/master.

  • gen_smtp 1.3.0, env SMTP_*; без хоста — log-only
  • verify / specialist_invite / password reset
  • eunit logic_email_tests ok
  • стенд: DevOps#11 (закрыт)

Закрываю Back#68. Родитель: Spec#8 волна 1.

## Готово Запушено: `69ee037` (SMTP + HTML CalenTIQ) на `origin/master`. - `gen_smtp` 1.3.0, env `SMTP_*`; без хоста — log-only - verify / specialist_invite / password reset - eunit `logic_email_tests` ok - стенд: DevOps#11 (закрыт) Закрываю Back#68. Родитель: Spec#8 волна 1.
Sign in to join this conversation.