Files

75 lines
5.1 KiB
Markdown
Raw Permalink 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.
# gotosocial-publisher Specification
## Purpose
TBD - created by archiving change gotosocial-publisher. Update Purpose after archive.
## Requirements
### Requirement: Fediverse-канал в publisher-service
* publisher-service MUST уметь публиковать карточку в GoToSocial через Mastodon-совместимый REST API при указании fediverse-канала в запросе или конфиге.
* publisher-service MUST отправлять текст статуса через `POST /api/v1/statuses` с заголовком `Authorization: Bearer <GT_SOCIAL_ACCESS_TOKEN>`.
* publisher-service MUST обрезать текст до 5000 символов (лимит GtS) перед публикацией, сохраняя ссылку на оригинал последней строкой.
* publisher-service MAY поддерживать visibility из конфига (`GT_SOCIAL_VISIBILITY`, default `public`).
* publisher-service MUST включать fediverse-канал в fan-out: ошибка одного канала не должна отменять публикацию в остальные (поведение как у Telegram-каналов).
* publisher-service MUST в режиме `dry_run` эмулировать публикацию в fediverse без реального HTTP-запроса наружу.
#### Scenario: Публикация карточки в GoToSocial
GIVEN конфиг publisher содержит `GT_SOCIAL_URL=https://social.dedinit.ru` и `GT_SOCIAL_ACCESS_TOKEN=<токен @vesti>`,
WHEN веб (или curl) отправляет `POST /api/v1/publish` с `card: {text, media?}` и каналом `@vesti@dedinit.ru`,
THEN publisher вызывает `POST https://social.dedinit.ru/api/v1/statuses` с Bearer-токеном и текстом,
AND ответ содержит `results["@vesti@dedinit.ru"].message_id` = id созданного статуса
AND `ok=true`, если GtS вернул 200.
#### Scenario: Публикация с медиа
GIVEN у карточки есть `media` и файл существует,
WHEN publisher публикует в fediverse-канал,
THEN publisher сначала загружает файл через `POST /api/v2/media` (multipart), получает `media_id`,
AND передаёт массив `media_ids` в `POST /api/v1/statuses` (до 6 вложений).
#### Scenario: dry_run не уходит наружу
GIVEN `dry_run=true` в запросе,
WHEN publisher обрабатывает fediverse-канал,
THEN в `results["@vesti@dedinit.ru"]` возвращается пустой `ChannelResult()` (message_id=0)
AND реальный HTTP-запрос к social.dedinit.ru НЕ выполняется.
#### Scenario: GtS недоступен
GIVEN GoToSocial не отвечает (сеть/HTTP 5xx),
WHEN publisher публикует в fediverse-канал,
THEN в `results["@vesti@dedinit.ru"].error` — понятное сообщение об ошибке
AND остальные каналы (Telegram) публикуются как обычно
AND `ok=false` (но без общего 502, если хотя бы один канал успешен).
### Requirement: Конфигурация fediverse
* publisher-service MUST читать настройки GtS из env: `GT_SOCIAL_URL`, `GT_SOCIAL_ACCESS_TOKEN`, `GT_SOCIAL_VISIBILITY` (SECRETS в .env).
* publisher-service MUST добавлять в `/healthz` блок `gotosocial`: url, аккаунт (из verify_credentials), `token_set`.
* publisher-service MUST определять fediverse-канал по признаку: содержит `@` + точка (например `@vesti@dedinit.ru`) или префикс `gt:` — и НЕ трактовать его как Telegram (chat_id).
#### Scenario: healthz показывает состояние GtS
GIVEN publisher запущен с настроенным GT_SOCIAL_ACCESS_TOKEN,
WHEN GET /healthz,
THEN ответ содержит `gotosocial: {url, token_set: true, account: <username>}` (или `account_ok: false` при сбое verify_credentials).
#### Scenario: token не задан
GIVEN `GT_SOCIAL_ACCESS_TOKEN` пуст,
WHEN publisher получает запрос публикации в fediverse-канал,
THEN результат канала содержит `error` «GT_SOCIAL_ACCESS_TOKEN не задан» (HTTP-статус общий 502 при пустых остальных),
AND healthz показывает `token_set: false`.
### Requirement: Удаление статуса (поддержка отмены тестовых)
* delete_status MUST удалять статус по id через `DELETE /api/v1/statuses/{id}` (для отмены тестовых публикаций/очистки канала); это SHOULD-часть publisher-service.
#### Scenario: Удаление статуса
GIVEN существует статус с id=123 в GtS,
WHEN вызывается `gotosocial.delete_status(123)`,
THEN GtS возвращает 200 и статус исчезает из ленты (проверяется GET /api/v1/statuses/123 → 404).