Files
jellybit/docs/adr/ADR-2026-08-07-tvdb-locale-reads-response.md
T
av c5d62d76ee docs: канон поднят с версии 7 до 12
- каталог задач переехал в tasks/ в корне, спринт упразднён — приоритет
  теперь порядок строк в BACKLOG.md, четыре задачи набора вернулись в беклог
- гейт: путь docs.py переведён на av-dev-docs вместо снесённого av-dev-pm,
  добавлены шаги tasks.py check и openspec.py check
- относительные ссылки внутри задач и ссылки из docs/ на задачи починены
2026-08-09 19:09:53 +03:00

67 lines
5.5 KiB
Markdown
Raw 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.
# Локаль TVDB читается из ответа поиска, а не передаётся в запрос
- **Дата:** 2026-08-07
- **Источник:** [openspec/changes/archive/2026-08-07-tvdb-title-locale/design.md](../../openspec/changes/archive/2026-08-07-tvdb-title-locale/design.md),
решение 1 и решение 1a
## Контекст
Глобальная настройка `[general].language` правит промпт LLM и клиент TMDB
([ADR решения 2](../../openspec/changes/archive/2026-07-24-content-language-switch/design.md)),
но до клиента TVDB не доезжала. TVDB отдавал primary name — название на языке
оригинала, — и оно попадало в карточку ревью и в имя папки Jellyfin как есть.
Очевидный подход, записанный прямо в постановке задачи и в её критерии приёмки:
добавить параметр языка в запрос `/search`, как это сделано для TMDB. От него
отказались.
## Решение
**Параметр языка в запрос поиска TVDB не передаётся. Локаль применяется только
при разборе ответа: `Candidate.Title` берётся из блока переводов, `OriginalTitle`
— из primary name.**
Цитата решения 1 архивного `design.md`:
> По [swagger TVDB v4, версия 4.7.10] у `/search` есть параметр `language` с
> описанием «Restrict results to a specific primary language. Should include the
> 3 character language code» — это **фильтр выдачи**, а не селектор перевода.
> Передача `language=rus` отсекла бы записи, основной язык которых не русский,
> то есть ровно наблюдаемый случай (`Ne Zha`, основной язык `zho`). Сужение
> выдачи — это изменение входа гейта матча, а задача такое явно запретила.
Тем самым два провайдера намеренно устроены по-разному: у TMDB локаль едет в
запрос, у TVDB читается из ответа. Асимметрия оставлена в клиентах, а не поднята
в общий тип: у TMDB карты названий в ответе нет вовсе, и общий тип пришлось бы
заполнять единственным ключом (решение 1a, форма B).
## Рассмотренные варианты
- **Слать `language` и мириться с сужением выдачи.** Ломает основной сценарий:
иноязычные записи, ради которых задача заводилась, пропадут из поиска.
- **Отдельный запрос `/movies/{id}/translations/{lang}` на каждого кандидата.**
Цена в лимитах ключа не окупает косметическое поле.
- **Заголовок `Accept-Language`.** Для v4 не документирован — была бы догадка.
- **`Candidate` несёт карту названий, выбор делает потребитель** (форма B). Язык
у потребителя уже есть, плюмбинг не нужен, но у TMDB карты в ответе нет —
внутри одного доменного типа завелись бы две формы.
- **TVDB не локализуется вовсе, заполняется только `OriginalTitle`** (форма C).
Тогда наблюдаемый случай чинится только при включённом TMDB, давшем матч, —
поведение молча зависело бы от набора включённых провайдеров.
## Последствия
- Критерий приёмки задачи «запрос поиска содержит параметр языка» выполнен быть
не может и отменён этим решением. Расхождение вынесено вопросом человеку —
разведка [tvdb-search-response-live-check](../../tasks/items/tvdb-search-response-live-check.md).
- **Решение опирается на документацию, а не на замер.** Семантика параметра и
форма блока переводов живым API не подтверждены —
[research/tvdb-search-translations.md](../research/tvdb-search-translations.md).
Если ручной прогон под ключом покажет иное, эта запись пересматривается новой,
а не правится.
- Заполнение `OriginalTitle` дало кандидату TVDB две оси сравнения вместо одной.
Логика гейта не менялась, но его вход изменился в обе стороны: запись, которую
отсекал иероглифический primary name, теперь может пройти по переводу, а две
разные записи могут совпасть с планом разными названиями и увести задачу в
review. Инвариант «авто-раскладка только при подтверждённом матче» не двигается.