# TG Publisher — формат «богатого репоста» ## ADDED Requirements ### Requirement: Карточка репоста — полный текст При публикации внешнего поста карточка MUST содержать полный текст исходного поста (а не сниппет из первых 120 символов), обрезанный до лимита Telegram (4096 символов). #### Scenario: публикация поста с длинным текстом - Given пост с текстом длиной 3000 символов и ссылкой на оригинал - When модератор подтверждает пост в вебе - Then в канале отправляется текст с полным содержимым поста (обрезанный до 4096) - And заголовок-сниппет из 120 символов НЕ используется ### Requirement: Карточка репоста — комментарий модератора При подтверждении поста модератор МОЖЕТ указать комментарий; комментарий MUST публиковаться первым блоком в тексте поста. #### Scenario: approve с комментарием - Given пост, подтверждаемый через веб - When модератор вводит комментарий «Отличный материал по Linux» и нажимает «Опубликовать» - Then текст карточки начинается с комментария «Отличный материал по Linux» - And полный текст исходного поста следует после комментария #### Scenario: approve без комментария - Given пост, подтверждаемый через веб - When модератор оставляет поле комментария пустым - Then текст карточки начинается с полного текста исходного поста - And лишних пустых блоков нет ### Requirement: Карточка репоста — ссылка на оригинал без предпросмотра Ссылка на оригинальный пост MUST присутствовать в тексте карточки, и Telegram-предпросмотр этой ссылки MUST быть отключён (link_preview_options is_disabled). #### Scenario: публикация внешнего поста - Given внешний пост с url на оригинал - When карточка отправляется в канал - Then в тексте есть строка со ссылкой на оригинал - And Telegram НЕ добавляет предпросмотр ссылки внизу поста ### Requirement: Карточка репоста — медиа из оригинала Если у исходного поста есть медиа (photo/video), публикация MUST отправлять медиа первым сообщением, а текст — следующим; видео (.mp4) MUST поддерживаться. #### Scenario: пост с фото - Given пост с media_path=media/xyz.jpg - When модератор подтверждает пост - Then в канал отправляется фото (sendPhoto) первым сообщением - And текст карточки отправляется следующим сообщением #### Scenario: пост с видео - Given пост с content_type=video и media_path=media/xyz.mp4 - When модератор подтверждает пост - Then в канал отправляется видео (sendVideo) первым сообщением - And текст карточки отправляется следующим сообщением ### Requirement: Карточка репоста — без служебной информации Служебная информация (направление/язык, источник, просмотры/реакции) MAY НЕ выводиться в теле поста; основное содержимое — текст, комментарий, ссылка на оригинал. #### Scenario: пост без служебки - Given внешний пост с направлением и просмотрами - When карточка формируется - Then в тексте карточки НЕТ строк «📁 linux / ru», «📰 источник», «👁 123 💬 4» - And текст содержит полный текст поста и ссылку на оригинал ## MODIFIED Requirements ### Requirement: Формат карточки (publisher/card.py) Функция make_card MUST принимать необязательный параметр `comment` и строить текст из: комментария (если задан), полного текста поста, ссылки на оригинал (атрибуция для своих). #### Scenario: make_card с comment - Given post с текстом «Важная новость» и comment «Мой комментарий» - When вызывается make_card(post, comment) - Then результат содержит «Мой комментарий» перед «Важная новость» - And ссылка на оригинал присутствует #### Scenario: make_card без comment - Given post с текстом «Важная новость» и comment=None - When вызывается make_card(post) - Then результат НЕ содержит пустого первого блока - And результат содержит полный текст «Важная новость» и ссылку на оригинал ### Requirement: Отправка медиа в publisher-service Сервис публикации MUST отправлять медиа первым и текст вторым; для sendMessage параметр link_preview_options MUST отключать предпросмотр ссылки. #### Scenario: sendMessage без предпросмотра - Given канал @dedinit_vesti и текст со ссылкой на оригинал - When вызывается sendMessage - Then параметр link_preview_options={"is_disabled": True} передаётся в Bot API #### Scenario: sendVideo для mp4 - Given файл media/xyz.mp4 существует в медиа-маунте - When публикуется пост с этим видео - Then вызывается sendVideo (а не sendPhoto) - And текст отправляется следом