Единый источник полей отображаемого имени и один рендер полного ярлыка на всех путях (старт и «Обновить имя»/авто-перелив). Раньше старт давал полный «Название (режиссёр, год). Сезон N» но выбрасывал структуру, а перелив по распознаванию — усечённый «Title (Year)». - Слоистое разрешение скаляров имени: override → recognition(+match) → новый базовый слой «контекст» (download.parsed_context, JSON naming.Fields). - naming: публичные Fields/Label/Derive, вынесен единый рендер; удалён FormatTitleYear. Сводка сезонов вынесена в recognize.SeasonSummary. - Режиссёр из метабазы (решение A2): TMDB/TVDB credits через опциональный metadata.DirectorProvider; авто-матч кладёт в plan.Director, ручной выбор кандидата тянет credits и пиннит ovrDirector. Метабаза бьёт контекст. - refreshDisplayNameLocked строит полный ярлык из эффективных полей; инфо-панель ревью показывает загруженного режиссёра. - Миграция 0011_parsed_context + ER-схема. Всё косметика: на пути/раскладку не влияет, приём/вывод имени не валятся (best-effort). Закрывает беклог-задачу «Кнопка „Обновить имя“: полный формат ярлыка». OpenSpec: archive/2026-07-11-field-resolution-display-name (ingest, recognition, metadata-match, review). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.4 KiB
review Specification
MODIFIED Requirements
Requirement: Подтверждение матча обновляет отображаемое имя
Система SHALL при подтверждении матча в ревью запускать обновление отображаемого
имени загрузки по подтверждённому распознаванию (см. capability ingest):
переливать полный ярлык имени — «Название (режиссёр, год)», для сериала со
сводкой сезонов — в download.display_name и в имя раздачи qBittorrent, без
нового вызова LLM. Имя строится из эффективных полей (override → распознавание с
вложенным матчем → сохранённый контекст). Подтверждением матча SHALL
считаться как выбор кандидата из списка совпадений, так и ручное добавление
источника по id/URL (оба закрепляют провайдера и каноническое название).
При закреплении выбранного/добавленного источника система SHALL best-effort
получить режиссёра этого источника из метабазы (credits по provider:id, см.
metadata-match) и закрепить его как override, чтобы он попал в эффективные поля
и в ярлык. Недоступность credits или отсутствие режиссёра SHALL NOT проваливать
выбор источника: режиссёр остаётся из более низкого слоя (сохранённый контекст)
или пустым. Так режиссёр из метабазы появляется и на основном пути
подтверждения — ручном выборе кандидата, а не только при авто-матче.
Обновление SHALL выполняться после успешного закрепления выбора кандидата и SHALL быть best-effort по отношению к qBittorrent: недоступность клиента SHALL NOT проваливать команду ревью. Это согласуется с инвариантом «авто-действие только при подтверждённом матче».
Scenario: Выбор кандидата обновляет имя
- GIVEN загрузка в ревью с пустым или неинформативным
display_name(например, «Unknown») и списком кандидатов - WHEN пользователь выбирает кандидата, подтверждая матч
- THEN выбор кандидата закрепляется как и прежде
- AND
download.display_nameобновляется полным ярлыком «Название (режиссёр, год)» (для сериала — со сводкой сезонов) - AND раздача в qBittorrent переименовывается в то же имя
Scenario: Ручное добавление источника обновляет имя
- GIVEN загрузка в ревью без совпадений в списке
- WHEN пользователь вручную добавляет источник по id/URL, подтверждая матч
- THEN источник закрепляется как и прежде
- AND
download.display_nameи имя раздачи в qBittorrent обновляются полным ярлыком подтверждённого источника
Scenario: Выбор кандидата подтягивает режиссёра в ярлык
- GIVEN загрузка в ревью, у выбранного кандидата в credits метабазы указан режиссёр
- WHEN пользователь выбирает кандидата, подтверждая матч
- THEN режиссёр best-effort извлекается из метабазы и закрепляется override
- AND
download.display_nameполучает полный ярлык с этим режиссёром
Scenario: Режиссёр кандидата недоступен — выбор не ломается
- GIVEN выбор кандидата, для которого credits недоступны или режиссёра нет
- WHEN пользователь подтверждает матч
- THEN выбор источника выполнен, режиссёр берётся из сохранённого контекста или остаётся пустым
- AND команда ревью не возвращает ошибку
Scenario: Недоступность qBittorrent не ломает выбор кандидата
- GIVEN выбор кандидата в ревью
- WHEN переименование раздачи в qBittorrent завершается ошибкой
- THEN выбор кандидата и обновление
download.display_nameвыполнены - AND команда ревью не возвращает ошибку
Requirement: Инфо и предпросмотр выбранного источника
В едином блоке выбора источника экран ревью SHALL показывать для выбранного
(активного) источника две части: инфо — тип (read-only, movie/series),
название, оригинальное название, год, режиссёра (из подтверждённого матча/
кандидата, когда доступен; иначе пусто/прочерк, не ломая вёрстку), для сериала —
сводку сезонов (один сезон, диапазон/список для многосезонного пака или
«Спецвыпуски»); и предпросмотр раскладки — целевые пути хардлинков этого
источника. Обе части SHALL относиться именно к активному источнику и SHALL
обновляться при смене выбора. Отрисовка блока (показ инфо и предпросмотра) MUST
NOT создавать хардлинки: раскладка создаётся только явным действием «Применить».
Совпадение целевых путей предпросмотра с результатом применения регулируется
требованием «Превью раскладки через единую логику именования» (web-ui).
Scenario: Инфо и предпросмотр относятся к активному источнику
- GIVEN в списке активен кандидат метабазы
- WHEN пользователь смотрит инфо-часть и предпросмотр раскладки
- THEN показаны тип, название, ориг. название, год (и сводка сезонов для сериала) именно этого источника и предпросмотр его целевых путей
Scenario: Просмотр блока не создаёт раскладку
- GIVEN экран ревью с показанным блоком выбора источника
- WHEN пользователь только просматривает инфо и предпросмотр, не нажимая «Применить»
- THEN хардлинки не создаются, файлы под
paths.movies/seriesне меняются
Scenario: Режиссёр показан, когда доступен
- GIVEN активный источник — подтверждённый матч, несущий режиссёра
- WHEN отображается инфо-часть выбранного источника
- THEN в ней показан режиссёр этого источника
- AND при отсутствии режиссёра место остаётся пустым (или прочерком), не ломая вёрстку