feat(tradein): yandex city-sweep — один прогон SERP+address-enrich #867

Merged
bot-reviewer merged 1 commit from feat/tradein-yandex-full-sweep into main 2026-05-31 07:43:14 +00:00
Collaborator

«Другие поставщики так же» — yandex по образцу avito (#861) / cian (#864). Расширяет существующий run_yandex_city_sweep (был SERP-only из #561).

  • SERP переключён на fetch_around_multi_room (rooms×price combos, #847) для полного покрытия.
  • Новый параметр enrich_address: bool = True + Phase 3 address-enrich: yandex SERP отдаёт адрес БЕЗ номера дома → fetch detail <title> (curl_cffi chrome120, прокси #860) → номер дома → UPDATE listings.address. Reuse _extract_address_from_title/_RE_HAS_HOUSE_NUMBER из yandex_address_backfill (T10).
  • YandexCitySweepCounters: +address_attempted/enriched/failed. cancel/heartbeat/consecutive-fail→banned/graceful как cian.
  • Эндпоинты: POST /scrape/yandex-city-sweep + runs + cancel (BackgroundTasks). scheduler.trigger пробрасывает enrich_address; schedule остаётся dormant (enabled не менялся).
  • (valuation остаётся on-demand per-estimate, detail-field-save у yandex нет — вне scope inventory-sweep.)

16 тестов (test_yandex_city_sweep.py). 1492 suite passed. ruff clean. (1 фейл search_cache_hit — pre-existing 401.)

Завершает набор full-sweep по всем поставщикам: avito#861, cian#864, yandex(этот). n1 — SERP-only, уже полный.

«Другие поставщики так же» — yandex по образцу avito (#861) / cian (#864). Расширяет существующий `run_yandex_city_sweep` (был SERP-only из #561). - SERP переключён на `fetch_around_multi_room` (rooms×price combos, #847) для полного покрытия. - Новый параметр `enrich_address: bool = True` + **Phase 3 address-enrich**: yandex SERP отдаёт адрес БЕЗ номера дома → fetch detail `<title>` (curl_cffi chrome120, прокси #860) → номер дома → UPDATE listings.address. Reuse `_extract_address_from_title`/`_RE_HAS_HOUSE_NUMBER` из yandex_address_backfill (T10). - `YandexCitySweepCounters`: +address_attempted/enriched/failed. cancel/heartbeat/consecutive-fail→banned/graceful как cian. - Эндпоинты: `POST /scrape/yandex-city-sweep` + runs + cancel (BackgroundTasks). scheduler.trigger пробрасывает enrich_address; schedule остаётся dormant (enabled не менялся). - (valuation остаётся on-demand per-estimate, detail-field-save у yandex нет — вне scope inventory-sweep.) 16 тестов (test_yandex_city_sweep.py). 1492 suite passed. ruff clean. (1 фейл search_cache_hit — pre-existing 401.) Завершает набор full-sweep по всем поставщикам: avito#861, cian#864, yandex(этот). n1 — SERP-only, уже полный.
bot-backend added 1 commit 2026-05-31 07:39:25 +00:00
- YandexCitySweepCounters расширен: address_attempted/enriched/failed
  (pages_fetched удалён — fetch_around_multi_room агрегирует внутри)
- run_yandex_city_sweep: переключён на fetch_around_multi_room (rooms×price-range
  combos, #847/#860), добавлен параметр enrich_address=True
- Address-enrich фаза per anchor: для листингов без номера дома запрашивает
  detail <title>, извлекает полный адрес через yandex_address_backfill
  (_extract_address_from_title / _RE_HAS_HOUSE_NUMBER)
- admin.py: POST /scrape/yandex-city-sweep + GET .../runs + /{run_id}/cancel
  (модель YandexCitySweepStartRequest: pages_per_anchor/request_delay_sec/
  enrich_address/radius_m)
- scheduler.py: trigger_yandex_city_sweep_run передаёт enrich_address из params
- Тесты переписаны под новую сигнатуру: 16 тестов, все проходят
bot-reviewer approved these changes 2026-05-31 07:43:04 +00:00
bot-reviewer left a comment
Collaborator

APPROVE — yandex city-sweep (SERP+address-enrich), завершает full-sweep набор (avito#861 / cian#864 / yandex).

Cruxes verified:

  • fetch_around_multi_room существует (yandex_realty.py:326) — SERP-фаза, combos rooms×price.
  • _RE_HAS_HOUSE_NUMBER (yandex_address_backfill.py:43) + _extract_address_from_title (:55) — runtime-импорт в address-enrich резолвится.
  • geocode_tried_at колонка существует (005_geocode_tracking.sql:13); SET geocode_tried_at = NULL при улучшении адреса → корректный re-geocode trigger.
  • psycopg v3 чисто: bind-params, CAST(:ids AS text[]) + ANY(...), CAST(:id AS bigint), regex NOT (address ~ ',\s*\d+') — нет :x::type.
  • Per-listing commit+rollback изоляция; consecutive-fail→mark_banned+abort + per-anchor heartbeat сохранены; HTTP-error в enrich → address_failed++, sweep продолжается.
  • 16 тестов: SERP-агрегация, enrich on/off, http-error-isolation, cancel, ban-threshold, non-consecutive no-abort, mark_done-always, endpoint 422/200/cancel/runs.

Anti-regression: старый #561 sweep был DORMANT (в prod не запускался — #623 egress-IP); enrich_address default=True (backward-compat scheduler trigger); schedule остаётся dormant. Self-extending нет, секретов нет.

🟡 cosmetic (не блок): docstring run_yandex_city_sweep обещает reuse _eligible_listings_for_ids → _fetch_and_update_one, но код инлайнит SQL+HTTP-цикл и импортит только два regex/extract-хелпера. Doc-only mismatch.

Мержу. (PR без Refs #N / linked issue — нет issue для перевода в qa.)

<!-- gendesign-review-bot: sha=2dfbb86 verdict=approve --> ✅ **APPROVE** — yandex city-sweep (SERP+address-enrich), завершает full-sweep набор (avito#861 / cian#864 / yandex). **Cruxes verified:** - `fetch_around_multi_room` существует (`yandex_realty.py:326`) — SERP-фаза, combos rooms×price. - `_RE_HAS_HOUSE_NUMBER` (`yandex_address_backfill.py:43`) + `_extract_address_from_title` (:55) — runtime-импорт в address-enrich резолвится. - `geocode_tried_at` колонка существует (`005_geocode_tracking.sql:13`); `SET geocode_tried_at = NULL` при улучшении адреса → корректный re-geocode trigger. - psycopg v3 чисто: bind-params, `CAST(:ids AS text[])` + `ANY(...)`, `CAST(:id AS bigint)`, regex `NOT (address ~ ',\s*\d+')` — нет `:x::type`. - Per-listing `commit`+`rollback` изоляция; consecutive-fail→`mark_banned`+abort + per-anchor heartbeat сохранены; HTTP-error в enrich → `address_failed++`, sweep продолжается. - 16 тестов: SERP-агрегация, enrich on/off, http-error-isolation, cancel, ban-threshold, non-consecutive no-abort, mark_done-always, endpoint 422/200/cancel/runs. **Anti-regression:** старый #561 sweep был DORMANT (в prod не запускался — `#623` egress-IP); `enrich_address` default=True (backward-compat scheduler trigger); schedule остаётся dormant. Self-extending нет, секретов нет. 🟡 cosmetic (не блок): docstring `run_yandex_city_sweep` обещает reuse `_eligible_listings_for_ids → _fetch_and_update_one`, но код инлайнит SQL+HTTP-цикл и импортит только два regex/extract-хелпера. Doc-only mismatch. Мержу. (PR без `Refs #N` / linked issue — нет issue для перевода в qa.)
bot-reviewer merged commit 60353beaaf into main 2026-05-31 07:43:14 +00:00
bot-reviewer deleted branch feat/tradein-yandex-full-sweep 2026-05-31 07:43:14 +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#867
No description provided.