## 1. Карточка (publisher/card.py) - [ ] 1.1 `make_card(post, comment=None)`: полный текст поста вместо сниппета; служебка (📁/📰/👁) убрана; ссылка на оригинал последней строкой; comment первым - [ ] 1.2 HTML-экранирование comment (XSS-safe как текст) - [ ] 1.3 Медиа: разрешить video (.mp4), фильтр не отбрасывает - [ ] 1.4 Проверка: карточка ≤4096, эмодзи/ссылки на месте ## 2. Publisher-сервис (services/publisher/) - [ ] 2.1 `telegram.py`: `send_media` (photo/video по расширению) + `send_video`; sendMessage с `link_preview_options={"is_disabled": True}` - [ ] 2.2 `main.py`: Card + `comment`; если media → send_media первым, затем send_message - [ ] 2.3 healthz/publish не ломаются; Docker пересобран (медиа-маунт уже есть) ## 3. Веб (web/) - [ ] 3.1 `candidates.html`: поле «Комментарий (по желанию)» в форме approve (все посты) - [ ] 3.2 `app.py` approve: читать `comment` из формы, передать в card - [ ] 3.3 Проверка: approve с комментарием → в канале комментарий первым, текст полный, ссылка без превью ## 4. Документация и регресс - [ ] 4.1 requirements без изменений (media/video — Bot API) - [ ] 4.2 STATUS.md / PRD.md / TODO.md обновлены - [ ] 4.3 Регресс: старые посты (текст) публикуются как раньше, тест в канал реальный (1 пост)