fix(tradein/admin): убрать показатели, которые не могут быть ненулевыми, и брать список источников из данных (#2674) #2684
Merged
bot-backend
merged 2 commits from 2026-08-05 23:01:31 +00:00
fix/2674-admin-metrics-honesty into main
2 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 3c5f535e6c |
fix(tradein/admin): гейт отмены по источнику, честный комментарий view, лимит 50 (#2674)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m2s
CI Trade-In / backend-tests (pull_request) Successful in 2m58s
Ревью PR #2684 — четыре MINOR. 1. Починка фильтра открыла кнопку отмены на все 53 источника. Раньше таблица была пуста на каждой вкладке, поэтому кнопка не рендерилась НИ РАЗУ и дыра не проявлялась: ручки отмены source не проверяют вовсе. Оператор на вкладке Авито мог бы «отменить» refresh_search_matview — задача продолжила бы работать под статусом 'cancelled' (ещё один врущий статус ровно в тот день, когда их вычищаем), а has_running_run перестал бы держать single-run guard, который существует из-за инцидента с двойным свипом и баном (2026-05-31). Гейт поставлен на общем узле всех пяти ручек — scrape_runs.honors_cancel + отказ в mark_cancelled, — а не в UI: иначе ручной POST по-прежнему снимал бы guard. Флаг cancellable отдаётся в строке, UI по нему прячет кнопку. Состав набора выведен из call-site'ов runs.is_cancelled: city-sweep'ы (все площадки и города), full-load'ы, avito_newbuilding_sweep, rosreestr_dkp_import. Правило НЕ «любой *_sweep»: yandex_newbuilding_sweep отмену не опрашивает. 2. Комментарий пересозданного v_data_quality утверждал, что его обновляет /api/v1/admin/data-quality. Читателей у view нет ни одного — живая ручка строит свой запрос. PR с тезисом «ложный показатель хуже отсутствующего» не имеет права переносить в прод ложное утверждение о читателе. 3. Лимит выдачи 20 → 50: первые 20 строк по started_at на три четверти — сердцебиение proxy_healthcheck (1631 из 3245), часовой сбор мог не поместиться. Привязка к вкладке НЕ возвращается. 4. Тест «действующее определение view» искал маркер подстрокой с OR REPLACE — миграция с обычным CREATE VIEW или парой DROP+CREATE была бы невидима, и тест проверял бы 214, пока показатель уже вернулся. Заменено регуляркой на обе формы. Фальсификация трёх новых тестов патч-методом — все три красные. Полный прогон 3490 passed / 9 skipped, tsc --noEmit чистый. |
|||
| 4d0795ae7a |
fix(tradein/admin): убрать показатели, которые не могут быть ненулевыми, и брать список источников из данных (#2674)
All checks were successful
CI / changes (pull_request) Successful in 7s
CI Trade-In / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m1s
CI Trade-In / backend-tests (pull_request) Successful in 2m57s
Четыре находки одного класса: админка показывает числа, которые никогда не бывают ненулевыми, и подаёт это как результат. Ноль читается оператором как «всё чисто», а не как «мы это не считаем» — такой показатель хуже отсутствующего. 1. «Помечено выбросов» (v_data_quality.outliers_flagged) — УБРАН вместе с колонкой listings.is_outlier. Механизм не «не доделан»: «выброс» у эстиматора вычисляется Tukey-фильтром по КОНКРЕТНОЙ подборке аналогов и живёт один запрос — один и тот же лот выброс для одной оценки и нормальный аналог для соседней. Persist-флаг на объявлении такое отношение выразить не может, реализовать пометку нечем. 2. http_requests / http_errors / returning_count / disappeared_count — УБРАНЫ. HTTP-запросы не считает ни один фетчер (заполнить нечем без сквозной инструментации). Ошибки и «пропало/вернулось» уже считает тот, кто их знает, и кладёт в counters jsonb: errors_count у pipeline, deactivated/revived у deactivate_stale_*. Отдельные колонки были бы вторым определением того же. 3. run_type — УБРАН из API, из таблицы админки и из схемы. Ни одно место кода его не задавало; DEFAULT из 051 подписывал 'city_sweep' даже proxy_healthcheck. Колонка «Тип» в UI заменена на «Источник» — там осмысленное значение. 4. Фильтр источников — теперь из данных (GET /scrape/runs/sources, SELECT DISTINCT source). Захардкоженная тройка не просто была неполной: сравнение точное, а строк с source='avito'/'cian'/'yandex' в таблице нет вообще, то есть каждый пункт фильтра давал пустую выдачу, и пустой выбор («Все») тоже — он молча подставлял source вкладки. Новый источник появляется в списке сам. Числа с прода (tradein-postgres, 2026-08-06): is_outlier=true у 0 из 93 408 listings (NULL у 0 — только DEFAULT); четыре счётчика = 0 во всех 3244 прогонах с миграции 015; run_type — одно значение на 3244 строки; 53 реальных источника, 2466 прогонов (76%) вне трёх площадок, включая весь Домклик. Миграция 214 идемпотентна; v_data_quality пересоздан тем же DDL минус outliers_flagged (порядок DROP VIEW → DROP COLUMN → CREATE как в 095). |