## 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) — правило окружения.