Files
transcriber/tasks/items/ntfy-delivery.md
T
av 115b3796e8 Нарезка задач под целевое состояние: PWA, вход, хранилище
Роадмап: web-access переименована под приложение, которое ставится на
телефон; заведена цель ready-notification — уведомление о готовности
без открытого приложения.

Беклог: десять задач. Многопользовательская цепочка (oidc-login,
record-ownership, telegram-account-link), веб (json-api-for-spa,
spa-skeleton, upload-and-status-screen, records-list-screen,
installable-pwa), уведомления через apprise и ntfy, разведка выбора
фреймворка. Очередь: долги, хранилище, вход, приложение.

Решение сменилось с htmx на SPA, поэтому conventions/web-ui.md снята
целиком и оставлена честной строкой до итога разведки. Открытые вопросы
архитектуры, границы паспорта и триггеры метки ревью приведены в
соответствие.
2026-08-10 21:36:54 +03:00

47 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ✨ Отправлять готовый текст через apprise и ntfy
- **Тип:** feature
- **Категория:** Ядро
- **Зачем:** Пользователь веба узнаёт о готовности только опросом с открытого экрана.
- **Теги:** goal:ready-notification
Двигает все пять пунктов «Завершения» цели: готовый текст и отказ доходят до
пользователя веба без открытого приложения, адрес канала свой у каждого, а отказ
канала задачу не роняет.
Сегодня `completeJob` и `failJob` отвечают только источнику `telegram`;
источник `api` не получает ничего. Здесь появляется второй способ доставки, и
выбор между ними обязан остаться в одной точке — той же, что сейчас.
## Затрагивает
- `internal/contract` — интерфейс отправителя уведомления;
- `internal/service`, `completeJob` и `failJob` — выбор канала по источнику
задачи;
- новый адаптер поверх apprise либо прямого HTTP к ntfy;
- адрес канала у учётной записи: колонка и её миграция, экран настройки;
- секция конфигурации: адрес сервера ntfy, способ вызова apprise;
- `docs/architecture.md` — новая внешняя зависимость и чем она отказывает;
- `docs/security.md` — текст расшифровки уходит на внешний сервис;
- `docs/database.md` — настройки числами.
## Критерии приёмки
- Задача из веба, дошедшая до `done`, отправляет текст в канал владельца.
Оракул — тест с подставным отправителем: вызов ровно один, с текстом задачи и
адресом владельца.
- Задача из Telegram по-прежнему отвечает ботом и вторым каналом не дублируется.
Оракул — тот же тест на источнике `telegram`: подставной отправитель ntfy не
вызван.
- Недоступный канал уведомлений не мешает задаче завершиться: состояние `done` и
текст в приложении остаются. Оракул — тест с отправителем, возвращающим
ошибку: задача в `done`, текст на месте, в логе одна запись уровня `WARN`.
- Отказ задачи доходит тем же каналом и тем же человекочитаемым текстом, что
видит пользователь Telegram. Оракул — тест на ветке `failJob`.
## Рамки
Web Push с VAPID и своим хранением подписок не делаем. Своего сервера ntfy не
поднимаем — адрес приходит конфигом. Текст расшифровки уходит на внешний сервис,
и это сдвиг периметра: строка в `docs/security.md` обязательна.