Files
vesti/openspec/changes/publisher-service/proposal.md
T

5.5 KiB
Raw Blame History

Why

Сейчас публикатор встроен в веб-приложение (web/app.py импортирует publisher.bot напрямую и вызывает publish_multi). Это нарушает изоляцию элементов системы и мешает масштабированию:

  • публикация привязана к процессу веба (ошибка Bot API роняет весь approve);
  • нет отдельного жизненного цикла (нельзя перезапустить/обновить публикатор отдельно);
  • каналы захардкожены шаблоном @dedinit_vesti___bot, а реальная схема — «один бот-контроллер, несколько каналов» (на старте один @dedinit_vesti, потом больше);
  • нет единой точки входа для публикации из любых компонентов (веб, cron, будущие боты VK/fediverse).

Цель — вынести публикацию в изолированный микросервис (отдельный FastAPI-сервис в контейнере), который вызывается HTTP-запросом при необходимости. Это соответствует архитектурному решению «сегментировать элементы системы на микросервисы в отдельных контейнерах» (PRD, раздел 5).

What Changes

  • Новый сервис publisher/ (или services/publisher/): FastAPI-приложение с эндпоинтом POST /api/v1/publish (публикация карточки в один или несколько каналов) и GET /healthz (healthcheck).
  • Конфигурация сервиса: VESTI_BOT_TOKEN (токен бота-контроллера @dedinit_controller_bot), TG_PROXY=socks5://127.0.0.1:1080 (Telegram из РФ доступен только через SOCKS5), список каналов (сейчас @dedinit_vesti, потом несколько) — из .env или отдельного YAML.
  • Бот-контроллер: один (id 7765665742, @dedinit_controller_bot), публикует во все каналы, в которые добавлен администратором.
  • publisher/bot.py переносится в сервис (логика publish_card/publish_multi/get_views), но с конфигом каналов вместо шаблона @dedinit_vesti___bot.
  • web/app.py больше НЕ импортирует publisher напрямую: вместо publish_multi — HTTP POST на publisher-service /api/v1/publish.
  • Dockerfile + docker-compose для сервиса; healthcheck; логирование.

Не меняется

  • Карточка (publisher/card.py) остаётся (формат ≤4096, атрибуция «Дед в АйТи», ссылка на оригинал).
  • Режим публикации «черновик на подтверждение» (веб подтверждает → публикация). Без автопостинга.

Capabilities

New Capabilities

  • tg-publisher-service: Изолированный FastAPI-сервис публикации в Telegram: единая точка POST /api/v1/publish, конфиг каналов, прокси SOCKS5 для Bot API, сбор views, healthcheck.

Modified Capabilities

  • tg-publisher: логика публикации переезжает в сервис; вызывающий код (веб) использует HTTP.
  • vesti-web: approve вызывает publisher-service по HTTP вместо прямого импорта.
  • news-store: без изменений (бандлы создаёт веб, как раньше).

Impact

  • Затронутые сервисы/порты: publisher-service — новый порт (напр. 8410, локально); vesti-web :8400 — меняет способ вызова публикатора (HTTP вместо импорта).
  • Файлы:
    • новый: services/publisher/ (app/, Dockerfile, docker-compose.yml, requirements.py, README.md)
    • изменён: web/app.py (HTTP-вызов), .env.example (VESTI_BOT_CHANNELS, TG_PROXY)
    • перенос: publisher/bot.py → services/publisher/ (логика сохраняется)
  • Данные: без миграций БД (published.tg_message_id/distributed_dirs остаются).
  • Секреты: тот же VESTI_BOT_TOKEN (бот-контроллер); TG_PROXY переиспользуется.
  • Прокси: Bot API ТОЛЬКО через SOCKS5 127.0.0.1:1080 (api.telegram.org из РФ недоступен).
  • Rollback: вернуть в web/app.py импорт publisher.bot (старый путь); сервис можно не запускать.

Risks

  • SOCKS5-прокси недоступен → сервис не может опубликовать: healthcheck должен это показывать.
  • Бот не админ канала → sendMessage 403: сервис возвращает понятную ошибку, веб показывает ее.
  • Несколько каналов в будущем: конфиг списком (VESTI_BOT_CHANNELS=@a,@b), fan-out по каналам.
  • Рестарт сервисов — только извне (SSH sudo systemctl restart) — правило окружения.