3136 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 49652f4413 |
fix(mera/b2c): вернуть потерянные вопросы FAQ, починить адрес превью и честность двух комментариев
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
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 1m0s
Правки по трём ревью ветки «v3 становится корнем».
FAQ. Из шести вопросов `content.ts` возражения v3 брали два, остальные
четыре (`how-accurate`, `vs-marketplace`, `personal-data`, `bank-report`)
не рендерились нигде: `Faq.tsx`, который выводил все шесть, удалён вместе
с лэндингом v1. Макетные возражения их тематически закрывали, но
пересказом — а оригиналы проходили юр-ревью. Содержательно пропали два
утверждения: «Имя, паспорт и документы на квартиру мы не спрашиваем» с
отсылкой к странице ПДн (152-ФЗ) и «показываем диапазон, а не одно число»
как прямой ответ про точность (рамка диапазона осталась только в
`AccuracyV3`, рядом с плейсхолдерными числами).
Теперь в секции один порядок чтения: все шесть вопросов из `FAQ` по id
плюс три макетных возражения, которым в `FAQ` пары нет («факт сделки»,
«почему так дёшево», «подписка»). Три макетных пересказа удалены в пользу
оригиналов; у «почему так дёшево» убран второй абзац — почти дословный
повтор второго абзаца `how-accurate`, который теперь стоит следующим.
Новых формулировок не добавлено. Отсылка к странице ПДн стала живой
ссылкой через `PublicLink` (обычный `<a>`, basePath не течёт); текст
ссылки — слова самого `content.ts`, найденные по вхождению.
Гейт стал двусторонним: тест перебирает `FAQ` и требует, чтобы КАЖДЫЙ id
был отрисован. Прежняя версия перечисляла два id руками и потому молчала
ровно в тот момент, когда четыре ответа исчезли со страницы. Проверено
мутацией: снятие вопроса, переименование id и переформулировка фразы про
ПДн красят тест по отдельности.
CADDY. `/trade-in/mera-public/v3` выбыл из @meraLongPages вместе со
страницей и никуда не попал — длинный адрес превью падал в catch-all 404,
хотя раньше вёл на страницу. Обе его формы добавлены в @meraV3Gone. Там же
редирект перестал терять query: было `redir * /`, стало `redir * {uri}`
со срезанием пути — как у @meraLongPages, где перенос UTM и обоснован.
Проверено на живом Caddy 2.11 по настоящему site-блоку: все четыре формы
дают 301 на `/` с сохранённой query, без параметров — чистый `/` без
хвоста `?`, соседние матчеры не задеты, лишний сегмент по-прежнему 404.
КОММЕНТАРИИ, ОПИСЫВАЮЩИЕ НЕСУЩЕСТВУЮЩЕЕ. Строка `page.tsx` в гейте
плейсхолдеров убрана: комментарий над ней утверждал, что устаревший путь
«перестал бы что-либо сканировать», но ни в корневом `page.tsx`, ни в
прежнем `v3/page.tsx` нет ни одного имени из `PLACEHOLDER_EXPORTS` —
страница только собирает секции. Замер подтверждает: множество найденных
плейсхолдеров со строкой и без неё совпадает, а сама по себе она не даёт
ничего. Держать её значило держать ложное ощущение охвата.
Дескриптор «Оценка вторичного жилья по рыночным данным · <регион>» на
внутренние страницы не возвращается — причина записана в докстринге
`InnerHeader`: эту шапку носят и `/estimate`, `/articles`, `/docs`, где
дескриптора не было никогда; требование юриста было про первый экран
лэндинга и там выполняется `HeroV3`; на самих юр-страницах то же сказано
сильнее — в тексте оферты (п. 1.3, 6.2) и в `FooterV3` на каждой странице.
|
|||
| 6976ca8915 |
feat(mera/b2c): лэндинг v3 становится корнем публичного домена
Вариант дизайна выбран — превью с /mera-public/v3 переехало в корень целиком, вместе с блоками, перенесёнными из v1 предыдущим шагом. Каталог v3/ и компоненты v1 (Hero / HowItWorks / WhatYouGet / DataSources / Faq / AddressForm / SiteHeader / SiteFooter) удалены: их данные живут в content.ts и уже читаются секциями v3, поэтому ушла только вёрстка. Юридические страницы (оферта, возврат, ПДн) держались на SiteHeader/ SiteFooter — единственные, кто их ещё импортировал. Переведены на InnerHeader + FooterV3, тем же способом, что /estimate, /articles и /docs. ПЕРИМЕТР. /v3 убран из @meraPages, @meraShortSlash и @meraLongPages, но не выброшен: адрес две недели был открыт наружу и разошёлся по закладкам, поэтому вместо тишины белого списка — 301 на корень (@meraV3Gone, обе формы). На это заведена проверка в public-perimeter.test.ts по образцу соседних; PREVIEW_ONLY стал пустым, а не удалённым — он держит проверку «наружу не открыто ничего сверх известных страниц» двусторонней. Из PUBLIC_SHORT_PATHS гварда /v3 убран: редирект отрабатывает в Caddy, до приложения запрос не доходит, а недостижимая строка в списке публичных путей сделала бы публичной будущую страницу с тем же адресом. Гейт Caddy→гвард односторонний и сам бы этого не поймал — обоснование в коде. NOINDEX ОСТАВЛЕН. Он держится за плейсхолдерные числа marketing-v3.ts (#2904), а не за то, какой вариант дизайна стоит в корне. Путь в гейте обновлён на page.tsx: placeholdersInUse() молча пропускает ненайденный файл, поэтому устаревшая строка не покраснела бы, а перестала бы сканировать. |
|||
| d4e106882c |
feat(mera/b2c): перенести потерянные блоки v1 в лэндинг v3
Корень meraocenka.ru отдаёт v1, новый дизайн живёт на /v3 и скоро станет корнем. Шесть вещей из v1 в v3 отсутствовали — при переключении они бы просто исчезли с публичного сайта: - реестра источников не было вовсе (SourcesV3, из SOURCE_GROUPS); - «что вы получите» и дисклеймера 135-ФЗ не было (WhatYouGetV3): о том, что это не отчёт аккредитованного оценщика, узнавал только тот, кто сам догадался открыть нужное возражение; - герой не называл границу покрытия (полное — Екатеринбург, частично — остальные города области, по другим регионам не считаем) и не говорил, что мы не покупаем квартиры и не берём их на продажу; - два вопроса FAQ («откуда вы знаете, сколько стоит именно моя квартира», «почему только Свердловская область») в возражениях v3 не звучали — теперь берутся из FAQ по id, а не копией строк; - карточка проверки не спрашивала город: гео-гейт #2576 на новом лэндинге был сломан (без города «Ленина, 1» уходит в одноимённую улицу ЕКБ); - она же спрашивала состояние обязательным полем и выбрасывала ответ на переходе — теперь он доезжает в черновике. Тексты перенесены дословно (проходили юр-ревью), новых чисел нет. Новые секции встали после «Точности»: сверяем прогноз с фактом → на каких данных → что получаете на руки, всё до первого разговора про деньги. Гейт: __tests__/v3-ported-copy.test.ts — проверен мутацией (снятие секции со страницы и переименование id вопроса красят его). |
|||
| deddef80ad |
Merge pull request 'feat(mera/b2c): раздел статей и хаб документов (макет 29.08) + числа статьи заменены на замер' (#3223) from feat/b2c-articles-docs into main
All checks were successful
Deploy Infra Host / sync-infra-host (push) Successful in 6s
Deploy / changes (push) Successful in 8s
Deploy Trade-In / changes (push) Successful in 13s
Deploy / deploy-caddy (push) Has been skipped
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy / build-frontend (push) Successful in 42s
Deploy Trade-In / build-frontend (push) Successful in 2m38s
Deploy Trade-In / deploy (push) Successful in 1m4s
Deploy Trade-In / deploy-status (push) Successful in 6s
Deploy / build-backend (push) Successful in 3m57s
Deploy Trade-In / perimeter-smoke (push) Successful in 15s
Deploy / build-worker (push) Successful in 4m52s
Deploy / deploy (push) Successful in 1m31s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 12s
|
|||
| 2d8edd2c4f |
feat(mera/b2c): раздел статей и хаб документов (макет 29.08) + числа статьи заменены на замер
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 58s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
Последняя часть макета Макса «B2C модуль для МЕРА»: /articles, /articles/kak-ocenit-kvartiru, /docs. Проводка ссылок доведена до конца — «Статьи» и «Проверьте себя» в шапке и подвале перестали быть заглушками, EstimateHeader переименован в InnerHeader (он теперь стоит на трёх страницах, а не только на проверке). ЧИСЛА СТАТЬИ — НЕ ИЗ МАКЕТА. Макет утверждал «по нашим данным, средний разрыв между первой ценой в объявлении и ценой сделки — 4,1%, а у провисевших дольше трёх месяцев доходит до 9%». Прод-замер (poincare, 29.08) показал, что величины такого рода у нас нет вовсе: связки листинга со сделкой в данных не существует (cadastral_number пуст у всех 108 623 сделок и 111 693 объявлений). Заменено на то, что измеряется парно и честно: по 6202 объявлениям Домклик в ЕКБ (срез 18.07.2026) цену снижали 44%, а среди провисевших дольше трёх месяцев — 62% в медиане на 4,9%. Границы замера названы в самом тексте: это движение цены В ОБЪЯВЛЕНИИ, а не скидка на сделке, и объявлений моложе трёх недель в выборке нет (прогон обогащения их не захватил), поэтому по всему живому рынку доля ниже. Заодно сняты остальные непроверяемые утверждения: «расхождение с кадастровой до 40%» (кадастровой стоимости ПОМЕЩЕНИЙ нет ни в одной базе — проверить нечем), поправки §3 помечены как рыночная практика, а не наш замер, пороги фильтра §2 приведены к тем, что реально стоят в оценщике (радиус 1 км, площадь ±15%, минимум 5 аналогов + каскад послаблений). Плейсхолдеров marketing-v3 в статье не осталось. Периметр закрыт во всех трёх местах: @meraPages / @meraShortSlash / @meraLongPages в apps.caddy, PUBLIC_ROUTES и PUBLIC_SHORT_PATHS в гварде. @meraShortSlash до сих пор не проверялся ничем — добавлен гейт в public-perimeter.test.ts (фальсифицирован: снятие /docs из альтернации красит тест). Гейт #2904 теперь видит и статью (articles-content.ts в V3_SOURCES) — фальсифицировано отдельно: с одним этим файлом в списке снятие noindex красит гейт. Честные отличия от макета — в докстрингах страниц: масок реквизитов и макетной редакции оферты нет (источник правды — /oferta, /privacy, /refund от 13.08), регламент ответа поддержки «9:00-19:00» снят (никто его не устанавливал), фильтр рубрик и обещание «новые статьи каждую неделю» не рендерятся. Проверено: tsc, eslint, vitest 69/69, изоляция mera-public, скриншоты трёх страниц на 1180/375/320px без горизонтального переполнения. |
|||
| fa62d69fb9 |
Merge pull request 'fix(tradein/domclick): detail-бэкфилл ходил в сайдкар мимо прокси-пула (#3197 ч.1)' (#3222) from fix/3197-domclick-backfill-proxy-pool into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m55s
Deploy Trade-In / build-backend (push) Successful in 1m6s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
Deploy Trade-In / deploy (push) Successful in 1m29s
Deploy Trade-In / deploy-status (push) Successful in 1s
|
|||
|
|
301d803ac5 |
test(tradein/domclick): второй assert_called_once_with на конструкторе (#3197 ч.1)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 11s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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 / backend-tests (pull_request) Successful in 4m58s
CI Trade-In / backend-tests упал на tests/tasks/test_domclick_detail_backfill.py:165 — там тот же хрупкий assert_called_once_with, что уже был поправлен в tests/test_3118_domclick_warm_context.py: он фиксирует ТОЧНУЮ сигнатуру вызова BrowserFetcher и ломается на любом новом kwarg. Лечение то же самое: assert_called_once() + точечная проверка source/endpoint/ reuse_context. Полная проводка пула покрыта отдельным tests/test_3197_domclick_proxy_pool_wiring.py. Причина пропуска: локально прогонялась выборка из трёх файлов, а не весь набор. Теперь прогнан весь: 4974 passed, 37 skipped, 0 failed. |
||
|
|
fd95c962bb |
fix(tradein/domclick): backfill ходил в сайдкар мимо прокси-пула (#3197 ч.1)
Some checks failed
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
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 / backend-tests (pull_request) Failing after 4m53s
BrowserFetcher(source="domclick", reuse_context=True) конструировался без proxy_provider/use_pool/environment -- тела POST /fetch не несли "proxy", сайдкар брал свой env-прокси, и прогон шёл мимо пула целиком: ни выбора узла по affinity, ни scrape_proxy_source_bans, ни ротации при блоке. Тот же дефект уже чинили на avito_detail_backfill/house_imv_backfill (#2698) -- этот call site оставался последним непочиненным. environment обязателен: без него отказ «пул пуст» на этом пути мёртв (#2616 шаг 1). reuse_context=True сохранён без изменений. Заодно поправлен устаревший комментарий над конструктором: ссылался на scrape_proxies.provider_affinity='domclick' и миграцию 173 -- на проде такого больше нет (миграция 253 сняла резервацию узла, #2800), все четыре включённых узла (id 1/9/10/11) имеют provider_affinity='any'. test_3118_domclick_warm_context.py обновлён под новую сигнатуру вызова (assert_called_once_with -> точечная проверка нужных kwargs). |
||
| 51fd939f5c |
Merge pull request 'feat(mera/b2c): результат проверки в облике отчёта (макет 29.08 «МЕРА отчёт»)' (#3221) from feat/b2c-report-redesign into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 2m6s
Deploy Trade-In / deploy (push) Successful in 55s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
|
|||
| de66826b25 |
feat(mera/b2c): результат проверки в облике отчёта (макет 29.08 «МЕРА отчёт»)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
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 59s
Редизайн результата /estimate по макету отчёта: шапка объекта (адрес + чипы параметров + «Изменить данные»), две большие бесплатные карточки, тизер платной части с shimmer-строками, честные состояния «мало данных» и «город не покрыт» в стилистике «ЧЕСТНЫЙ ОТВЕТ». Сознательные расхождения с макетом (задокументированы в шапке компонента): - «✓ расчёт готов и ждёт вас» не воспроизводится — платного расчёта для анонима не существует (анонимный /estimate закрыт, платёжного контура нет, #2896); тизер честно называется «что будет в полном отчёте», вместо кнопки оплаты — прежняя формулировка «приём оплаты подключается»; - бейджи МИР/СБП/VISA — за тем же TODO платёжного контура, что и в FooterV3; - email-подписка «сообщим когда добавим» — нет хранения и согласия (#2895), вместо неё живой канал поддержки; - «Расширить радиус до 3 км» — /coverage радиус не параметризует; - подписи бесплатных плиток — запиненные честные из coverage-copy. Возврат 150 ₽ — строкой из макета со ссылкой на /refund. Старый CoverageResult удалён (один рендер результата, не два). Фикстурное превью всех трёх тонов — /mera-public/ui-preview/report. Проверено: tsc чисто, lint чисто, vitest 27 passed, скрин трёх состояний. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 9f45c7616c |
Merge pull request 'chore(ci): node 20 отслужил — рантайм фронтов и оба CI-джоба на node 24 LTS' (#3214) from chore/node24-runtime into main
Some checks failed
Deploy / changes (push) Successful in 8s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy Trade-In / changes (push) Successful in 12s
Deploy / deploy-caddy (push) Has been skipped
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 3m22s
Deploy Trade-In / deploy (push) Successful in 58s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy / build-frontend (push) Successful in 4m38s
Deploy Trade-In / perimeter-smoke (push) Successful in 14s
Deploy / deploy (push) Failing after 15m16s
Deploy / perimeter-smoke (push) Has been skipped
Deploy / deploy-status (push) Failing after 1s
|
|||
| f37d3476a4 |
Merge pull request 'chore(deps/site-finder): vitest 2 → 3 — заодно уходит вся dev-цепочка vite/esbuild' (#3218) from chore/vitest3-sitefinder into main
Some checks failed
Deploy / perimeter-smoke (push) Blocked by required conditions
Deploy / deploy-status (push) Blocked by required conditions
Deploy / changes (push) Successful in 10s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-frontend (push) Successful in 5m10s
Deploy / deploy (push) Has been cancelled
|
|||
| 8f5a87d4dc |
Merge pull request 'chore(deps): три места, где сборка не воспроизводится — лок-призрак, глоб и неприпинованный сайдкар' (#3213) from chore/deps-hygiene-dockerfiles into main
Some checks are pending
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / deploy-caddy (push) Blocked by required conditions
Deploy / perimeter-smoke (push) Blocked by required conditions
Deploy / deploy-status (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 15s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Successful in 2m42s
Deploy Trade-In / test (push) Successful in 4m17s
Deploy Trade-In / build-backend (push) Successful in 1m6s
Deploy Trade-In / deploy (push) Successful in 2m12s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
|
|||
| fbc8e89b6f |
Merge pull request 'fix(tradein/domclick): перезапуск браузера на карточку уничтожал пропуск QRATOR (#3212)' (#3217) from fix/3212-domclick-keep-context into main
Some checks failed
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / perimeter-smoke (push) Blocked by required conditions
Deploy Trade-In / deploy-status (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 14s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Successful in 2m19s
Deploy Trade-In / test (push) Has been cancelled
|
|||
|
|
0f6cf5c67d |
chore(deps/site-finder): vitest 2 → 3 — заодно уходит вся dev-цепочка vite/esbuild
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 11s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m11s
CI / openapi-codegen-check (pull_request) Successful in 2m3s
Зеркало #3216 для Site Finder. Отдельным PR, чтобы CI двух приложений не блокировали друг друга. Мажор ради GHSA-5xrq-8626-4rwp (CRITICAL, vitest ≤2.x). Сам CRITICAL к нам неприменим — он про `--ui`, а `@vitest/ui` не установлен и скриптов с `--ui` нет — но держать заведомо непатченный рантайм тестов ради этого рассуждения не стоит. vitest тянет vite сам, и у мажора другой диапазон (2.1.9 → vite ^5.0.0; 3.2.7 → ^5||^6||^7), поэтому одним мажором: vitest 2.1.9 → 3.2.7 GHSA-5xrq-8626-4rwp vite 5.4.21 → 7.3.6 GHSA-4w7w-66w2-5vf9, GHSA-fx2h-pf6j-xcff, GHSA-v6wh-96g9-6wx3 esbuild 0.21.5 → 0.28.2 GHSA-67mh-4wv8-2f99 OSV по локу: 4 → 1. Остаток — postcss 8.4.31, вендоренный ВНУТРИ next/node_modules; нашим локом не управляется. @vitejs/plugin-react 4.3.4 → 5.2.0 — вынужденно: у 4.x peer на vite ^4||^5||^6, семёрка туда не попадает. В 6.x не идём — там peer уже ^8.0.0. vitest.config.ts не тронут: в нём нет ничего из переименованного/убранного мажором (ни environmentMatchGlobs, ни deps.inline, ни workspace). Приёмка (локально, node 26): npm run test 278 passed, 13 failed npm run type-check ok 13 падений — те же самые, что на vitest 2 (те же 4 файла: api, useParcelAnalyzeQuery, AnalysisPageContent.weights, WeightProfilePanel.identity; TypeError на src/lib/sessionId.ts:8, localStorage undefined). Мажор их не добавил и не убрал. Причина локальная — node 26 против node 20/24 в CI. Гейт — CI. |
||
| a3e642fed4 |
Merge pull request 'chore(deps/mera): vitest 2 → 3 — заодно уходит вся dev-цепочка vite/esbuild' (#3216) from chore/vitest3-mera into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 13s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 3m24s
Deploy Trade-In / deploy (push) Successful in 59s
Deploy Trade-In / deploy-status (push) Successful in 2s
Deploy Trade-In / perimeter-smoke (push) Successful in 14s
|
|||
| 2f91b4b34f |
Merge pull request 'feat(mera/b2c): лэндинг v3 доведён до макета 29.08 — лента, игра, два пути, возражения, статьи' (#3215) from feat/b2c-landing-v3-full into main
Some checks are pending
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Blocked by required conditions
Deploy Trade-In / build-browser (push) Blocked by required conditions
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / perimeter-smoke (push) Blocked by required conditions
Deploy Trade-In / deploy-status (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 13s
Deploy Trade-In / test (push) Has been skipped
|
|||
|
|
09bdd7888b |
fix(tradein/domclick): перезапуск браузера на карточку уничтожал пропуск QRATOR (#3212)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 19s
CI Trade-In / frontend-checks (pull_request) Has been skipped
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 / browser-tests (pull_request) Successful in 1m10s
CI Trade-In / backend-tests (pull_request) Successful in 5m23s
ДомКлик закрыт QRATOR с proof-of-work: первый запрос отдаёт 401 и заглушку с задачей, браузер её решает, дёргает /__qrator/validate и получает пропуск в куках (qrator_jsid2 + qrator_jsr). Пропуск живёт в cookie jar, то есть в browser context'е — а прод брал каждую карточку в новом контексте, выбрасывая его. Повторная валидация с того же IP получала 403 и страницу bot-mitigation. Замер (прод, прод-прокси, по 6 карточек): общий контекст, одна вкладка 6/6, validate не вызывался ни разу общий контекст, вкладка на карточку 6/6, validate не вызывался ни разу новый контекст на карточку (= прод) 1/6, validate = [304, 403] на каждой боевой путь /fetch с reuse_context 6/6 при 0 перезапусков и 1 контексте Что правится: * снят код-дефолт domclick=1 из #3205: перезапуск процесса гарантированно уничтожает контекст, то есть лечил симптом, который сам же и создавал. Ручка per-provider и domclick как отдельный провайдер остаются; * сброс контекста в бэкфилле был на КАЖДЫЙ блок — стал один раз за прогон. Это и объясняет провал #3193: сброс выбрасывал пропуск, следующий фетч блокировался гарантированно, что снова вызывало сброс. Приёмка тогда дала ровно 1 успех из 10; * снята неверная формулировка «отказ, а не челлендж» из #3204/#3205 — 26 624 байта это РЕЗУЛЬТАТ проваленного PoW, а не статика вместо него. Ошибка вышла из метода: HTML читали на 4.5-й секунде и не смотрели в сеть. Замер 6/6, которым обосновывали #3205, был испорчен: в логах сайдкара после каждой страницы стоит «recycle threshold (1) достигнут, перезапуск браузера». Тесты: два кодировали domclick=1 — переписаны через подставной словарь, чтобы уровень «код-дефолт поставщика» продолжал проверяться, а не исчез вместе с записью. Тест сброса требует ровно одну попытку за прогон. 159 passed (сайдкар), 4972 passed / 37 skipped (backend). |
||
|
|
57ec24f364 |
chore(deps/mera): vitest 2 → 3 — заодно уходит вся dev-цепочка vite/esbuild
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m18s
Мажор ради GHSA-5xrq-8626-4rwp (CRITICAL, vitest ≤2.x). Сам CRITICAL к нам неприменим — он про `--ui`, а `@vitest/ui` не установлен и скриптов с `--ui` нет — но держать заведомо непатченный рантайм тестов ради этого рассуждения не стоит: следующий, кто добавит `--ui`, про оговорку не узнает. Побочно закрылось больше, чем планировалось. vitest тянет vite сам, и диапазон у мажора другой: 2.1.9 → vite ^5.0.0 (резолв 5.4.21 → esbuild 0.21.5), 3.2.7 → vite ^5||^6||^7 (резолв 7.3.6 → esbuild 0.28.2). Так что одним мажором: vitest 2.1.9 → 3.2.7 GHSA-5xrq-8626-4rwp vite 5.4.21 → 7.3.6 GHSA-4w7w-66w2-5vf9, GHSA-fx2h-pf6j-xcff, GHSA-v6wh-96g9-6wx3 esbuild 0.21.5 → 0.28.2 GHSA-67mh-4wv8-2f99 OSV по локу: 4 → 1. Остаток — postcss 8.4.31, вендоренный ВНУТРИ next/node_modules; нашим локом не управляется вообще. @vitejs/plugin-react 4.3.4 → 5.2.0 — вынужденно и ровно поэтому: у 4.x peer на vite ^4||^5||^6, семёрка в него не попадает. У 5.2.0 — ^4||^5||^6||^7. В шестёрку не идём: там peer уже ^8.0.0. vitest.config.ts править не пришлось: в нём нет ничего из того, что мажор переименовал или убрал (ни environmentMatchGlobs, ни deps.inline, ни workspace) — только environment/globals/setupFiles/include, которые в 3.x как были. Приёмка (локально, node 26): npm run test 66 passed, 2 failed npm run type-check ok Те же самые 2 падения (LoginPage, ветки 429/401) дают и vitest 2 на этом же локе, и vitest 2 на локе ДО апдейта зависимостей — проверено прогоном в обеих конфигурациях. Это локальный node 26 против node 20/24 в CI, к мажору отношения не имеет. Гейт — CI. |
||
| be7d7d0205 |
feat(mera/b2c): лэндинг v3 доведён до макета 29.08 — лента, игра, два пути, возражения, статьи
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 12s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m18s
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
Макет «B2C модуль для МЕРА» (Макс, 29.08) — пять секций, которых превью /mera-public/v3 не имело (его шапка их и перечисляла как отсутствующие): - DealsTickerV3 — бегущая строка «ПРОГНОЗ → ФАКТ»; данные — ТЕ ЖЕ строки, что таблица сверок (PROOF_ROWS_PLACEHOLDER): один будущий контур — один набор реквизита, второй не заводится; - GuessGameV3 — игра «Угадай цену», три раунда со слайдером, сверка «ваш ответ / МЕРА / факт», итог с медианной ошибкой игрока; раунды — GAME_ROUNDS_PLACEHOLDER под гейтом #2904; - TwoPathsV3 — «сами / сделаем за вас»; заявка пути 2 ведёт в Telegram поддержки (формы и договора «под ключ» не существует); - ObjectionsV3 — FAQ «перед оплатой» на нативных details; ответы из выверенной честной копии (content.ts/oferta/refund), макетный ответ про «отметки продавцов» заменён тем, что в продукте есть (Росреестр + снятие с публикации); - ArticlesV3 — тизер «Разборы на данных»; карточки БЕЗ ссылок до появления раздела статей (следующий шард). Решение «модалка → /estimate» (StickyCtaV3) сохранено для всех CTA макета. Гейт noindex↔плейсхолдеры дополнен новыми файлами и GAME_ROUNDS_PLACEHOLDER. Проверено: tsc чисто, next lint чисто, vitest 27 passed, живой прогон игры на dev (раунд → сверка → следующая), полностраничный скрин 1:1 с макетом. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 5b5d8eb06c |
Merge pull request 'fix(deps/mera): 6 уязвимых пакетов во фронт-локе — пересборка без правки package.json' (#3211) from fix/deps-mera-frontend-cve into main
Some checks are pending
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / perimeter-smoke (push) Blocked by required conditions
Deploy Trade-In / deploy-status (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 15s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 3m37s
|
|||
|
|
4e8cf5ab62 |
chore(ci): node 20 отслужил — рантайм фронтов и оба CI-джоба на node 24 LTS
All checks were successful
CI Trade-In / changes (pull_request) Successful in 11s
CI / changes (pull_request) Successful in 13s
CI Trade-In / browser-tests (pull_request) Successful in 1m16s
CI Trade-In / frontend-checks (pull_request) Successful in 1m30s
CI / frontend-tests (pull_request) Successful in 1m23s
CI / openapi-codegen-check (pull_request) Successful in 2m23s
CI Trade-In / backend-tests (pull_request) Successful in 5m47s
CI / backend-tests (pull_request) Successful in 18m12s
Node 20 вышел из поддержки 30.04.2026: security-патчи для него больше не выпускаются, а образ node:20-alpine продолжает собираться и молча уносить это в прод. Node 24 — текущая Active LTS. Меняется ровно major рантайма, больше ничего: frontend/Dockerfile node:20-alpine → node:24-alpine (deps/builder/runner) tradein-mvp/frontend/Dockerfile то же, три стадии .forgejo/workflows/ci.yml node-version "20" → "24" (два джоба) .forgejo/workflows/ci-tradein.yml то же (один джоб) Версия в CI намеренно держится равной major'у из Dockerfile — так было и раньше, комментарии рядом обновлены вместе с числом, чтобы не разошлись. Ни `engines`, ни `.nvmrc` в проекте нет — других мест, где закреплён major, не осталось (проверено grep'ом по Dockerfile/yml/md). Совместимость: next 15.5.24 поддерживает node 20/22/24; sharp 0.35.4 — node ^18.17 || ^20.3 || >=22, prebuild linuxmusl-x64 есть. Приёмка — этот самый CI: джобы фронтов теперь выполняются на node 24, так что зелёный прогон PR и есть доказательство. Локально проверить нечем — на машине node 26, это не тот major. |
||
|
|
25bebadca5 |
chore(deps): три места, где сборка не воспроизводится — лок-призрак, глоб и неприпинованный сайдкар
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 1m9s
CI / openapi-codegen-check (pull_request) Successful in 2m23s
CI / backend-tests (pull_request) Successful in 18m6s
Ничего не апгрейдит. Убирает три способа собрать образ не тем, что в репозитории. 1. tradein-mvp/backend/uv.lock — удалён (файл был untracked, в .gitignore с рождения). Мера — uv-workspace, сборка берёт КОРНЕВОЙ tradein-mvp/uv.lock (`context: ./tradein-mvp`, `COPY pyproject.toml uv.lock ./` + `uv sync --frozen`). Лок, созданный `uv lock` из backend/, не читает никто, и он тихо разошёлся с рабочим: на 2026-08-29 в нём pillow 12.2.0, starlette 1.0.1, python-multipart 0.0.29, pydantic-settings 2.14.1, weasyprint 68.1 — пять пакетов с открытыми advisory, которых в реальной сборке Меры нет вообще. Именно он подмешал пять фантомных строк в OSV-скан этой серии. Строка .gitignore остаётся (второй лок не нужен), но теперь с объяснением почему — иначе следующий читатель снимет ignore и закоммитит призрак. 2. backend/Dockerfile — `COPY pyproject.toml uv.lock* ./` + `if [ -f uv.lock ]; then uv sync --frozen ...; else uv sync ...; fi` → без глоба и без фолбэка. Глоб + фолбэк означали: пропал лок — сборка не падает, а молча переключается на резолв «свежайшее из диапазонов pyproject». Образ собрался бы с версиями, которых никто не видел ни в одном PR. Теперь пропажа лока роняет COPY. 3. tradein-mvp/browser/Dockerfile — `pip install "camoufox[geoip]" aiohttp` без единого пина. У сайдкара нет лока вообще, так что любая пересборка (в том числе на несвязанном коммите) тянула свежайший camoufox, а с ним другой playwright — под который НЕ написан sed-патч coreBundle.js в том же файле. Запинено по факту прод-контейнера tradein-browser: camoufox 0.5.5, playwright 1.60.0, aiohttp 3.14.3. playwright явно, хотя и транзитивный (camoufox 0.5.5 → playwright<1.61): патч завязан на конкретную сборку драйвера. Там же переписан комментарий «Апгрейд playwright невозможен — camoufox 0.4.11 pinned»: неверны обе половины. camoufox не был запинен ни на что, а 0.4.11 в проде не стоит с неизвестно каких пор — контейнер сейчас несёт 0.5.5 и playwright 1.60.0. Версии сняты с живого прод-контейнера, наличие на PyPI проверено. |
||
|
|
b52ec68aad |
fix(deps/mera): 6 уязвимых пакетов во фронт-локе — пересборка без правки package.json
All checks were successful
CI Trade-In / changes (pull_request) Successful in 14s
CI / changes (pull_request) Successful in 15s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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
`npm update --package-lock-only` в tradein-mvp/frontend: package.json не тронут,
все диапазоны прежние — обновился только резолв внутри них.
OSV по локу: 6 уязвимых версий → 4. Закрыто:
sharp 0.34.5 → 0.35.4 GHSA-f88m-g3jw-g9cj
nanoid 3.3.17 → 3.3.18 GHSA-2v37-7h3g-55p8
Заодно (без CVE, в тех же диапазонах): next/@next/* 15.5.23 → 15.5.24,
js-yaml 4.3.1 → 4.3.2, @tanstack/react-query 5.101.4 → 5.102.8,
@typescript-eslint/* 8.66.0 → 8.68.0, rollup 4.62.4 → 4.63.1,
@testing-library/react 16.3.2 → 16.3.3, ws 8.21.2 → 8.21.3.
Остаток (4) диапазонами не чинится, вынесен в отдельную задачу:
postcss 8.4.31 — вендорится ВНУТРИ next/node_modules, нашим локом не управляется;
vitest 2.1.9 → vite 5.4.21 → esbuild 0.21.5 — dev-цепочка, лечится мажором
vitest 2 → 3.2.6+. GHSA-5xrq-8626-4rwp (CRITICAL) при этом неприменим:
@vitest/ui не установлен, скриптов с --ui нет.
Приёмка (локально, node 26):
npm ci --legacy-peer-deps — 566 пакетов, ok
npm run build — ok, весь роут-набор собрался
npm run test — 66 passed, 2 failed (LoginPage 429/401)
Два падения НЕ от апдейта: те же 2 теста падают ровно так же на СТАРОМ локе
(проверено откатом лока + npm ci + прогоном того же файла). Локальный node 26
против node 20 в CI; гейт — CI.
Хойстинг в диффе выглядит как даунгрейд, но им не является: picomatch 2.3.2
переехал из micromatch/node_modules/ наверх, а 4.0.5 → 4.0.7 ушёл под
tinyglobby/ вместе с fdir 6.5.0. Реального понижения версий нет.
NB: npm 12 локально требует --allow-remote=all даже при --package-lock-only
(ничего не ставится, только резолв). В CI npm 10 — там ограничения нет.
|
||
| cec1eaaa1e |
Merge pull request 'fix(deps/site-finder): 19 уязвимых пакетов во фронт-локе — пересборка без правки package.json' (#3210) from fix/deps-sitefinder-frontend-cve into main
Some checks failed
Deploy / changes (push) Successful in 10s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-frontend (push) Successful in 5m16s
Deploy / deploy (push) Failing after 15m20s
Deploy / perimeter-smoke (push) Has been skipped
Deploy / deploy-status (push) Failing after 1s
|
|||
| 8af5e226cd |
Merge pull request 'fix(deps/site-finder): 53 advisory в backend/uv.lock — точечный апгрейд восьми пакетов' (#3207) from fix/deps-sitefinder-backend-cve into main
Some checks failed
Deploy / deploy (push) Blocked by required conditions
Deploy / perimeter-smoke (push) Blocked by required conditions
Deploy / deploy-status (push) Blocked by required conditions
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Has been cancelled
Deploy / build-worker (push) Has been cancelled
|
|||
| 4a9df83209 |
Merge pull request 'feat(glitchtip): включить встроенный MCP-сервер образа 6.1.6' (#3209) from feat/glitchtip-mcp into main
All checks were successful
Deploy Infra Host / sync-infra-host (push) Successful in 5s
Deploy / changes (push) Successful in 8s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-frontend (push) Successful in 38s
Deploy / build-worker (push) Successful in 42s
Deploy / build-backend (push) Successful in 43s
Deploy / deploy (push) Successful in 1m5s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 11s
|
|||
|
|
0cf89dd5bb |
fix(deps/site-finder): 19 уязвимых пакетов во фронт-локе — пересборка без правки package.json
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m57s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 59s
Лок не пересобирали с 3 июля (у «Меры» — 7 августа), и весь разрыв по уязвимостям
между двумя фронтендами объясняется этим. Прогон OSV: было 19 уязвимых пакет-версий,
стало 4. package.json не тронут — все фиксы влезли в существующие каретки.
Главное — Next: у 15.5.15 висело 21 advisory, 10 из них HIGH (обходы middleware/
proxy, SSRF в Server Actions и rewrites, набор DoS). Максимальный fixed_in среди них
— 15.5.21, то есть ВСЕ закрываются внутри ветки 15.5.x. Переход на 16 для
безопасности не требуется, это отдельная миграция.
next / eslint-config-next 15.5.15 -> 15.5.24
sharp 0.34.5 -> 0.35.4 унаследованные дыры libvips
postcss 8.5.10 -> 8.5.26 чтение произвольного .map по
sourceMappingURL
nanoid 3.3.11 -> 3.3.18
js-yaml 4.1.1 -> 4.3.2 квадратичный CPU на merge-key
form-data 4.0.5 -> 4.0.6 CRLF-инъекция
brace-expansion ... -> 1.1.18 три DoS
@babel/core 7.29.0 -> 7.29.7
@opentelemetry/core 2.7.1 -> 2.10.0
echarts 6.0.0 -> 6.1.0
@sentry/nextjs 10.53.1 -> 10.72.0
tailwindcss + postcss-плагин 4.2.4 -> 4.3.3
react / react-dom 19.2.5 -> 19.2.8
Дерево схлопнулось с 1010 до 749 пакетов — это следствие двухмесячной давности
лока, а не косметика, поэтому приёмка шла через полный npm ci, а не по диффу.
Остаются 4 и не чинятся здесь: postcss 8.4.31 Next вендорит ВНУТРИ своего
node_modules, а vitest 2.1.9 -> vite -> esbuild требуют мажора vitest — отдельная
задача.
Проверено локально: npm ci с нуля и npm run build проходят, сборка Next 15.5.24 +
tailwind 4.3.3 + sentry 10.72 отдаёт все маршруты. npm run test локально даёт 13
падений в 4 файлах (localStorage undefined при определённом window) — это jsdom 25
под здешним node 26; версии тестового стека в диффе НЕ менялись (jsdom 25.0.1,
vitest 2.1.9, vite 5.4.21 те же), CI гоняет node 20 и он тут гейт.
NB для тех, кто повторит локально: npm 12 по умолчанию режет remote-загрузки
(allow-remote=none) и спотыкается об опциональную @tailwindcss/oxide-wasm32-wasi.
Обходится флагом --allow-remote=all на время команды; в CI npm 10, там этого нет.
|
||
|
|
b3713144ba |
feat(glitchtip): включить встроенный MCP-сервер образа 6.1.6
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 11s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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
GLITCHTIP_ENABLE_MCP по умолчанию False (settings.py:291), поэтому https://errors.gendsgn.ru/mcp сегодня отдаёт 404. Флаг читается в asgi.py:181 (обёртка MCPDjangoDispatcher) и api/api.py:189 — нужен только web-контейнеру, worker HTTP не отдаёт. Заменяет неофициальный mcp-glitchtip (coffebar 0.1.2, 2 инструмента) на вендорский с 17, включая detect_n_plus_one. Аутентификация — статический APIToken в Authorization: Bearer, полный OAuth не нужен: фолбэк в apps/oauth/provider.py:281-291 проверен чтением образа 6.1.6 (апстрим-issue #473 описывает более раннее состояние кода). Blast radius: пересоздание только glitchtip-web, единицы секунд без приёма событий. Схема БД и миграции не затрагиваются. Откат: убрать строку и передеплоить. |
||
|
|
e059e41f5f |
fix(deps/site-finder): 53 advisory в backend/uv.lock — точечный апгрейд восьми пакетов
All checks were successful
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m9s
CI / backend-tests (pull_request) Successful in 17m38s
Прогон всех локов через OSV batch API (2026-08-29) показал: уязвимые версии есть
только в backend/uv.lock. Корневой лок «Меры» (tradein-mvp/uv.lock, из которого и
собирается её образ) чист полностью — ноль находок.
Было 8 пакетов / 53 advisory, стало 0. Проверено повторным прогоном OSV по
получившемуся локу.
pillow 12.2.0 -> 12.3.0 26 advisory, среди них heap OOB write в
Image.paste/crop и ImageFilter.RankFilter;
Image.open у нас на внешнем входе (загрузка фото)
starlette 1.0.0 -> 1.6.0 10 advisory, в т.ч. обход лимитов request.form()
cryptography 47.0.0 -> 50.0.1 7 advisory; транзитив pdfminer-six
urllib3 2.6.3 -> 2.7.0 4 advisory; обход защиты от decompression-bomb
weasyprint 68.1 -> 69.0 CSS injection via presentational hints
idna 3.13 -> 3.19 2 advisory
mako 1.3.11 -> 1.4.1 path traversal в TemplateLookup (Windows-only,
у нас Linux — берём попутно)
pydantic-settings 2.14.0 -> 2.15.0 1 advisory
Апгрейд ТОЧЕЧНЫЙ (--upgrade-package на 8 имён), не общий --upgrade: спеки в
pyproject все вида ">=" без верхней границы, и общий апгрейд затянул бы мажоры
вроде redis 7->8 и numpy заодно. Диффом подтверждено: из 138 пакетов изменились
ровно эти 8, прямые спеки в pyproject.toml не тронуты.
Проверка совместимости локально: fastapi 0.136.1 поднимается на starlette 1.6.0,
TestClient отвечает. weasyprint импортировать на Windows нельзя (нет GTK), его
гоняет CI на Linux.
NB: fastapi.testclient на starlette 1.6 предупреждает, что связка с httpx
устарела в пользу httpx2 — это ворнинг, не отказ; отдельная задача.
|
||
| c09215f779 |
Merge pull request 'fix(tradein/domclick): одна карточка на процесс браузера — перезапускать camoufox после каждой страницы (#3205)' (#3206) from fix/3205-domclick-recycle into main
All checks were successful
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Successful in 2m13s
Deploy Trade-In / deploy (push) Successful in 1m32s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy-status (push) Successful in 1s
|
|||
|
|
b9025de666 |
fix(tradein/domclick): площадка отдаёт одну карточку на процесс браузера, а мы держали один на весь прогон (#3205)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 10s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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 / browser-tests (pull_request) Successful in 1m5s
Замер на проде 2026-08-29. Три независимых запуска camoufox через прод-прокси, идём по карточкам до первого отказа — каждый раз одно и то же: карточка #1 даёт 200 и ~1 МБ с SSR-стейтом, карточка #2 даёт 401 и страницу отказа на 26 625 байт. A/B на восьми карточках: свой браузер на каждую — 4 из 4 успеха, один браузер на четыре — 1 из 4. Прямой выход с сервера и выход через прокси неразличимы (1 из 8 в обоих условиях), то есть дело не в IP. Свежего КОНТЕКСТА не хватает: в контрольном замере каждая карточка бралась через browser.new_page(), в новом изолированном контексте, — и всё равно отказ со второй. Признак живёт на уровне процесса, camoufox генерирует отпечаток при запуске, а не при создании контекста. Отсюда: reset_context (#3118) эту задачу не решает в принципе. Цена перезапуска — 0.6 с (3.5 с только первый, холодный). - PROVIDERS: добавлен "domclick" (+ host-detect). Раньше он проваливался в generic и делил браузер со счётчиком страниц с прочим трафиком — при пороге перезапуска 1 это было бы неверно. - BROWSER_RECYCLE_PAGES стал поставщик-зависимым (_resolve_recycle_pages + BROWSER_RECYCLE_PAGES_{PROVIDER}), по образцу BROWSER_BLOCK_IMAGES_{PROVIDER} из #3185. Код-дефолт domclick=1, остальным прежние 15 — у Авито и Циана узор другой и своего замера под него нет. Отдельно починены ~24 холостых охранника в тестах. Они делали monkeypatch.setattr(server, "BROWSER_RECYCLE_PAGES", 10_000), чтобы запретить перезапуск браузера; после перехода на словарь этот патч перестал на что-либо влиять, и набор оставался зелёным лишь потому, что ни один тест не делает 15 страниц подряд. Теперь патчится _RECYCLE_PAGES_BY_PROVIDER, а сама глобальная константа убрана, чтобы её не патчили снова. Проверено мутацией: при пороге 1 для всех провайдеров падают ровно три теста, которые этот дефолт и проверяют, остальные 155 удерживаются — значит охранники работают. |
||
| 2e97c81274 |
Merge pull request 'fix(tradein/domclick): 401 — тот же отказ площадки, что 403, а классифицировался как unknown (#3196)' (#3204) from fix/3196-domclick-401 into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 4m0s
Deploy Trade-In / build-backend (push) Successful in 1m3s
Deploy Trade-In / deploy (push) Successful in 1m17s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
|
|||
|
|
663f426d4c |
fix(tradein/domclick): отказ с кодом 401 классифицировался как причина неизвестной природы (#3196)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
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 / backend-tests (pull_request) Successful in 4m55s
Замер на проде 2026-08-29: страница отказа ДомКлика при HTTP 401 — РОВНО 26 624 байта, байт в байт та же, что снималась 28.08 под кодом 403. Ни PoW, ни QRATOR, ни капчи. Приходит одинаково и с валидной сохранённой сессией (16 куков из domclick_session), и полностью анонимно — значит это не «сессия отвергнута», а WAF-отказ с подменённым кодом ответа. В таблице классификатора 401 не было (403/429 → platform, 5xx → infra), поэтому все три пробы подряд дали ban_kind='unknown' — ровно то, что #3196 и должен был убрать. Механика диагноза при этом рабочая: статус доезжает от page.goto до исключения целым, шов blocked.status = status подтверждён живым 401 на проде. Правка доменная — в _ban_kind_of_block домкликового таска, а не в общей scraper_kit.browser_fetcher.ban_kind_from_status: у других поставщиков 401 обычно значит «наша сессия протухла», это наша сторона, и метка 'platform' там зря запустила бы ротацию IP (#2611). |
||
| 7cb037a919 |
Merge pull request 'chore(rules): убрать осиротевшие после PR #3198 ветки bot-pipeline' (#3203) from chore/rules-drop-bot-orphans into main
Reviewed-on: #3203 |
|||
| cdcb152d76 |
Merge pull request 'fix(tradein/scrapers): ABORT-лог называл серию блоков, хотя рвал прогон по доле' (#3201) from fix/3184-abort-log-names-wrong-criterion into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 14s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Successful in 43s
Deploy Trade-In / test (push) Successful in 4m10s
Deploy Trade-In / build-backend (push) Successful in 1m35s
Deploy Trade-In / deploy (push) Successful in 2m32s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
Reviewed-on: #3201 |
|||
|
|
555bbf546c |
chore(rules): убрать осиротевшие после PR #3198 ветки bot-pipeline
All checks were successful
CI Trade-In / changes (pull_request) Successful in 13s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 18s
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
Правила ссылались на механику удалённых ботов. Главное — не косметика: секция "Polling loop / Foreground fallback" безусловно предписывала парсить маркер <!-- gendesign-review-bot: ... -->, который писал auto-code-reviewer. Агента нет, маркера нет — соло-сессия опрашивала PR до Cap 30 iter × 60s в ожидании вердикта, которого не будет, и через полчаса пинговала человека. git-pr.md: - Polling loop: шаг 3 вместо маркера бота теперь merge по зелёному CI, добавлены ветки "checks красные" и "человеческий review с правками" - Refs #N -> Closes #N: обходной путь был нужен только потому, что issue закрывал qa-бот на status/done. Бота нет, иначе issue не закроется никогда - Auto-merge policy: убрано упоминание reviewer-окна и approve+SHA gate delegation.md: - снята ветка "bot-pipeline: label status/needs-analysis, снять claim" Что НЕ менялось: сам self-extending guard, пороги эвристик, Cap 30 iter. |
||
| 79e469de1c |
Merge pull request 'fix(tradein/scrapers): диагноз блока из HTTP-статуса, а не из маркеров чужой площадки (#3196)' (#3202) from fix/3196-ban-kind-http-status into main
Some checks failed
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / perimeter-smoke (push) Blocked by required conditions
Deploy Trade-In / deploy-status (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / test (push) Has been cancelled
Deploy Trade-In / build-browser (push) Has been cancelled
Reviewed-on: #3202 |
|||
|
|
bf3214b9e4 |
fix(tradein/scrapers): диагноз блока брался из текстовых маркеров чужой площадки, а не из HTTP-статуса (#3196)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
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 / browser-tests (pull_request) Successful in 1m7s
CI Trade-In / backend-tests (pull_request) Successful in 4m57s
Сайдкар вообще не читал код ответа page.goto: страница классифицировалась только по маркерам, снятым с Авито. Домклик отдаёт статическую `403 | Домклик` на 26 624 байта, где нет ни одного такого маркера (замер прода 28.08.2026) — она уезжала наверх как валидный HTML, парсер не находил состояние, и прогон получал блок неизвестной природы. За 14 дней все 14 прогонов домклика легли с ban_kind='unknown'; у Яндекса счётчика blocked не было вовсе, поэтому ветка перевода прогона в 'banned' была недостижима по построению — ноль банов. - browser/server.py: статус целевой навигации сохраняется per-provider и доезжает в тело /fetch аддитивным ключом "status" (ключ "html" не тронут); 403/429 с маркерами челленджа больше не ждут PoW — ждать нечего, статическая страница сама себя не перезагрузит. Наверх идёт BanPageDetectedError, а не заглушка: вернув её контентом, воскресили бы #3045. - scraper_kit/browser_fetcher.py: BrowserFetcher.last_response_status + ban_kind_from_status (403/429 → platform, 5xx → infra, прочее → None). Поток управления не менялся: fetch() по-прежнему отдаёт str. - domclick: DomClickBlockedError несёт .status — один тип исключения на маркер-детект и на сбой фетча разводится без размножения типов; прогон передаёт перепись диагнозов в mark_backfill_finished. - yandex: появился счётчик blocked, оживляющий ветку бана. Серии блоков и промахов парсера считаются РАЗДЕЛЬНО: иначе четыре промаха плюс один 403 пятым давали 'banned' с переписью {platform: 1}. - cian: ban_kinds наполняется только диагностируемым статусом. HTTP 200 с пустым разбором — дрейф разметки на нашей стороне, а не отказ площадки; записав его блоком, мы бы штамповали фиктивные баны у здорового источника (13 done против 1 banned за 14 дней). Инвариант: непустой ban_kinds ⟺ виден ответ 403/429/5xx. Значения остаются в пределах CHECK scrape_runs.ban_kind. Известный пробел: шов providers/domclick/detail.py `blocked.status = status` тестами не покрыт — существующие домкликовые тесты подают исключение готовым моком и боевой fetch_detail не исполняют. |
||
|
|
8176e8d167 |
fix(tradein/scrapers): ABORT-лог называл серию блоков, хотя рвал прогон по доле
All checks were successful
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 7s
CI Trade-In / browser-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 / backend-tests (pull_request) Successful in 4m49s
Прод-прогон 5210 оборвался по ratio-критерию — 14 блоков из 20, ровно порог 0.7 — и отчитался строкой «ABORT -- 1 consecutive blocks». Число верное: последняя серия в тот момент действительно равнялась единице (19-я попытка успех, 20-я блок). Величина не та. Читатель лога видит цифру, по которой обрыва быть не могло, и идёт искать несуществующий баг в брейкере. Причина: #3184 заменил критерий обрыва на долю в скользящем окне, а текст лога остался от прежнего критерия «N подряд» — то есть ровно та же болезнь, которую #3178 лечил у соседней строки (литерал «IP rate-limited» вместо измеренной причины). - BlockRatioBreaker.abort_reason() возвращает "ratio" / "safety_net" / None; should_abort() выражен через него, поведение не меняется. - abort_explanation() даёт текст с той величиной, по которой обрыв и произошёл: доля печатает «доля блоков 14/20 в окне (порог 70%)», safety-net — «5 блоков подряд без единого успеха (снапшот 5 короче окна 20)». - counters["abort_reason"] — чтобы причина обрыва читалась SQL-запросом по scrape_runs, а не грепом контейнера. Ключа нет, если прогон не обрывался. Тесты (проверено мутацией источника — на прежнем сообщении оба падают): - ratio-обрыв на раскладке прогона 5210 (серия на обрыве = 1) требует «14/20» в логе и отсутствия слова consecutive; - safety-net требует «5 блоков подряд» и отсутствия «доля блоков» — без этого зеркала первый тест проходил бы и у сообщения, всегда печатающего долю; - прогон без обрыва (13/20) не пишет abort_reason в counters. Refs #3184, #3178 |
||
| ede1243ce6 |
fix(tradein/browser): в репозитории лежало опровергнутое обоснование хранилища сессий Яндекса (#3200)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m53s
Deploy Trade-In / build-backend (push) Successful in 1m1s
Deploy Trade-In / deploy (push) Successful in 1m34s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
|
|||
|
|
c995af73c2 |
docs(tradein/scrapers): в репозитории лежало опровергнутое обоснование хранилища сессий Яндекса
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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 / backend-tests (pull_request) Successful in 4m44s
#3195 замержен с утверждением, что авторизованная сессия раскрывает контакты продавца. Утверждение неверно, а лежит оно в двух местах, которые читают в первую очередь: докстринг app/services/yandex_session.py и шапка миграции 274. Повторный замер (#3192, 2026-08-28) сделан на ПРОД-транспорте — curl_cffi + прокси из пула, тот же путь, что у yandex_detail_backfill, — а не на сайдкаре, как первый: - offerCard.card.author у целевой карточки не несёт phones/phoneNumbers ни в одном из 12 случайных объявлений (6 AGENCY, 6 DEVELOPER), одинаково с куками и без; только encryptedPhones (1 токен) и redirectPhones; - phoneNumbers во всём INITIAL_STATE встречается только под offerCard.visitedOffers[*].author — истории просмотров НАШЕЙ учётки; анонимно список пуст, с куками в нём 9-10 записей; - первый замер («0 → 3,4,5,6») считал рост именно этой истории: +1 на каждый фетч; - authorStats.phones (коммутатор застройщика) отдаётся анонимно — тот же номер в обеих ветках. Правка только текстовая: ни схема, ни поведение не меняются. Шапку применённой миграции правлю сознательно — файл повторно не выполняется (учёт по имени в _schema_migrations), а неверное описание пережило бы любой следующий разбор. Таблицу не трогаю: она пуста, но DROP без явного решения владельца делать нельзя. Судьба #3195 — на владельце, #3192 помечен needs-human. Refs #3192, #3195 |
||
| fcc6c6576a |
fix(tradein/browser): дефолт block_images для avito вернулся к True (#3199)
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Successful in 2m9s
Deploy Trade-In / deploy (push) Successful in 1m48s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
Deploy Trade-In / build-backend (push) Has been skipped
|
|||
| 9edf8b07d0 |
Merge pull request 'chore(claude): retire autonomous bot-pipeline' (#3198) from chore/retire-bot-pipeline into main
Reviewed-on: #3198 |
|||
|
|
b37acfe00d |
fix(tradein/browser): дефолт block_images для avito вернулся к True — гипотеза не подтвердилась
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 1m4s
#3185 выключил блокировку картинок для avito по гипотезе, что она сама по себе сигналит QRATOR'у. Гипотеза шла от camoufox'ского LeakWarning, а не от замера. Что показали замеры после выкатки: - прямой A/B на сайдкаре — 6/8 успехов с блокировкой против 7/8 без, разница в пределах шума; - прод стал хуже: прогон 5200 (картинки блокировались) — 43/63 карточки при 32% блоков; прогоны 5206 и 5207 (не блокировались) — 2/22 и 2/13 при 91% и 77%. Причинность НЕ доказана: между прогонами через тот же пул прокси прошло ~40 моих диагностических запросов, репутация пула могла просесть от них. Но выгоды правка не показала ни разу, поэтому дефолт возвращается к прежнему поведению. Ручка из #3185 остаётся целиком: BROWSER_BLOCK_IMAGES и BROWSER_BLOCK_IMAGES_{PROVIDER} работают как работали, меняется только код-дефолт (_BLOCK_IMAGES_DEFAULT_BY_PROVIDER теперь пуст). Эффект картинок надо мерить отдельно и на чистом пуле. Тест per-provider-override развёрнут в направление, которое ОТЛИЧАЕТСЯ от дефолта (env=false снимает блокировку): со всеми дефолтами True прежний тест с env=true проходил бы и у функции, всегда возвращающей True. Refs #3185 |
||
|
|
4b019ebd67 |
chore(claude): retire autonomous bot-pipeline
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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
Ролевые окна (claude --strict-mcp-config --mcp-config .claude/mcp/<role>.json)
не используются — отказ по стоимости: слишком много токенов на простых задачах.
Удалено (25 файлов):
- scripts/: start-bot, start-{analyst,backend,frontend,qa,reviewer}, setup-bot-env
- .claude/mcp/: 5 per-role MCP-конфигов
- .claude/commands/: 6 work-as-*
- .claude/agents/: 6 auto-* + _autonomous_pickup
Ссылки в выживших файлах поправлены: CLAUDE.md, README.md, git-pr.md,
deep-review-phases/phase-5-verdict.md, deep-code-reviewer.md,
cleanup-stale-claims.sh. Self-extending guard сохранён — из него убраны
только имена удалённых файлов, сам запрет на self-merge правил пайплайна цел.
Универсальные воркеры не тронуты: backend-engineer, frontend-engineer,
database-expert, devops-engineer, tech-analyst, code-reviewer, qa-tester,
deep-code-reviewer.
|
||
| 0ac443d0ba | Merge pull request 'fix(tradein/domclick): каждый запрос получал чистый браузерный контекст, куки реплеились протухшими (#3190)' (#3193) from fix/3118-domclick-warm-context into main | |||
| 5be64c6688 |
fix(tradein/scrapers): хранилище авторизованной сессии Яндекс.Недвижимости (#3195)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Successful in 2m18s
Deploy Trade-In / test (push) Successful in 4m4s
Deploy Trade-In / build-backend (push) Successful in 1m36s
Deploy Trade-In / deploy (push) Successful in 2m0s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
|
|||
|
|
e2863f6be9 |
fix(tradein/domclick): каждый запрос получал чистый браузерный контекст, куки реплеились протухшими
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
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 / browser-tests (pull_request) Successful in 1m7s
CI Trade-In / backend-tests (pull_request) Successful in 4m49s
Сайдкар на каждый /fetch делал browser.new_page() поверх AsyncCamoufox — это новый изолированный контекст, cookie-jar умирал сразу после ответа. Туда вливался замороженный снимок кук из domclick_session_cookies, где qrator_jsid2 живёт ~2.5 часа, а хранится 30 дней. Первый запрос проходил с ещё живым токеном, все следующие показывали QRATOR один и тот же протухший — он отдавал челлендж-страницу без __SSR_STATE__. Отсюда двухнедельное attempted=4, enriched=1, blocked=3. Замер на проде 28.08: через сайдкар 26 запросов подряд — 100% блоков, включая свежеротированный exit-IP; те же карточки в тёплом контексте — 5 из 5 успешно, ~2 сек каждая. Сайдкар получил переиспользуемый per-provider контекст: куки вливаются один раз при создании, дальше jar живёт сам; страница закрывается после ответа, контекст остаётся. Закрытие контекста подшито к _close_browser, так что relaunch и shutdown его не теряют. Флаг opt-in: при reuse_context=False payload /fetch не получает новых ключей вовсе, поведение остальных поставщиков не меняется. Сброс сожжённого контекста — ровно один на обнаруженный блок, через отложенный флаг BrowserFetcher.request_context_reset(): fetch_detail() в kit не прокидывает reset_context, и менять этот промежуточный слой ради одного поставщика не хотелось. NB для деплоя: правка работает только если tradein-browser пересобран вместе с бэкендом. Старый сайдкар новые поля молча проигнорирует — не упадёт, но и не починит. Refs #3190, #3118 |
||
| 49b70a67f3 |
fix(tradein/scrapers): обрыв по серии блоков рвал каждый прогон, включая здоровые (#3188)
All checks were successful
Deploy Trade-In / changes (push) Successful in 13s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 4m2s
Deploy Trade-In / build-backend (push) Successful in 1m10s
Deploy Trade-In / deploy (push) Successful in 1m37s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
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
|