feat(tradein/geocoder): регион-параметризация геокодера — region_code в geocode()/known_city_hint, --region-code у скрипта сделок, region_code у geocode-missing (#3051) #3432

Merged
lekss361 merged 1 commit from feat/3051-geocoder-region-param into main 2026-09-08 23:58:58 +00:00
Owner

Трек «Москва» (#3051): предпосылка для геокода 212 937 московских сделок (address='Москва, <улица>', 2 797 уникальных адресов, lat/lon NULL).

Почему

Геокодер был жёстко привязан к Свердловской области: Nominatim с viewbox=OBLAST66 + bounded=1, accept только при address.state ~ 'свердловск' и точке в bbox 66, known_city_hint знал лишь города области ('Москва' → None), cache-ключ без города смешивал регионы. Для 77 это давало None (впустую жгло квоту) либо ложный хит по одноимённой улице области.

Что

  • geocoder.py: geocode(addr, db, city_hint, region_code=66) → регион прокинут в _geocode_resolve → _nominatim_lookup → _nominatim_query; viewbox/bbox из REGIONS[code] (для 66 — прежний литерал OBLAST66_VIEWBOX, те же объекты bbox), state-маркер per region ('свердловск' / 'москва'), ЕКБ-тиры (geoportal/cadastral) и local-houses fallback только при 66; known_city_hint(value, region_code=66) по словарю региона → cache-ключ |city=москва; _has_oblast_marker/_resolve_city_for_geocode регион-aware (без префикса «Москва, Москва…»); неизвестный регион → ValueError. Регион приходит только от вызывающего (deals.region_code), без угадывания по тексту.
  • scripts/geocode_deals_nominatim.py: --region-code (default 66) → фильтр во всех 4 SQL (select/count/update/mark_tried), проброс в geocode/known_city_hint, регион в логах.
  • admin.py POST /admin/geocode-missing: region_code: int = 66 → фильтр в выборке и remaining, проброс в known_city_hint/geocode.
  • Адаптация 3 существующих тестов под новые сигнатуры (assert'ы усилены явным region_code=66), новых тестов нет (правило: после живого прогона).

Регрессия 66

Для всех существующих вызовов (дефолт 66) поведение байт-идентично: тот же словарь/regex/viewbox/маркер/tie-break/cache-ключ (ревью линзой «регрессия 66»). Единственное осознанное расхождение: geocode-missing?target=listings по умолчанию больше не берёт 16 930 неактивных listings чужих городов с region_code NULL (миграция 200) — раньше они геокодились впустую (bounded 66 → None).

Живая проверка Nominatim с прода для Москва, Гродненская с viewbox 77: state=Москва, city=Москва, 55.719/37.435 — маркер и bbox сработают. ruff чисто; целевые тесты зелёные (55 файлов, 1079 passed у воркера). Ревью: линза 77 APPROVE, линза 66 — MINOR (см. выше).

Не в scope (follow-up): межпроцессный лимитер Nominatim (скрипт + API), регион в /estimate/api/v1/geocode/tasks/geocode_missing (дефолт 66), suggest-путь.

Refs #3051. Связано: #3422, #3423, #3430, #3431.

🤖 Generated with Claude Code

Трек «Москва» (#3051): предпосылка для геокода 212 937 московских сделок (`address='Москва, <улица>'`, 2 797 уникальных адресов, `lat/lon NULL`). ## Почему Геокодер был жёстко привязан к Свердловской области: Nominatim с `viewbox=OBLAST66 + bounded=1`, accept только при `address.state ~ 'свердловск'` и точке в bbox 66, `known_city_hint` знал лишь города области (`'Москва' → None`), cache-ключ без города смешивал регионы. Для 77 это давало None (впустую жгло квоту) либо **ложный хит** по одноимённой улице области. ## Что - `geocoder.py`: `geocode(addr, db, city_hint, region_code=66)` → регион прокинут в `_geocode_resolve → _nominatim_lookup → _nominatim_query`; viewbox/bbox из `REGIONS[code]` (для 66 — прежний литерал `OBLAST66_VIEWBOX`, те же объекты bbox), state-маркер per region (`'свердловск'` / `'москва'`), ЕКБ-тиры (geoportal/cadastral) и local-houses fallback только при 66; `known_city_hint(value, region_code=66)` по словарю региона → cache-ключ `|city=москва`; `_has_oblast_marker`/`_resolve_city_for_geocode` регион-aware (без префикса «Москва, Москва…»); неизвестный регион → `ValueError`. Регион приходит только от вызывающего (`deals.region_code`), без угадывания по тексту. - `scripts/geocode_deals_nominatim.py`: `--region-code` (default 66) → фильтр во всех 4 SQL (select/count/update/mark_tried), проброс в `geocode`/`known_city_hint`, регион в логах. - `admin.py` `POST /admin/geocode-missing`: `region_code: int = 66` → фильтр в выборке и `remaining`, проброс в `known_city_hint`/`geocode`. - Адаптация 3 существующих тестов под новые сигнатуры (assert'ы усилены явным `region_code=66`), новых тестов нет (правило: после живого прогона). ## Регрессия 66 Для всех существующих вызовов (дефолт 66) поведение байт-идентично: тот же словарь/regex/viewbox/маркер/tie-break/cache-ключ (ревью линзой «регрессия 66»). Единственное осознанное расхождение: `geocode-missing?target=listings` по умолчанию больше не берёт 16 930 неактивных listings чужих городов с `region_code NULL` (миграция 200) — раньше они геокодились впустую (bounded 66 → None). Живая проверка Nominatim с прода для `Москва, Гродненская` с viewbox 77: `state=Москва`, `city=Москва`, 55.719/37.435 — маркер и bbox сработают. `ruff` чисто; целевые тесты зелёные (55 файлов, 1079 passed у воркера). Ревью: линза 77 ✅ APPROVE, линза 66 — MINOR (см. выше). Не в scope (follow-up): межпроцессный лимитер Nominatim (скрипт + API), регион в `/estimate`/`api/v1/geocode`/`tasks/geocode_missing` (дефолт 66), suggest-путь. Refs #3051. Связано: #3422, #3423, #3430, #3431. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
lekss361 added 1 commit 2026-09-08 23:53:22 +00:00
feat(tradein/geocoder): регион-параметризация геокодера — region_code в geocode()/known_city_hint, --region-code у скрипта сделок, region_code у admin geocode-missing (#3051)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 9s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-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 / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m6s
9898b6bc02
Геокодер был жёстко привязан к Свердловской области: viewbox 66 +
bounded=1, accept только при state ~ 'свердловск' и точке в bbox 66,
known_city_hint знал лишь города области → для 212 937 московских сделок
(address 'Москва, <улица>') геокод давал None либо ложный хит по
одноимённой улице области, а cache-ключ без города смешивал регионы.
Теперь регион приходит от вызывающего (deals.region_code): viewbox и
bbox из REGIONS[code], state-маркер per region ('свердловск'/'москва'),
ЕКБ-тиры (geoportal/cadastral/local houses) только при 66, city-хинт
через словарь региона → cache-ключ '|city=москва'. Дефолт 66 везде —
для существующих вызовов поведение байт-идентично (ревью двумя
линзами). Побочно: geocode-missing по умолчанию больше не берёт
listings с region_code NULL (16 930 неактивных чужих городов, которые
и раньше геокодились впустую).
lekss361 merged commit 6de69c4d05 into main 2026-09-08 23:58:58 +00:00
lekss361 deleted branch feat/3051-geocoder-region-param 2026-09-08 23:58:58 +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#3432
No description provided.