review: убрать явный переключатель типа movie↔series из всех транспортов

Кнопка «Тип» была только в Telegram (доменная SetType = жёсткий override
media_type + хинт + перераспознавание), в вебе её нет. Это создавало
расхождение поверхностей и внутреннюю противоречивость спеки review.
Решение: смена типа — редкий случай, для него достаточно «Уточнить»
(перераспознавание с явным указанием типа). Явный переключатель не нужен
ни на одной поверхности.

Снято: Telegram-кнопка и callback type:, worker.SetType, ставший мёртвым
override-плумбинг media_type (ovrMediaType, ветка applyOverrides, хелпер
oppositeType) и стейл-хвосты в тестах httpapi. Спека review — три MODIFIED
требования (запрет на все поверхности, «фиксация типа» убрана из команд и
из быстрых действий Telegram, иллюстрация override заменена на закрепление
источника). Синхронизирован docs/specs/review-ux.md.

Change заархивирован: openspec/changes/archive/2026-07-18-review-remove-type-switch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-07-18 16:50:43 +03:00
co-authored by Claude Opus 4.8
parent 023fdacda5
commit 1d6f8f3449
13 changed files with 252 additions and 123 deletions
+2 -18
View File
@@ -67,7 +67,6 @@ type fakeReviewer struct {
data *worker.ReviewData
applied []string
refined map[string]string
typed map[string]string
deferred []string
canceled []string
retried []string
@@ -97,13 +96,6 @@ func (f *fakeReviewer) ChooseCandidate(_ context.Context, id, candidateID string
f.chosen[id] = candidateID
return nil
}
func (f *fakeReviewer) SetType(_ context.Context, id string, t string) error {
if f.typed == nil {
f.typed = map[string]string{}
}
f.typed[id] = t
return nil
}
func (f *fakeReviewer) Defer(_ context.Context, id string) error {
f.deferred = append(f.deferred, id)
return nil
@@ -270,14 +262,6 @@ func TestBot_CallbackApply(t *testing.T) {
}
}
func TestBot_CallbackType(t *testing.T) {
b, _, _, rev := newTestBot(t, []int64{7})
b.handleCallback(context.Background(), cbFrom(7, "type:"+tid+":movie"))
if rev.typed[tid] != "movie" {
t.Errorf("typed = %v", rev.typed)
}
}
func TestBot_CallbackRefineSetsPending(t *testing.T) {
b, api, _, _ := newTestBot(t, []int64{7})
b.handleCallback(context.Background(), cbFrom(7, "refine:"+tid))
@@ -457,8 +441,8 @@ func TestBot_CallbackRetry(t *testing.T) {
}
func TestParseCallback(t *testing.T) {
a, id, v := parseCallback("type:" + tid + ":series")
if a != "type" || id != tid || v != "series" {
a, id, v := parseCallback("pick:" + tid + ":" + tid)
if a != "pick" || id != tid || v != tid {
t.Errorf("got %q %q %q", a, id, v)
}
a, id, v = parseCallback("apply:" + tid)