[tradein] scraper_kit Group E4: финальное переключение estimator.py на kit (#2308 завершение) #2337

Closed
opened 2026-07-03 22:34:31 +00:00 by lekss361 · 3 comments
Owner

Родительский: #2308 (Group E). Зависит от E1 (#2311), E2 (#2312), E3 (#2313 — номер уточнить
после создания) — стартовать ТОЛЬКО когда все три стабильны на main.

Scope

Маленький изолированный PR: переключить импорты в app/services/estimator.py с legacy
app/services/scrapers/{avito_imv,cian_valuation,yandex_valuation} на scraper_kit.providers.*
эквиваленты, использующие уже проверенную (в E1-E3) config-wiring.

Blast radius (из разведки)

Единственный caller — POST /trade-in/estimate (app/api/v1/trade_in.py:171), sync,
квота-лимитирован (15/мес/аккаунт), реальная оценка стоимости показывается клиенту. Ни одна
Celery-задача не зовёт estimate_quality.

DoD (жёсткий, не смягчать)

  • Shadow-run: посчитать оценку старым и новым путём на выборке РЕАЛЬНЫХ объектов (не
    синтетика) ДО переключения импорта, сравнить расхождение — задокументировать конкретные
    числа в PR description
  • deep-code-reviewer explicit APPROVE обязателен — НЕ self-merge по обычной политике
    эпика, здесь дополнительный человеко-эквивалентный gate
  • Откат — проверить на практике, что это реально один revert импорта, не требует доп. миграций
  • Полный suite + существующие estimator-интеграционные тесты
    (test_estimator_{imv,cian,yandex}_integration.py) зелёные

Почему отдельный маленький PR, не часть E1-E3

Финальный switch — точка максимального риска (реальный прод-путь). Изоляция позволяет чистый
revert одним PR, если что-то пойдёт не так, не откатывая всю миграцию E1-E3.

Родительский: #2308 (Group E). Зависит от E1 (#2311), E2 (#2312), E3 (#2313 — номер уточнить после создания) — стартовать ТОЛЬКО когда все три стабильны на main. ## Scope Маленький изолированный PR: переключить импорты в `app/services/estimator.py` с legacy `app/services/scrapers/{avito_imv,cian_valuation,yandex_valuation}` на `scraper_kit.providers.*` эквиваленты, использующие уже проверенную (в E1-E3) config-wiring. ## Blast radius (из разведки) Единственный caller — `POST /trade-in/estimate` (`app/api/v1/trade_in.py:171`), sync, квота-лимитирован (15/мес/аккаунт), реальная оценка стоимости показывается клиенту. Ни одна Celery-задача не зовёт `estimate_quality`. ## DoD (жёсткий, не смягчать) - [ ] Shadow-run: посчитать оценку старым и новым путём на выборке РЕАЛЬНЫХ объектов (не синтетика) ДО переключения импорта, сравнить расхождение — задокументировать конкретные числа в PR description - [ ] **`deep-code-reviewer` explicit APPROVE обязателен** — НЕ self-merge по обычной политике эпика, здесь дополнительный человеко-эквивалентный gate - [ ] Откат — проверить на практике, что это реально один revert импорта, не требует доп. миграций - [ ] Полный suite + существующие estimator-интеграционные тесты (`test_estimator_{imv,cian,yandex}_integration.py`) зелёные ## Почему отдельный маленький PR, не часть E1-E3 Финальный switch — точка максимального риска (реальный прод-путь). Изоляция позволяет чистый revert одним PR, если что-то пойдёт не так, не откатывая всю миграцию E1-E3.
lekss361 added the
scope/backend
scrapers
tech-debt
tradein
labels 2026-07-03 22:34:41 +00:00
Author
Owner

Коррекция номеров: E1=#2334, E2=#2335, E3=#2336 (в теле issue указаны неверные номера-заглушки).

Коррекция номеров: E1=#2334, E2=#2335, E3=#2336 (в теле issue указаны неверные номера-заглушки).
Author
Owner

Обновление scope по итогам E1 (#2334): найден ВТОРОЙ реальный live-caller avito_imv, не
только estimator.pyapp/services/house_imv_backfill.py's process_houses_imv_batch.
Вызывается автоматически из scrape_pipeline.py (финальная IMV-фаза run_avito_city_sweep,
НЕ "только вручную", как гласит устаревший docstring) и пишет в house_imv_evaluations,
которую estimator.py читает напрямую (~строка 806, "killer accuracy fix" #651 IMV/Yandex
blend) для core-оценки. Тот же риск-периметр, что сам estimator.py.

E1's воркер намеренно НЕ мигрировал этот call site (оставлен на legacy), корректно опознав риск.

Решение по scope этого issue: включить house_imv_backfill.py's avito_imv call site в
scope ЭТОГО issue (#2337), под тем же review-гейтом что и estimator.py — они делят
data-path (house_imv_evaluations), логично переключать вместе, не оставлять один мигрированным
раньше другого. Kit-сторона (scraper_kit.providers.avito.imv) уже подтверждена безопасной
(#2334's golden-parity + config-footgun regression-тест на реальных фикстурах, byte-identical).

Обновление scope по итогам E1 (#2334): найден ВТОРОЙ реальный live-caller `avito_imv`, не только `estimator.py` — `app/services/house_imv_backfill.py`'s `process_houses_imv_batch`. Вызывается автоматически из `scrape_pipeline.py` (финальная IMV-фаза `run_avito_city_sweep`, НЕ "только вручную", как гласит устаревший docstring) и пишет в `house_imv_evaluations`, которую `estimator.py` читает напрямую (~строка 806, "killer accuracy fix" #651 IMV/Yandex blend) для core-оценки. Тот же риск-периметр, что сам `estimator.py`. E1's воркер намеренно НЕ мигрировал этот call site (оставлен на legacy), корректно опознав риск. **Решение по scope этого issue:** включить `house_imv_backfill.py`'s avito_imv call site в scope ЭТОГО issue (#2337), под тем же review-гейтом что и `estimator.py` — они делят data-path (`house_imv_evaluations`), логично переключать вместе, не оставлять один мигрированным раньше другого. Kit-сторона (`scraper_kit.providers.avito.imv`) уже подтверждена безопасной (#2334's golden-parity + config-footgun regression-тест на реальных фикстурах, byte-identical).
Author
Owner

Доп. уточнение по итогам review #2334 (E1):

  • Найден третий caller avito_imv (помимо estimator.py и house_imv_backfill.py) —
    app/api/v1/admin.py:700-732's /scrape/avito-imv debug-эндпоинт. Уже мигрирован на kit в
    Group A (#2305) и УЖЕ корректно передаёт config=RealScraperConfig() — не требует действий
    в #2337, просто для полноты чеклиста.
  • house_imv_backfill.py:15 docstring устарел ("Deliberately NOT wired into scheduler —
    triggered manually") — на деле process_houses_imv_batch вызывается автоматически из
    scrape_pipeline.py:1544 внутри run_avito_city_sweep (scheduler-triggered). Поправить
    docstring заодно с миграцией этого файла в #2337.
  • Жёсткое требование для #2337: когда будете переключать house_imv_backfill.py's
    _process_one_house (строка ~653) на kit — ОБЯЗАТЕЛЬНО добавить config=RealScraperConfig()
    (сейчас отсутствует, legacy в этом не нуждался). Regression-тест из #2334 существует именно
    для проверки этого — держать его как merge-гейт.
Доп. уточнение по итогам review #2334 (E1): - Найден третий caller `avito_imv` (помимо estimator.py и house_imv_backfill.py) — `app/api/v1/admin.py:700-732`'s `/scrape/avito-imv` debug-эндпоинт. Уже мигрирован на kit в Group A (#2305) и УЖЕ корректно передаёт `config=RealScraperConfig()` — не требует действий в #2337, просто для полноты чеклиста. - `house_imv_backfill.py:15` docstring устарел ("Deliberately NOT wired into scheduler — triggered manually") — на деле `process_houses_imv_batch` вызывается автоматически из `scrape_pipeline.py:1544` внутри `run_avito_city_sweep` (scheduler-triggered). Поправить docstring заодно с миграцией этого файла в #2337. - **Жёсткое требование для #2337**: когда будете переключать `house_imv_backfill.py`'s `_process_one_house` (строка ~653) на kit — ОБЯЗАТЕЛЬНО добавить `config=RealScraperConfig()` (сейчас отсутствует, legacy в этом не нуждался). Regression-тест из #2334 существует именно для проверки этого — держать его как merge-гейт.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#2337
No description provided.