Когда для распознавания сохранены кандидаты метабазы, карточка подтверждения бота показывает кнопку «🗂 База (N)». По ней двухшагово (как delete/dismiss) разворачивается список кандидатов inline-кнопками; выбор пиннит источник через worker.ChooseCandidate (ручной матч, без авто-раскладки) и обновляет карточку. Веб остаётся точкой точных правок (ручной ввод id/URL, «без базы»). Безопасность границы: id кандидата из callback_data валидируется как ULID (ident.Parse) до доменного вызова, как в вебе. Текст inline-кнопок Telegram не парсится как HTML — название кандидата в подписи не экранируется. SDD: change telegram-vybor-nahodok — дельта notifications (ADDED «Выбор кандидата метабазы из карточки подтверждения бота») + review (MODIFIED «Разделение труда транспортов»: быстрый выбор кандидата — Telegram-действие). Влито в specs, change заархивирован. Миграций БД нет (кандидаты уже в БД). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.1 KiB
5.1 KiB
Why
Распознавание уже копит кандидатов метабазы (recognize.Result.Candidates →
metadata_candidate), и веб даёт полный «единый список источников совпадения»
для точного выбора. В Telegram же карточка подтверждения показывает лишь
эффективный матч (строка «База: …» / «нет матча»), но не даёт выбрать между
несколькими найденными кандидатами: когда единичного сильного матча нет (частый
триггер ревью — «несколько кандидатов»), из бота нельзя быстро закрепить нужный,
приходится открывать веб. Ядро для этого уже готово: команда
worker.ChooseCandidate пиннит кандидата как источник (ручной матч), не
запуская авто-раскладку.
What Changes
- Карточка подтверждения (review) в боте, когда для распознавания есть сохранённые кандидаты метабазы, показывает кнопку выбора базы. По ней карточка двухшагово (как подтверждение удаления) разворачивает список кандидатов inline-кнопками — быстрый выбор из готового короткого списка.
- Выбор кандидата кнопкой вызывает
ChooseCandidate(пиннинг источника, ручной матч) и обновляет карточку на месте. Активный (уже выбранный) кандидат помечается в списке. Кнопка «← Назад» возвращает карточку без изменений. - Веб остаётся точкой точных правок (ввод id/URL вручную, «без базы», предпросмотр путей): бот — только быстрый выбор из уже найденных кандидатов.
- Безопасность границы: id кандидата приходит в
callback_data— недоверенный вход; перед доменным вызовом он валидируется как ULID (ident.Parse), как это уже делает веб-транспорт. Выбор кандидата — ручной матч, авто-раскладку не запускает (нужно явное «Применить»), инвариант авто-раскладки не двигается.
Capabilities
New Capabilities
Нет.
Modified Capabilities
notifications: добавляется требование к поверхности бота — предлагать выбор среди сохранённых кандидатов метабазы в карточке подтверждения (inline-кнопки, двухшаговое разворачивание), с валидацией id кандидата изcallback_dataна границе и без авто-раскладки. Доменная механика выбора (ChooseCandidate, пиннинг источника) уже покрыта capabilityreview— здесь не дублируется.review: MODIFIED требование «Разделение труда транспортов в ревью» — быстрый выбор источника из готового списка кандидатов теперь и Telegram-действие; точный ручной ввод id/URL и «без базы» остаются за вебом. Снимает межспековое расхождение (прежде выбор источника целиком относился к веб-точным-правкам).
Impact
- Спеки: дельта
notifications— ADDED «Выбор кандидата метабазы из карточки подтверждения бота»; дельтаreview— MODIFIED «Разделение труда транспортов в ревью» (быстрый выбор кандидата — Telegram-действие). - Код:
internal/tgbot/bot.go(интерфейсReviewer+ChooseCandidate; callback-и списка/выбора/назад),internal/tgbot/render.go(кнопка выбора базы вreviewKeyboard, клавиатура списка кандидатов). - Тесты:
internal/tgbot— карточка с кандидатами содержит кнопку выбора; разворачивание даёт список; выбор зовётChooseCandidateс валидным id; невалидный id из callback отклоняется. - Миграции БД: нет (кандидаты уже в БД — таблица
metadata_candidate).