Каталог DOM.РФ в beat: вместо обещания «вернуть после cooldown» — факт о блокировке StormWall и тест, который не даст включить молча #3566

Merged
bot-backend merged 3 commits from fix/ptica-domrf-waf-probe into main 2026-09-17 09:15:51 +00:00
Collaborator

#2443 — каталог DOM.РФ выключен из-за блокировки, а не «до cooldown»

Что было

У двух закомментированных beat-записей, scrape-kn-catalog-objects-weekly и scrape-kn-catalog-flats-weekly, стоял комментарий «Возврат после cooldown 24-48h (проверить через targeted test)». Он же и сейчас лежит в живом контейнере: docker exec gendesign-beat-1 grep -n cooldown /app/app/workers/beat_schedule.py на 17.09 выдаёт строки 353 и 369.

То же обещание таймера оператор видел в отказе ручных эндпоинтов каталога (POST /api/v1/admin/scrape/kn-catalog-objects и /kn-catalog-flats): HTTP 400 советовал передать i_understand_waf_risk=true, «если WAF cooldown прошёл». Проверено на проде 17.09, только чтение: в gendesign-backend-1 у _WAF_COOLDOWN_GUARD_MSG нет упоминания #3307, а слово cooldown есть.

Почему это неправда

Точечный тест, о котором просила задача, провели трижды: 20.08, 27.08 и 01.09 (в комментариях здесь и в #3307).

  • Кулдауна не было. kn-прогоны 29–33 (03.06–28.06) прошли успешно уже после «бана» 24.05.
  • С 01.09 наш.дом.рф стоит за StormWall (куки spid/spjs/spsc), и IP Poincare получает «Доступ заблокирован [403]». Это блокировка: ожидание, перезагрузка и чистый профиль её не снимают.
  • Прод, 17.09, только чтение: у job_settings.scrape_kn стоит enabled=f, в description записана честная причина «RE-DISABLED 2026-09-01 ПО ФАКТУ ЗОНДОВ… StormWall…».

У записей каталога флага в job_settings нет: они просто закомментированы в коде. Поэтому решение по ним жило только в комментарии с обещанием таймера — ровно то, против чего задача и была заведена.

Что сделано

  • backend/app/workers/beat_schedule.py: оба комментария теперь называют факт (зонды, StormWall, 403) и условие включения: прокси плюс kn-прогон, принятый по числу строк (#3307). Больше никакого «по таймеру».
  • backend/tests/workers/test_beat_schedule_domrf_catalog.py: тест собирает beat-расписание и проверяет по значению, что ни одна из двух задач (tasks.scrape_kn_catalog_objects…, tasks.scrape_kn_catalog_flats…) в него не попала. Сверка идёт по task, а не по ключу, так что переименованный ключ проверку не обойдёт. Контроль в тесте убеждается, что статическая часть расписания действительно построилась, иначе пустое расписание давало бы зелёный результат само по себе. Когда кто-то включит запись, тест упадёт с текстом, который отправляет в #3307.
  • (по ревью) backend/app/api/v1/admin_scrape.py: текст отказа guard'а переписан и константа переименована в _DOMRF_BLOCK_GUARD_MSG. Теперь отказ говорит, что наш.дом.рф за StormWall отдаёт «Доступ заблокирован [403]», что ожидание блокировку не снимает и что флаг ставится только при сборе через прокси и принятом kn-прогоне (#3307). Докстринги обоих эндпоинтов тоже больше не называют guard «WAF cooldown». Из докстринга objects-эндпоинта убрано «Beat schedule: Tuesday 04:00 UTC»: запись выключена, а расписание было в МСК.
  • (по ревью) Докстринги задач: scrape_kn_catalog_flats.py («WAF-cooldown на VPS IP; включается вручную после проверки targeted-тестом», «Beat отключён (WAF cooldown)») и scrape_kn_catalog_objects.py («Beat schedule: вторник 04:00 UTC») говорят то же, что beat-комментарий.
  • frontend/src/lib/api-types.ts перегенерирован так же, как это делает CI-гейт openapi-codegen-check (дамп app.openapi()openapi-typescript → локальный prettier). Разница только в двух докстрингах эндпоинтов.
  • backend/tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py: оба теста отказа проверяют, что detail ответа 400 называет #3307 и не содержит cooldown. Оператор решает по этому тексту, поэтому текст здесь и есть проверяемое значение.

Поведение guard'а не менялось: без i_understand_waf_risk=true ответ по-прежнему 400, задача не ставится. Запросов к наш.дом.рф не делал ни с прода, ни локально.

Что НЕ сделано (поэтому без Closes)

  1. description scrape_kn всё ещё начинается с «Скрейпинг КН (ЦИАН)» (сид data/sql/81_job_settings.sql:89, на проде то же). Для правки нужна миграция в data/sql/, а номер миграции на эту работу не выдавали. Оставлено отдельным шагом.
  2. В приёмке #3307 нет пункта «включить обе записи каталога (#2442) после зелёного kn-прогона; catalog_scraped_at свежее 2026-05-19». Чужие issue я не правил. Этот PR ссылается на #3307, а тест сам указывает на него при включении, но пункт в приёмку стоит добавить.
  3. Историческое описание инцидента «WAF hard-ban 2026-05-24 (#2443)» осталось в комментариях config.py, stealth.py, domrf_catalog*.py, pravo_gov66_client.py, okn_egrkn_client.py и в описании поля i_understand_waf_risk. Таймера и совета подождать там нет, это рассказ о майском эпизоде, поэтому не трогал.
  4. Vault: исход уже записан. fixes/Fix_Night_Checkpoints_Wrong_Instruments_Aug28.md («история опровергает посылку #2443…») и audits/Project_Status_Revision_0901.md (StormWall, #3307, #2443 ждёт решения по прокси). Проверено 17.09.

Правки по ревью

Каждую находку сначала проверил сам.

  1. Блокирующая: критерий приёмки «grep -n cooldown находит только строку 67» не выполнился бы никогда. Верно. В ветке grep -n cooldown backend/app/workers/beat_schedule.py выдаёт 67 и 349: новый комментарий сам цитирует старую посылку «hard-ban, cooldown 24-48h». Раздел «Приёмка на проде» переписан. Главный маркер теперь grep -c StormWall (на проде 17.09 даёт 0, в ветке 2). Второй маркер grep -c "Возврат после" (на проде 2, в ветке 0): он есть только в старой версии и пропадает в новой. Ожидание по cooldown исправлено на 67 и 349. Код это не задевало.
  2. admin_scrape.py:1913-1924, :1963, :2025: текст HTTP 400 предлагал поставить флаг, «если WAF cooldown прошёл». Верно, исправлено (см. «Что сделано»).
  3. scrape_kn_catalog_flats.py:27-28, :119 и scrape_kn_catalog_objects.py:12: та же посылка и «вторник 04:00 UTC» у выключенной записи с расписанием в МСК. Верно, исправлено. Та же фраза про UTC была в докстринге objects-эндпоинта (admin_scrape.py, «Beat schedule: Tuesday 04:00 UTC»). Её в ревью не было, исправил заодно.
  4. Неточность в deploy-заметке: таблицы scrape_runs в gendesign нет. Верно. Прод 17.09, только чтение: to_regclass('public.scrape_runs') пусто, v_scrape_runs_unified и kn_scrape_runs есть. Заметка ниже поправлена.
  5. Про отсутствие Closes ревьюер согласен. Опровергать нечего.

Тесты

  • cd backend && uv run python -m pytest tests/workers/test_beat_schedule_domrf_catalog.py tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py -q: 6 passed, rc=0.
  • Весь сьют ПТИЦА backend, uv run python -m pytest tests/ -q -p no:cacheprovider: 5033 passed, 84 skipped, 4 failed, rc=1. Все 4 падения относятся к tests/ops/test_2203_backup_trailer_grep_dashdash.py. Это известная проблема BSD mktemp на macOS, к этой правке она отношения не имеет. Сьют гонялся до мержа origin/main. Мерж принёс только tradein-mvp/backend/data/sql/308_…sql (#3567), backend ПТИЦА он не трогает. После мержа два целевых файла снова дали 6 passed, rc=0, ruff check rc=0, а маркеры приёмки на дереве ветки совпали с ожидаемыми (StormWall 2, «Возврат после» 0, cooldown 67 и 349, guard True True False).
  • uv run ruff check app tests: All checks passed, rc=0. ruff format --check по 4 изменённым py-файлам: already formatted, rc=0.
  • Гейт codegen локально: после перегенерации api-types.ts меняются только два докстринга (18 строк). Значит, до правки файл совпадал со схемой, а теперь закоммичен в перегенерированном виде.

Фальсификация

Beat (первый коммит). Вернул в beat_schedule.py запись для квартир каталога под переименованным ключом kn-flats-renamed (исходник предварительно скопирован в scratchpad). Прогон покраснел:

E       AssertionError: каталог DOM.РФ включён в beat: {'kn-flats-renamed': 'tasks.scrape_kn_catalog_flats.scrape_kn_catalog_flats'}. IP Poincare заблокирован StormWall (#2443); включать только после прокси и принятого kn-прогона (#3307)
1 failed, 7 warnings in 1.17s
rc=1

После этого исходник восстановил, diff -q расхождений не нашёл, тест снова зелёный.

Guard (коммит по ревью). Исправленный admin_scrape.py скопировал в scratchpad и дважды его ломал.

Мутация A: хвост отказа вернул к старому совету «…передай i_understand_waf_risk=true, если WAF cooldown прошёл (targeted smoke-test)». Результат:

E       assert '3307' in "Ad-hoc catalog-scrape заблокирован guard'ом: наш.дом.рф за StormWall … Передавай i_understand_waf_risk=true, если WAF cooldown прошёл (targeted smoke-test)."
FAILED tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py::test_kn_catalog_objects_refuses_without_override
FAILED tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py::test_kn_catalog_flats_refuses_without_override
2 failed, 3 passed, 8 warnings in 3.17s
rc=1

Мутация B проверяла, что вторая проверка живая сама по себе: #3307 оставил, добавил «…(#3307) или WAF cooldown прошёл.». Результат:

E       AssertionError: assert 'cooldown' not in 'ad-hoc cata...down прошёл.'
E           ) или waf cooldown прошёл.
2 failed, 3 passed, 8 warnings in 4.37s
rc=1

После каждой мутации исходник восстановлен, diff -q с копией пустой (rc=0), тесты снова зелёные.

Этот же тестовый файл на исходном тексте из main (до правки admin_scrape.py) даёт 2 failed, 3 passed, rc=1.

Приёмка на проде (после деплоя, не раньше 17.09.2026)

Значения «сейчас» сняты 17.09.2026 с poincare, только чтение.

  • Главный маркер: ssh poincare "docker exec gendesign-beat-1 grep -c StormWall /app/app/workers/beat_schedule.py" должна дать 2. Сейчас 0.
  • docker exec gendesign-beat-1 grep -c "Возврат после" /app/app/workers/beat_schedule.py должна дать 0. Сейчас 2.
  • docker exec gendesign-beat-1 grep -n cooldown /app/app/workers/beat_schedule.py должна найти 67 и 349. 67 — историческая строка про инцидент env-fallback, 349 — новый комментарий, который цитирует опровергнутую посылку. Сейчас 67, 353, 369. Если main до мержа поменяет начало файла, номера сдвинутся, поэтому решают счётчики выше.
  • Guard, проверка по значению без запросов к эндпоинту: docker exec gendesign-backend-1 python -c "import app.api.v1.admin_scrape as a; m=getattr(a,'_DOMRF_BLOCK_GUARD_MSG',None) or a._WAF_COOLDOWN_GUARD_MSG; print(hasattr(a,'_DOMRF_BLOCK_GUARD_MSG'), '3307' in m, 'cooldown' in m.lower())" должна напечатать True True False. Сейчас печатает False False True.
  • В beat по-прежнему нет задач каталога. Проверка: в логе beat после рестарта нет scrape_kn_catalog.

Деплой

Деплой пересоздаёт backend, worker и beat. В коде меняются только комментарии, докстринги и текст отказа guard'а. Frontend тоже пересоберётся, потому что изменился frontend/src/lib/api-types.ts, но там поменялись только комментарии. Миграций нет.

Пересоздание worker прерывает работающие Celery-задачи. Перед деплоем проверить: SELECT count(*) FROM v_scrape_runs_unified WHERE status='running' (таблицы scrape_runs в gendesign нет; kn-прогоны лежат в kn_scrape_runs). 17.09 в v_scrape_runs_unified строк со статусом running не было.

Refs #2443, #3307, #2442

🤖 Generated with Claude Code

## #2443 — каталог DOM.РФ выключен из-за блокировки, а не «до cooldown» ### Что было У двух закомментированных beat-записей, `scrape-kn-catalog-objects-weekly` и `scrape-kn-catalog-flats-weekly`, стоял комментарий «Возврат после cooldown 24-48h (проверить через targeted test)». Он же и сейчас лежит в живом контейнере: `docker exec gendesign-beat-1 grep -n cooldown /app/app/workers/beat_schedule.py` на 17.09 выдаёт строки 353 и 369. То же обещание таймера оператор видел в отказе ручных эндпоинтов каталога (`POST /api/v1/admin/scrape/kn-catalog-objects` и `/kn-catalog-flats`): HTTP 400 советовал передать `i_understand_waf_risk=true`, «если WAF cooldown прошёл». Проверено на проде 17.09, только чтение: в `gendesign-backend-1` у `_WAF_COOLDOWN_GUARD_MSG` нет упоминания #3307, а слово cooldown есть. ### Почему это неправда Точечный тест, о котором просила задача, провели трижды: 20.08, 27.08 и 01.09 (в комментариях здесь и в #3307). - Кулдауна не было. kn-прогоны 29–33 (03.06–28.06) прошли успешно уже после «бана» 24.05. - С 01.09 наш.дом.рф стоит за StormWall (куки spid/spjs/spsc), и IP Poincare получает «Доступ заблокирован [403]». Это блокировка: ожидание, перезагрузка и чистый профиль её не снимают. - Прод, 17.09, только чтение: у `job_settings.scrape_kn` стоит `enabled=f`, в description записана честная причина «RE-DISABLED 2026-09-01 ПО ФАКТУ ЗОНДОВ… StormWall…». У записей каталога флага в job_settings нет: они просто закомментированы в коде. Поэтому решение по ним жило только в комментарии с обещанием таймера — ровно то, против чего задача и была заведена. ### Что сделано - `backend/app/workers/beat_schedule.py`: оба комментария теперь называют факт (зонды, StormWall, 403) и условие включения: прокси плюс kn-прогон, принятый по числу строк (#3307). Больше никакого «по таймеру». - `backend/tests/workers/test_beat_schedule_domrf_catalog.py`: тест собирает beat-расписание и проверяет по значению, что ни одна из двух задач (`tasks.scrape_kn_catalog_objects…`, `tasks.scrape_kn_catalog_flats…`) в него не попала. Сверка идёт по `task`, а не по ключу, так что переименованный ключ проверку не обойдёт. Контроль в тесте убеждается, что статическая часть расписания действительно построилась, иначе пустое расписание давало бы зелёный результат само по себе. Когда кто-то включит запись, тест упадёт с текстом, который отправляет в #3307. - (по ревью) `backend/app/api/v1/admin_scrape.py`: текст отказа guard'а переписан и константа переименована в `_DOMRF_BLOCK_GUARD_MSG`. Теперь отказ говорит, что наш.дом.рф за StormWall отдаёт «Доступ заблокирован [403]», что ожидание блокировку не снимает и что флаг ставится только при сборе через прокси и принятом kn-прогоне (#3307). Докстринги обоих эндпоинтов тоже больше не называют guard «WAF cooldown». Из докстринга objects-эндпоинта убрано «Beat schedule: Tuesday 04:00 UTC»: запись выключена, а расписание было в МСК. - (по ревью) Докстринги задач: `scrape_kn_catalog_flats.py` («WAF-cooldown на VPS IP; включается вручную после проверки targeted-тестом», «Beat отключён (WAF cooldown)») и `scrape_kn_catalog_objects.py` («Beat schedule: вторник 04:00 UTC») говорят то же, что beat-комментарий. - `frontend/src/lib/api-types.ts` перегенерирован так же, как это делает CI-гейт `openapi-codegen-check` (дамп `app.openapi()` → `openapi-typescript` → локальный prettier). Разница только в двух докстрингах эндпоинтов. - `backend/tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py`: оба теста отказа проверяют, что `detail` ответа 400 называет #3307 и не содержит cooldown. Оператор решает по этому тексту, поэтому текст здесь и есть проверяемое значение. Поведение guard'а не менялось: без `i_understand_waf_risk=true` ответ по-прежнему 400, задача не ставится. Запросов к наш.дом.рф не делал ни с прода, ни локально. ### Что НЕ сделано (поэтому без Closes) 1. **description `scrape_kn` всё ещё начинается с «Скрейпинг КН (ЦИАН)»** (сид `data/sql/81_job_settings.sql:89`, на проде то же). Для правки нужна миграция в `data/sql/`, а номер миграции на эту работу не выдавали. Оставлено отдельным шагом. 2. **В приёмке #3307 нет пункта «включить обе записи каталога (#2442) после зелёного kn-прогона; catalog_scraped_at свежее 2026-05-19».** Чужие issue я не правил. Этот PR ссылается на #3307, а тест сам указывает на него при включении, но пункт в приёмку стоит добавить. 3. Историческое описание инцидента «WAF hard-ban 2026-05-24 (#2443)» осталось в комментариях `config.py`, `stealth.py`, `domrf_catalog*.py`, `pravo_gov66_client.py`, `okn_egrkn_client.py` и в описании поля `i_understand_waf_risk`. Таймера и совета подождать там нет, это рассказ о майском эпизоде, поэтому не трогал. 4. Vault: исход уже записан. `fixes/Fix_Night_Checkpoints_Wrong_Instruments_Aug28.md` («история опровергает посылку #2443…») и `audits/Project_Status_Revision_0901.md` (StormWall, #3307, #2443 ждёт решения по прокси). Проверено 17.09. ### Правки по ревью Каждую находку сначала проверил сам. 1. **Блокирующая: критерий приёмки «grep -n cooldown находит только строку 67» не выполнился бы никогда.** Верно. В ветке `grep -n cooldown backend/app/workers/beat_schedule.py` выдаёт 67 и 349: новый комментарий сам цитирует старую посылку «hard-ban, cooldown 24-48h». Раздел «Приёмка на проде» переписан. Главный маркер теперь `grep -c StormWall` (на проде 17.09 даёт 0, в ветке 2). Второй маркер `grep -c "Возврат после"` (на проде 2, в ветке 0): он есть только в старой версии и пропадает в новой. Ожидание по cooldown исправлено на 67 и 349. Код это не задевало. 2. **admin_scrape.py:1913-1924, :1963, :2025: текст HTTP 400 предлагал поставить флаг, «если WAF cooldown прошёл».** Верно, исправлено (см. «Что сделано»). 3. **scrape_kn_catalog_flats.py:27-28, :119 и scrape_kn_catalog_objects.py:12: та же посылка и «вторник 04:00 UTC» у выключенной записи с расписанием в МСК.** Верно, исправлено. Та же фраза про UTC была в докстринге objects-эндпоинта (`admin_scrape.py`, «Beat schedule: Tuesday 04:00 UTC»). Её в ревью не было, исправил заодно. 4. **Неточность в deploy-заметке: таблицы `scrape_runs` в gendesign нет.** Верно. Прод 17.09, только чтение: `to_regclass('public.scrape_runs')` пусто, `v_scrape_runs_unified` и `kn_scrape_runs` есть. Заметка ниже поправлена. 5. Про отсутствие Closes ревьюер согласен. Опровергать нечего. ### Тесты - `cd backend && uv run python -m pytest tests/workers/test_beat_schedule_domrf_catalog.py tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py -q`: 6 passed, rc=0. - Весь сьют ПТИЦА backend, `uv run python -m pytest tests/ -q -p no:cacheprovider`: 5033 passed, 84 skipped, 4 failed, rc=1. Все 4 падения относятся к `tests/ops/test_2203_backup_trailer_grep_dashdash.py`. Это известная проблема BSD mktemp на macOS, к этой правке она отношения не имеет. Сьют гонялся до мержа origin/main. Мерж принёс только `tradein-mvp/backend/data/sql/308_…sql` (#3567), backend ПТИЦА он не трогает. После мержа два целевых файла снова дали 6 passed, rc=0, `ruff check` rc=0, а маркеры приёмки на дереве ветки совпали с ожидаемыми (StormWall 2, «Возврат после» 0, cooldown 67 и 349, guard `True True False`). - `uv run ruff check app tests`: All checks passed, rc=0. `ruff format --check` по 4 изменённым py-файлам: already formatted, rc=0. - Гейт codegen локально: после перегенерации `api-types.ts` меняются только два докстринга (18 строк). Значит, до правки файл совпадал со схемой, а теперь закоммичен в перегенерированном виде. ### Фальсификация **Beat (первый коммит).** Вернул в `beat_schedule.py` запись для квартир каталога под переименованным ключом `kn-flats-renamed` (исходник предварительно скопирован в scratchpad). Прогон покраснел: ``` E AssertionError: каталог DOM.РФ включён в beat: {'kn-flats-renamed': 'tasks.scrape_kn_catalog_flats.scrape_kn_catalog_flats'}. IP Poincare заблокирован StormWall (#2443); включать только после прокси и принятого kn-прогона (#3307) 1 failed, 7 warnings in 1.17s rc=1 ``` После этого исходник восстановил, `diff -q` расхождений не нашёл, тест снова зелёный. **Guard (коммит по ревью).** Исправленный `admin_scrape.py` скопировал в scratchpad и дважды его ломал. Мутация A: хвост отказа вернул к старому совету «…передай i_understand_waf_risk=true, если WAF cooldown прошёл (targeted smoke-test)». Результат: ``` E assert '3307' in "Ad-hoc catalog-scrape заблокирован guard'ом: наш.дом.рф за StormWall … Передавай i_understand_waf_risk=true, если WAF cooldown прошёл (targeted smoke-test)." FAILED tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py::test_kn_catalog_objects_refuses_without_override FAILED tests/api/v1/test_admin_scrape_kn_catalog_waf_guard.py::test_kn_catalog_flats_refuses_without_override 2 failed, 3 passed, 8 warnings in 3.17s rc=1 ``` Мутация B проверяла, что вторая проверка живая сама по себе: #3307 оставил, добавил «…(#3307) или WAF cooldown прошёл.». Результат: ``` E AssertionError: assert 'cooldown' not in 'ad-hoc cata...down прошёл.' E ) или waf cooldown прошёл. 2 failed, 3 passed, 8 warnings in 4.37s rc=1 ``` После каждой мутации исходник восстановлен, `diff -q` с копией пустой (rc=0), тесты снова зелёные. Этот же тестовый файл на исходном тексте из main (до правки `admin_scrape.py`) даёт `2 failed, 3 passed`, rc=1. ### Приёмка на проде (после деплоя, не раньше 17.09.2026) Значения «сейчас» сняты 17.09.2026 с `poincare`, только чтение. - **Главный маркер:** `ssh poincare "docker exec gendesign-beat-1 grep -c StormWall /app/app/workers/beat_schedule.py"` должна дать **2**. Сейчас 0. - `docker exec gendesign-beat-1 grep -c "Возврат после" /app/app/workers/beat_schedule.py` должна дать **0**. Сейчас 2. - `docker exec gendesign-beat-1 grep -n cooldown /app/app/workers/beat_schedule.py` должна найти **67 и 349**. 67 — историческая строка про инцидент env-fallback, 349 — новый комментарий, который цитирует опровергнутую посылку. Сейчас 67, 353, 369. Если main до мержа поменяет начало файла, номера сдвинутся, поэтому решают счётчики выше. - Guard, проверка по значению без запросов к эндпоинту: `docker exec gendesign-backend-1 python -c "import app.api.v1.admin_scrape as a; m=getattr(a,'_DOMRF_BLOCK_GUARD_MSG',None) or a._WAF_COOLDOWN_GUARD_MSG; print(hasattr(a,'_DOMRF_BLOCK_GUARD_MSG'), '3307' in m, 'cooldown' in m.lower())"` должна напечатать **`True True False`**. Сейчас печатает `False False True`. - В beat по-прежнему нет задач каталога. Проверка: в логе beat после рестарта нет `scrape_kn_catalog`. ### Деплой Деплой пересоздаёт backend, worker и beat. В коде меняются только комментарии, докстринги и текст отказа guard'а. Frontend тоже пересоберётся, потому что изменился `frontend/src/lib/api-types.ts`, но там поменялись только комментарии. Миграций нет. Пересоздание worker прерывает работающие Celery-задачи. Перед деплоем проверить: `SELECT count(*) FROM v_scrape_runs_unified WHERE status='running'` (таблицы `scrape_runs` в gendesign нет; kn-прогоны лежат в `kn_scrape_runs`). 17.09 в `v_scrape_runs_unified` строк со статусом running не было. Refs #2443, #3307, #2442 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bot-backend added 1 commit 2026-09-17 08:14:52 +00:00
beat: каталог DOM.РФ выключен из-за блокировки StormWall, а не «до cooldown» (#2443)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 13s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 17s
CI Trade-In / browser-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) Successful in 2m45s
CI / backend-tests (pull_request) Successful in 6m59s
b2ff92afbb
Комментарии у закомментированных записей scrape-kn-catalog-objects-weekly и
scrape-kn-catalog-flats-weekly обещали «возврат после cooldown 24-48h
(проверить через targeted test)». Тест проведён 20.08, 27.08 и 01.09:
кулдауна нет (kn-прогоны 29-33 шли в июне, уже после «бана» 24.05), с 01.09
наш.дом.рф за StormWall отдаёт IP Poincare «Доступ заблокирован [403]».
Комментарии теперь называют факт и условие включения (прокси и принятый
kn-прогон, #3307).

Решение больше не живёт только в комментарии: тест проверяет по значению
(по task, не по ключу), что ни одна из двух задач не попала в собранное
beat-расписание, и в тексте падения ведёт в #3307.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Light1YT added 2 commits 2026-09-17 09:00:08 +00:00
Ревью PR #3566: обещание таймера, убранное из beat, осталось в тексте
HTTP 400 эндпоинтов /admin/scrape/kn-catalog-objects и /kn-catalog-flats.
Отказ предлагал передать i_understand_waf_risk=true, «если WAF cooldown
прошёл», то есть подсказывал оператору обойти блокировку, которую ожидание
не снимает (зонды 20.08-01.09: StormWall, «Доступ заблокирован [403]»).

Теперь отказ называет StormWall и реальное условие: прокси и kn-прогон,
принятый по числу строк (#3307). Константа переименована в
_DOMRF_BLOCK_GUARD_MSG. Докстринги эндпоинтов и задач
scrape_kn_catalog_flats/objects больше не говорят про WAF cooldown и про
«вторник 04:00 UTC» у выключенной записи с расписанием в МСК.
api-types.ts перегенерирован как в CI-гейте openapi-codegen-check,
изменились только два докстринга.

Тесты отказа проверяют значение detail: #3307 есть, cooldown нет.
Поведение guard'а (400 без флага, задача не ставится) не менялось.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merge remote-tracking branch 'origin/main' into fix/ptica-domrf-waf-probe
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
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 13s
CI / frontend-tests (pull_request) Successful in 2m1s
CI / openapi-codegen-check (pull_request) Successful in 4m0s
CI / backend-tests (pull_request) Successful in 8m21s
0327af6fab
bot-backend merged commit b2394b0a0f into main 2026-09-17 09:15:51 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3566
No description provided.