gendesign/tradein-mvp/backend/app/services
Light1YT 0d010a707c
All checks were successful
CI / changes (pull_request) Successful in 7s
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
feat(tradein-imv): route IMV backfill через BrowserFetcher.fetch_json за dormant-флагом (#915 Stage 3)
Транспорт-своп для avito IMV backfill: вместо curl_cffi 4 IMV-запроса
(warm-up → coords → position → get-data) ходят через камуфокс in-page fetch
(/fetch-json sidecar). Same-origin avito.ru + прокси + warmed-cookies +
реальный fingerprint обходят datacenter-403 (#562/#853) без отдельного
IMV-прокси. За dormant-флагом avito_imv_use_browser_fetcher (default False) —
деплой не меняет prod IMV-поведение.

- avito_imv.py: _BrowserResponse + _BrowserSessionAdapter (мимикрия под
  curl_cffi session/response: .get/.post/.close, .status_code/.text/.json/
  .raise_for_status). evaluate_via_imv получает browser_fetcher kwarg; при
  его наличии адаптер вместо curl-сессии (browser-путь не требует curl_cffi).
- config.py: avito_imv_use_browser_fetcher (ENV AVITO_IMV_USE_BROWSER_FETCHER).
- house_imv_backfill.py: backfill_house_imv при флаге открывает ОДИН
  BrowserFetcher(source="avito") на батч и прокидывает в _process_one_house →
  evaluate_via_imv. Флаг OFF → browser_fetcher=None → curl-путь как раньше.
  Backfill-only: estimator и sweep-путь (process_houses_imv_batch) не тронуты.
- browser_fetcher.py: _post_fetch_json защищён от ответа без status/body keys.
- test_server_fetch_json.py: тест crash-retry ветки _do_fetch_json (relaunch
  + второй _fetch_json_once после browser-crash).
- tests: _BrowserResponse/_BrowserSessionAdapter юниты, evaluate_via_imv
  browser happy-path + 403→IMVAuthError, backfill flag on/off проводка.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 14:42:26 +05:00
..
exporters fix(tradein): trade-in PDF cover uses estimate.expires_at, not hardcoded +30d (#1530) 2026-06-17 20:27:57 +03:00
matching fix(matching): conflict_resolution picks freshest (last_seen_at) value, deterministic (#1539) 2026-06-17 22:43:59 +03:00
scrapers feat(tradein-imv): route IMV backfill через BrowserFetcher.fetch_json за dormant-флагом (#915 Stage 3) 2026-06-26 14:42:26 +05:00
__init__.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
account_quota.py fix(tradein): atomic conditional quota increment — close TOCTOU (#747) (#749) 2026-05-30 15:52:34 +00:00
brand.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
cache.py feat(tradein): Phase 3.2 — /api/v1/search endpoint + Redis cache (#479) 2026-05-23 14:44:22 +00:00
cian_price_history.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
cian_session.py feat(tradein): dedicated Cian mobile proxy — separate egress from Avito (#923) 2026-05-31 19:30:14 +00:00
dadata.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
estimator.py fix(estimator): enable split-home disclosure at validated threshold 1.2 (audit #1871) 2026-06-24 01:54:58 +05:00
geocoder.py fix(tradein): drop non-EKB avito detail coords on ingest (audit #1871 P2) 2026-06-23 14:33:10 +05:00
house_imv_backfill.py feat(tradein-imv): route IMV backfill через BrowserFetcher.fetch_json за dormant-флагом (#915 Stage 3) 2026-06-26 14:42:26 +05:00
house_metadata.py feat(tradein): postgres_fdw live read of gendesign.cad_buildings (replaces snapshot) (#493) 2026-05-24 08:57:30 +00:00
image_sanitizer.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
rosreestr_poll.py feat(tradein): scheduled monthly Rosreestr new-quarter poll → ingest alert (#888) (#894) 2026-05-31 13:13:55 +00:00
sber_index.py fix(tradein): correct SberIndex hedonic/asking dataset-paths + 404 warning (#902) 2026-06-17 22:50:52 +03:00
scheduler.py feat(scheduler): wire house_imv_backfill as scheduled source (#854) (#1910) 2026-06-26 07:45:08 +00:00
scrape_pipeline.py fix(avito): post-merge polish — unify fetch_mode guard + empty-render guard (#1811) (#1909) 2026-06-26 07:44:22 +00:00
scrape_runs.py feat(admin): unified scrape/runs + scraper/health + rotate-ip API для единой scrapers-страницы 2026-06-20 09:25:57 +03:00
scraper_settings.py chore(tradein): деактивировать N1.ru scraper — источник переехал в Cian 2026-06-16 14:50:51 +03:00
search_query.py feat(tradein): segment=vtorichka|novostroyki|all query-param on listings (#1188) 2026-06-17 21:43:01 +03:00
yandex_address_backfill.py fix(tradein): yandex address-enrich — city-agnostic title regex (спутники ЕКБ) (#875) 2026-05-31 09:08:29 +00:00
yandex_price_history.py feat(tradein): populate offer_price_history for yandex from gate price.previous/trend 2026-06-18 14:23:23 +03:00