web-ui: карточка и страница обновляются, пока задачу может двигать фон
- условие самообновления — доменный предикат store.State.IsObservable() вместо фазы catched; один поллер на поверхность, интервалы 5 с и 15 с - отказ тика отвечает 200 и самозавершающимся фрагментом с корневым id цели вместо 404/500, который htmx не свопит - заведён ADR-2026-08-10-observability-is-not-terminality, переписан раздел «Живой поллинг» в конвенции веб-UI
This commit is contained in:
@@ -653,3 +653,33 @@ func TestListAndByState(t *testing.T) {
|
||||
t.Fatalf("ListDownloadsByState(downloading) = %v", dl)
|
||||
}
|
||||
}
|
||||
|
||||
// TestIsObservable: наблюдаемость — «состояние ещё может измениться без
|
||||
// человека». Нетерминальные наблюдаемы все; из терминальных — те, которые фон
|
||||
// возвращает в поток сам (failed по восстановимым кодам, target_missing и
|
||||
// orphaned переоценивает сверка). done в перечень не входит сознательно: его
|
||||
// переоценка означает удаление файлов мимо сервиса.
|
||||
func TestIsObservable(t *testing.T) {
|
||||
observable := []State{
|
||||
StateCatched, StateDownloading, StateCompleted, StateRecognizing,
|
||||
StateReview, StateLinking, StateDeferred, StateStuck,
|
||||
StateFailed, StateTargetMissing, StateOrphaned,
|
||||
}
|
||||
silent := []State{StateDone, StateCancelled, StateReverted, StateDeleted}
|
||||
|
||||
for _, s := range observable {
|
||||
if !s.IsObservable() {
|
||||
t.Errorf("%s: IsObservable=false, want true", s)
|
||||
}
|
||||
}
|
||||
for _, s := range silent {
|
||||
if s.IsObservable() {
|
||||
t.Errorf("%s: IsObservable=true, want false", s)
|
||||
}
|
||||
}
|
||||
// Наблюдаемое множество не сводится к нетерминальному — иначе предикат был
|
||||
// бы лишним, а карточка упавшей задачи замирала бы навсегда.
|
||||
if !StateFailed.IsTerminal() || !StateFailed.IsObservable() {
|
||||
t.Error("failed должно быть терминальным и при этом наблюдаемым")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user