openspec: архивирован change gotosocial-publisher (2026-09-13), delta влита в specs/gotosocial-publisher

This commit is contained in:
kpa39l
2026-09-13 20:27:41 +00:00
parent bf176cc02b
commit 6b955aa143
6 changed files with 79 additions and 5 deletions
@@ -38,8 +38,8 @@
## 7. Документация и git ## 7. Документация и git
- [ ] 7.1 STATUS.md: раздел «Fediverse-публикация (GoToSocial)» - [x] 7.1 STATUS.md: раздел «Fediverse-публикация (GoToSocial)»
- [ ] 7.2 WALKTHROUGH.md/PRD.md: фича отмечена - [x] 7.2 WALKTHROUGH.md/PRD.md: фича отмечена
- [ ] 7.3 git commit + push на gitverse - [x] 7.3 git commit + push на gitverse
- [ ] 7.4 openspec archive (после подтверждения пользователя) - [x] 7.4 openspec archive (после подтверждения пользователя)
- [ ] 7.5 backup.sh (обязателен после изменений) - [x] 7.5 backup.sh (обязателен после изменений)
@@ -0,0 +1,74 @@
# 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).