Каждый кандидат внешней базы метаданных (TMDB/TVDB/TVMaze) теперь несёт URL на страницу элемента — при ревью можно кликнуть и проверить матч. URL формируется клиентом провайдера при поиске, сохраняется в БД (metadata_candidate.url) и отображается ссылкой в веб-интерфейсе. Co-Authored-By: Claude <noreply@anthropic.com>
9.4 KiB
recognition Specification
Purpose
Распознавание: сопоставление загрузки с конкретным фильмом/сериалом во включённых базах метаданных. Capability описывает контракт LLM на названия, порядок и нормализацию сверки по нескольким названиям, локаль запроса к TMDB и сбор кандидатов для ручного выбора в review.
Requirements
Requirement: Сверка с базой по нескольким названиям
При сверке плана с включёнными базами метаданных система SHALL искать по
нескольким названиям в порядке убывания силы ключа: сначала по
original_title, затем по локализованному title, затем по provider_hint.
Поиск SHALL останавливаться, как только очередной запрос дал единичный
сильный матч (ровно один кандидат с совпадением названия и года). Запрос с
названием, нормализованно совпадающим с уже выполненным, система SHALL
пропускать, чтобы не обращаться к базе повторно с тем же ключом.
Кандидаты для ручного выбора в review система SHALL собирать из всех
выполненных заходов с дедупликацией по provider:id и общим потолком.
Scenario: Иностранный фильм находится по оригинальному названию
- GIVEN план с
title«Тёмный рыцарь»,original_title«The Dark Knight», год 2008 - WHEN выполняется сверка с базой
- THEN первый запрос идёт по «The Dark Knight»
- AND при единичном сильном матче дальнейшие запросы (по
title,provider_hint) не выполняются
Scenario: Фолбэк на локализованное название
- GIVEN план, для которого запрос по
original_titleне дал единичного сильного матча - WHEN продолжается сверка
- THEN выполняется запрос по локализованному
title - AND при отсутствии матча и там — запрос по
provider_hint
Scenario: Дублирующий запрос пропускается
- GIVEN план, у которого
original_titleнормализованно совпадает сtitle - WHEN выполняется сверка
- THEN база запрашивается этим названием один раз, повторный заход по
titleне делается
Requirement: Контракт LLM на оригинальное и локализованное названия
Промпт распознавания SHALL требовать от модели всегда заполнять и title, и
original_title. Если отдельного оригинального названия нет или контент
российского происхождения, модель SHALL дублировать title в
original_title. При неуверенности в оригинальном названии модель SHALL
дублировать title, а не выдумывать название (защита от ложного авто-матча).
Разбор ответа SHALL оставаться устойчивым к пустому original_title: пустое
значение не отбраковывается и не вызывает correction-ретрай; сверка
gracefully использует доступные названия.
Scenario: Российский фильм — дублирование
- GIVEN раздача российского фильма без отдельного оригинального названия
- WHEN модель возвращает план
- THEN
titleиoriginal_titleзаполнены одинаковым каноническим названием
Scenario: Пустой original_title не ломает разбор
- GIVEN ответ модели с пустым
original_title - WHEN план разбирается
- THEN разбор успешен без correction-ретрая
- AND сверка использует
title(иprovider_hint)
Requirement: Локаль запроса к TMDB
Запрос поиска к TMDB SHALL передавать параметр language, по умолчанию
ru-RU, со значением, настраиваемым конфигом [metadata.tmdb].language.
Это влияет только на локализованное поле Title/Name; поле
original_title/original_name остаётся на языке оригинала, поэтому
оригинальная сторона сравнения не затрагивается.
Scenario: Локализованный заголовок приходит по-русски
- GIVEN TMDB включён,
languageне задан в конфиге - WHEN выполняется поиск фильма с русской локализацией
- THEN запрос содержит
language=ru-RU - AND в кандидате
Titleприходит на русском, аOriginalTitle— на языке оригинала
Requirement: Нормализация названий при сравнении
Нормализация названий для гейта сильного матча SHALL сводить букву ё к е,
чтобы написания, различающиеся только ё/е, считались одним названием.
Scenario: «Тёмный» и «Темный» совпадают
- GIVEN план с названием «Тёмный рыцарь» и кандидат базы «Темный рыцарь»
- WHEN сравниваются нормализованные названия
- THEN они считаются совпадающими
Requirement: Кандидат несёт URL для внешней проверки
Каждый кандидат внешней базы метаданных (metadata.Candidate) SHALL нести
поле URL — ссылку на страницу элемента (фильма/сериала) на сайте
провайдера. URL SHALL формироваться клиентом провайдера при поиске
(Search) и сохраняться в таблице metadata_candidate. На странице ревью
URL SHALL отображаться кликабельной ссылкой, открывающейся в новой вкладке
браузера.
Формат URL для каждого провайдера:
- TMDB:
https://www.themoviedb.org/movie/{id}(фильм) илиhttps://www.themoviedb.org/tv/{id}(сериал) — тип контента известен из запросаQuery.Type - TVDB:
https://www.thetvdb.com/dereferrer/series/{id} - TVMaze:
https://www.tvmaze.com/shows/{id}— URL SHALL использовать нативный id TVMaze, а не внешний тег (TVDB/IMDb), чтобы ссылка вела на TVMaze-страницу
Scenario: Кандидат TMDB с корректной ссылкой
- GIVEN TMDB найден кандидат-фильм с id
603(«Матрица») - WHEN клиент TMDB формирует Candidate
- THEN
URL=https://www.themoviedb.org/movie/603
Scenario: Кандидат TVMaze с нативной ссылкой
- GIVEN TVMaze найден сериал с id
169(«Фарго»), внешний тег — TVDB id269613 - WHEN клиент TVMaze формирует Candidate
- THEN
URL=https://www.tvmaze.com/shows/169 - AND
TagProvider/TagIDостаютсяtvdb/269613(тег папки Jellyfin не меняется)
Scenario: Ссылка в интерфейсе ревью
- GIVEN загрузка в состоянии
reviewс кандидатами, у которых заполненurl - WHEN рендерится страница ревью
- THEN в таблице кандидатов каждый кандидат SHALL отображаться со ссылкой на внешний сайт
- AND ссылка открывается в новой вкладке (
target="_blank") - AND текстом ссылки служит провайдер или сокращённый url
Scenario: URL сохраняется в БД
- GIVEN результат поиска с кандидатами
- WHEN кандидаты сохраняются в таблицу
metadata_candidate - THEN значение
urlSHALL быть записано в колонкуurl - AND при последующей загрузке данных ревью url доступен без повторной генерации