- чистка стоит на каждой точке входа значения метабазы в план — сборка матча, копия кандидата для ревью, набор закреплённых значений источника и его чтение: гарантия, поставленная только на запись, обходится данными, сохранёнными прежними версиями - название, непригодное как имя каталога (пустое или без единой буквы и цифры), не подставляется — раздача уходит в review с названной причиной - гейт подтверждения матча не сдвинут: сравнение с планом идёт по значениям провайдера, чистится только копия, уходящая дальше
70 lines
6.3 KiB
Markdown
70 lines
6.3 KiB
Markdown
## MODIFIED Requirements
|
|
|
|
### Requirement: Подтверждение матча обновляет отображаемое имя
|
|
|
|
Система SHALL при подтверждении матча в ревью запускать обновление отображаемого
|
|
имени загрузки по подтверждённому распознаванию (см. capability `ingest`):
|
|
переливать **полный ярлык** имени — «Название (режиссёр, год)», для сериала со
|
|
сводкой сезонов — в `download.display_name` и в имя раздачи qBittorrent, без
|
|
нового вызова LLM. Имя строится из эффективных полей (override → распознавание с
|
|
вложенным матчем → сохранённый контекст). Подтверждением матча SHALL
|
|
считаться как выбор кандидата из списка совпадений, так и ручное добавление
|
|
источника по id/URL (оба закрепляют провайдера и каноническое название).
|
|
|
|
Закрепляемое название источника SHALL проходить санитайзинг человекочитаемых
|
|
полей (см. `recognition`) и проверку пригодности как компонента пути (см.
|
|
`metadata-match`) — на **общей** точке сборки набора пинов источника, той же,
|
|
через которую строится предпросмотр. Отсюда следует свойство, на которое
|
|
опирается экран ревью: показанное для источника название и путь совпадают с тем,
|
|
что закрепится и разложится по выбору этого источника. Название, непригодное как
|
|
имя каталога, пином SHALL NOT становиться — в плане остаётся название
|
|
распознавания, а факт отказа SHALL быть наблюдаем в журнале.
|
|
|
|
Санитайзинг на закреплении SHALL применяться независимо от того, было ли значение
|
|
очищено при сохранении кандидата: гарантия чистоты не может держаться на времени
|
|
записи строки, иначе кандидаты, сохранённые прежними версиями, обходят её. Тот же
|
|
санитайзинг идемпотентен, поэтому на уже очищенном значении он ничего не меняет.
|
|
|
|
При закреплении выбранного/добавленного источника система SHALL best-effort
|
|
получить режиссёра этого источника из метабазы (credits по `provider:id`, см.
|
|
`metadata-match`) и закрепить его как override, чтобы он попал в эффективные поля
|
|
и в ярлык. Недоступность credits или отсутствие режиссёра SHALL NOT проваливать
|
|
выбор источника: режиссёр остаётся из более низкого слоя (сохранённый контекст)
|
|
или пустым. Так режиссёр из метабазы появляется и на **основном** пути
|
|
подтверждения — ручном выборе кандидата, а не только при авто-матче.
|
|
|
|
Обновление SHALL выполняться после успешного закрепления выбора кандидата и
|
|
SHALL быть best-effort по отношению к qBittorrent: недоступность клиента SHALL
|
|
NOT проваливать команду ревью. Это согласуется с инвариантом «авто-действие
|
|
только при подтверждённом матче».
|
|
|
|
#### Scenario: Выбор кандидата переливает каноническое имя
|
|
|
|
- **GIVEN** загрузка в ревью с кандидатами метабазы
|
|
- **WHEN** человек выбирает кандидата
|
|
- **THEN** провайдер, id и каноническое название закрепляются как override
|
|
- **AND** отображаемое имя загрузки обновляется полным ярлыком
|
|
|
|
#### Scenario: Название источника показано ровно таким, каким закрепится
|
|
|
|
- **GIVEN** кандидат, название которого содержит zero-width символ или
|
|
кириллический двойник внутри латинского слова
|
|
- **WHEN** строится список источников для экрана ревью
|
|
- **THEN** в строке источника и в его предпросмотре стоит очищенное название
|
|
- **AND** выбор этого источника закрепляет то же самое значение
|
|
|
|
#### Scenario: Кандидат, сохранённый прежней версией, чистится на закреплении
|
|
|
|
- **GIVEN** кандидат, чьё название записано в хранилище без санитайзинга
|
|
- **WHEN** человек выбирает этого кандидата
|
|
- **THEN** закрепляется санитизированное значение, а не то, что лежит в хранилище
|
|
|
|
#### Scenario: Непригодное название источника пином не становится
|
|
|
|
- **GIVEN** кандидат, название которого не содержит ни одной буквы и ни одной
|
|
цифры
|
|
- **WHEN** человек выбирает этого кандидата
|
|
- **THEN** название пином не становится, в плане остаётся название распознавания
|
|
- **AND** провайдер, id и год закрепляются как обычно
|
|
- **AND** отказ закрепить название виден в журнале
|