В карточке подтверждения и уведомлении о готовности бот теперь показывает
запись матча метабазы — провайдер, id и кликабельную ссылку на страницу
записи, — как веб-страница /download/{id} и экран ревью. Так ошибочную
привязку видно и из Telegram.
Билдер URL записи (providerURL/matchURL) вынесен из internal/httpapi в ядро
internal/worker (worker.ProviderURL + метод (*ReviewData).MatchURL()), чтобы
оба транспорта строили ссылку одинаково; httpapi делегирует туда. baseLine
переведён на эффективные provider/id (с учётом ручных правок), URL в href
экранируется escHref (сверх esc закрывает кавычку — иначе изготовленный id
разорвал бы атрибут и Telegram отклонил бы сообщение). При отсутствии матча
карточка ревью показывает «нет матча», уведомление о готовности строку
опускает.
Capability notifications: ADDED «Показ записи матча метабазы» + MODIFIED
требования об экранировании (id матча и URL, контекст href).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.7 KiB
2.7 KiB
1. Ядро: общий билдер URL
- 1.1
internal/worker/review.go: добавить экспортируемуюfunc ProviderURL(provider, id, mediaType string) string(канонический URL; пустой id / неизвестный провайдер → пусто) и методfunc (rd *ReviewData) MatchURL() string(приоритет URL выбранного кандидата при совпадении provider+id с эффективными, иначеProviderURLпоrd.Provider/rd.ProviderID/rd.Plan.Type). - 1.2 Перенести тесты
providerURL/matchURLвinternal/worker(изinternal/httpapi/providerurl_test.go), поправив на новые имена/сигнатуры.
2. httpapi: делегирование
- 2.1
internal/httpapi/review.go/download.go: удалить локальныеproviderURL/matchURL;view.MatchURL = rd.MatchURL();sourceMatchURLзовётworker.ProviderURL(src.Provider, src.ProviderID, src.Type).parseProviderURL/parseManualSourceостаются в httpapi.
3. tgbot: показ матча
- 3.1
internal/tgbot/render.go:escHref— экранирование URL для значения атрибутаhref(поверхescзаменяет"→"). - 3.2
baseLineпринимает*worker.ReviewData, использует эффективныеrd.Provider/rd.ProviderIDиrd.MatchURL(): при непустом URL —<a href="...">provider id ↗</a>(provider/id черезesc, URL черезescHref), иначе текстprovider id; при отсутствии матча — пусто. - 3.3
reviewCardзовётbaseLine(rd), при пустом результате показывает «База: нет матча» (сохранение поведения);renderDoneдобавляет строку «База: …» только при непустомbaseLine(rd)(без матча — опускает).
4. Тесты
- 4.1
internal/tgbot: карточка ревью с матчем содержит<a href=...↗; провайдер/id экранированы; матч без URL — текстом;renderDoneсодержит строку матча при матче и опускает её без матча; карточка ревью без матча — «нет матча». - 4.2
internal/tgbot: id с"— кавычка вhrefэкранируется ("), атрибут остаётся целым.
5. Спека и проверки
- 5.1
openspec validate --strict telegram-metabase-match. - 5.2
task testиtask lint— зелёные.