fix(tradein/scrapers): подключить geoportal coords backfill в scheduler (#1967) #2346

Merged
lekss361 merged 1 commit from fix/tradein-avito-geo-backfill into main 2026-07-03 23:25:48 +00:00
Owner

Closes #1967

Премиса issue устарела — живой прод-замер (2026-07-04) вместо исходных "47% NULL lat":

  • avito active = 9181 (не 30327 из аудита 06-27), NULL lat = 393 (4.3%, не 47%).
  • Разрыв уже почти закрыт побочно: dedup-миграции 159-167 сократили active avito-set с ~30k до 9.2k; nightly geocode_missing_listings крутится с PR #1549 (2026-06-16), 18 дней прогонов.

Реальная находка: точный street+house геокодер против локального ekb_geoportal_buildings (34735 строк, pure local DB op без внешнего HTTP/rate-limit) — backfill_listings_coords_geoportal.py (#1841) — существовал, но был manual-only script, ни разу не запускавшийся recurring.

Фикс: подключил его в in-app scheduler по паттерну уже существующего cadastral_geo_match:

  • backfill_listings_coords_geoportal.pyto_counters() + run_geoportal_coords_backfill() run-lifecycle wrapper.
  • scheduler.pytrigger_geoportal_coords_backfill_run + dispatch.
  • product_handlers.py — kit-registry entry (обязательно для scraper_kit strangler-migration completeness — test_kit_registry_completeness.py иначе красный).
  • data/sql/171_scrape_schedules_seed_geoportal_coords_backfill.sql — seed на окно 05:00-06:00 UTC, до geocode_missing_listings (06:00-09:00) — точный house-level матч забирает адрес раньше грубого Nominatim-геокода.
  • 6 новых тестов (run-wrapper, scheduler wiring, migration content, kit-registry parity).

Честная оценка эффекта: проблема уже маргинальна на момент фикса — текущих live-кандидатов всего ~210 (avito active, address есть, lat NULL), по прошлому 5.8% match-rate эффект — единицы-десятки строк. Ценность: устранение up-to-24h задержки для новых NULL-coord листингов + приоритет точности над грубым геокодом.

Не в этом PR: dedup-на-ингесте (вторая половина исходного DoD issue #1967) — отдельный follow-up, out of scope здесь. Backoff-механизм для permanently-unmatchable строк (job пересканирует ~14.7k inactive backlog каждую ночь, дёшево но не идеально) — minor follow-up, не блокер.

Проверено: ruff чисто, migration идемпотентна (ON CONFLICT (source) DO NOTHING), нет basename-коллизии, окно не пересекается с geocode_missing_listings. Live SQL независимо перепроверен reviewer'ом (4.3%/9181 — день-в-день совпадение). code-reviewer APPROVE, 67/67 relevant tests + kit-registry-completeness passed.

Post-merge: UPDATE scrape_schedules SET next_run_at=now() WHERE source='geoportal_coords_backfill' для форс-прогона smoke на проде.

Closes #1967 **Премиса issue устарела — живой прод-замер (2026-07-04) вместо исходных "47% NULL lat":** - avito active = 9181 (не 30327 из аудита 06-27), NULL lat = 393 (**4.3%**, не 47%). - Разрыв уже почти закрыт побочно: dedup-миграции 159-167 сократили active avito-set с ~30k до 9.2k; nightly `geocode_missing_listings` крутится с PR #1549 (2026-06-16), 18 дней прогонов. **Реальная находка:** точный street+house геокодер против локального `ekb_geoportal_buildings` (34735 строк, pure local DB op без внешнего HTTP/rate-limit) — `backfill_listings_coords_geoportal.py` (#1841) — существовал, но был manual-only script, ни разу не запускавшийся recurring. **Фикс:** подключил его в in-app scheduler по паттерну уже существующего `cadastral_geo_match`: - `backfill_listings_coords_geoportal.py` — `to_counters()` + `run_geoportal_coords_backfill()` run-lifecycle wrapper. - `scheduler.py` — `trigger_geoportal_coords_backfill_run` + dispatch. - `product_handlers.py` — kit-registry entry (обязательно для scraper_kit strangler-migration completeness — `test_kit_registry_completeness.py` иначе красный). - `data/sql/171_scrape_schedules_seed_geoportal_coords_backfill.sql` — seed на окно 05:00-06:00 UTC, **до** `geocode_missing_listings` (06:00-09:00) — точный house-level матч забирает адрес раньше грубого Nominatim-геокода. - 6 новых тестов (run-wrapper, scheduler wiring, migration content, kit-registry parity). **Честная оценка эффекта:** проблема уже маргинальна на момент фикса — текущих live-кандидатов всего ~210 (avito active, address есть, lat NULL), по прошлому 5.8% match-rate эффект — единицы-десятки строк. Ценность: устранение up-to-24h задержки для новых NULL-coord листингов + приоритет точности над грубым геокодом. **Не в этом PR:** dedup-на-ингесте (вторая половина исходного DoD issue #1967) — отдельный follow-up, out of scope здесь. Backoff-механизм для permanently-unmatchable строк (job пересканирует ~14.7k inactive backlog каждую ночь, дёшево но не идеально) — minor follow-up, не блокер. Проверено: ruff чисто, migration идемпотентна (`ON CONFLICT (source) DO NOTHING`), нет basename-коллизии, окно не пересекается с `geocode_missing_listings`. Live SQL независимо перепроверен reviewer'ом (4.3%/9181 — день-в-день совпадение). code-reviewer APPROVE, 67/67 relevant tests + kit-registry-completeness passed. **Post-merge:** `UPDATE scrape_schedules SET next_run_at=now() WHERE source='geoportal_coords_backfill'` для форс-прогона smoke на проде.
lekss361 added 1 commit 2026-07-03 23:23:20 +00:00
fix(tradein/scrapers): подключить geoportal coords backfill в scheduler (#1967)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 8s
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 1m38s
fd9b27f87c
Живой прод-замер показал, что исходная постановка issue (avito 47% NULL
lat) уже почти закрыта побочно: dedup-миграции 159-167 сократили active
avito-set с 30k до 9.2k, nightly geocode_missing_listings крутится с PR
#1549 — текущий NULL lat = 4.3% (393/9181), не 47%.

Реальная находка: точный street+house геокодер против локального
ekb_geoportal_buildings (#1841, backfill_listings_coords_geoportal.py)
существовал, но был manual-only script, ни разу не запускавшийся
recurring. Подключил его в in-app scheduler по паттерну cadastral_geo_match
— run-lifecycle wrapper, dispatch, kit-registry entry (обязательно для
scraper_kit strangler-migration completeness), seed-миграция на окно
05:00-06:00 UTC (до geocode_missing_listings 06:00-09:00 — точный
house-level матч забирает адрес раньше грубого Nominatim-геокода).

Dedup-на-ингесте (вторая половина исходного DoD) — отдельный follow-up,
out of scope здесь.
lekss361 merged commit 5fa505b809 into main 2026-07-03 23:25:48 +00:00
Sign in to join this conversation.
No reviewers
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#2346
No description provided.