Москва, часть 1/3: ключи регионов — реестр вместо констант, city_fias_id, doc_type #3051

Open
opened 2026-08-22 11:23:52 +00:00 by lekss361 · 8 comments
Owner

Разбиение #2996 · эпик #2989 · блокирует части 2 и 3

Область: только регион 77 (Москва). Область 50 отложена — обоснование в комментарии к #2996: там 10 121 значение города против 612 у Москвы, вся мина текстовых имён сосредоточена именно в области.

Почему это первое

Три остальные части опираются на региональные ключи. Пока region_code нет у houses, а город сравнивается строкой, ни гард по полигону, ни решение по FDW не на что опереть.

Что сделать

1. Реестр регионов вместо зашитых констант

Сейчас границы покрытия лежат константами в трёх местах, и каждая отвергнет Москву:

Место Что
location_index.py:65-73 _EKB_BBOX 56.70–56.95 / 60.50–60.75 → точка вне даёт out_of_coverage
geocoder.py:75-76 EKB_BBOX_TIGHT, EKB_BBOX_WIDE
geocoder.py:105 OBLAST66_BBOX
normalize.py:117 EKB_CITY_TOKEN = "екатеринбург"
geocoder.py:129,292,298,319 SVERDLOVSK_OBLAST_CITIES, гейтинг ЕКБ-локальных тиров

Образец уже написан: house_imv_backfill.py:143 держит _REGION_BBOX списком регионов. Поднять в общий реестр (регион → границы, набор городов, доступные тиры обогащения) и заставить потреблять всех перечисленных.

Ключевое требование: регион без тира обогащения должен деградировать явно, а не молча. Сейчас estimator.py:1318 пишет warning и считает цену дальше без квартального индекса — для Москвы такой тир отсутствует целиком.

2. city_fias_id сквозняком

listings, deals, deal_city_price_bands. Джойн по ключу, текстовое имя — только для показа.

Прицельно: estimator.py:1728 и :1809LEFT JOIN deal_city_price_bands b ON b.city = d.city; _load_city_price_bands (estimator.py:329-348) грузит словарь строками; estimator.py:1801 — литерал city != "екатеринбург" в ветке расширения коридора (условие должно стать свойством плотности выборки, а не именем города).

3. doc_type в deals с фильтром на ДКП

Колонки нет, тип теряется при загрузке, а оценщик всюду предполагает ДКП. Для Москвы это искажает цену:

Год ДКП медиана ДДУ медиана ДДУ
2026 53 327 316 096 1 371 409 672
2025 113 522 276 388 3 072 296 152
2024 107 005 256 250 30 627 112 743

Тридцать тысяч ДДУ 2024 года по ценам котлована войдут в коридор как продажи.

4. region_code NOT NULL у houses

Дом без выводимого региона уходит в карантин, а не получает выдуманный. Сейчас 23 дома лежат вне области 66 с разбросом широты 43–59.

5. Снять депромоут не-ЕКБ описаний

estimator.py:4884-4887premium_buildings_curated активно понижает не-ЕКБ описания как шум. Для Москвы это прямой вред.

Отдельно зафиксировать, но не чинить здесь: estimator.py:2308 — константы калибровки вторички ЕКБ применяются ко всему движку. Это вопрос точности, а не корректности, и требует отдельного замера на московских данных.

6. Параметризовать регион в загрузчиках

scheduler.py:309, yandex_address_backfill.py:82, zhkh_flats_loader.py:368, gar_flats_load.py:98, sber_index.py:72,453.

Приёмка

  • Реестр регионов единственный источник границ; ни одного bbox-литерала в location_index.py, geocoder.py, normalize.py
  • Московская координата (55.75 / 37.62) даёт статус ok, а не out_of_coverage
  • city_fias_id в трёх таблицах, джойн по ключу; 612 значений города региона 77 сопоставлены и проверены перечислением
  • doc_type в deals, загрузка фильтрует ДКП; ДДУ не попадают в ценовой коридор
  • region_code NOT NULL у houses, карантин для невыводимых
  • Отсутствующий тир обогащения даёт явную деградацию, а не warning в лог
  • Регрессия на ЕКБ: замороженный гейт оценок не сдвинулся

Оценка

L — дробить дальше. Разумный порядок под-PR: реестр регионов и bbox → doc_type и фильтр загрузки → city_fias_idregion_code у houses → депромоут и параметризация загрузчиков.

Разбиение #2996 · эпик #2989 · **блокирует части 2 и 3** Область: **только регион 77 (Москва)**. Область 50 отложена — обоснование в комментарии к #2996: там 10 121 значение города против 612 у Москвы, вся мина текстовых имён сосредоточена именно в области. ## Почему это первое Три остальные части опираются на региональные ключи. Пока `region_code` нет у `houses`, а город сравнивается строкой, ни гард по полигону, ни решение по FDW не на что опереть. ## Что сделать ### 1. Реестр регионов вместо зашитых констант Сейчас границы покрытия лежат константами в трёх местах, и каждая отвергнет Москву: | Место | Что | |---|---| | `location_index.py:65-73` | `_EKB_BBOX` 56.70–56.95 / 60.50–60.75 → точка вне даёт `out_of_coverage` | | `geocoder.py:75-76` | `EKB_BBOX_TIGHT`, `EKB_BBOX_WIDE` | | `geocoder.py:105` | `OBLAST66_BBOX` | | `normalize.py:117` | `EKB_CITY_TOKEN = "екатеринбург"` | | `geocoder.py:129,292,298,319` | `SVERDLOVSK_OBLAST_CITIES`, гейтинг ЕКБ-локальных тиров | Образец уже написан: `house_imv_backfill.py:143` держит `_REGION_BBOX` списком регионов. Поднять в общий реестр (регион → границы, набор городов, доступные тиры обогащения) и заставить потреблять всех перечисленных. Ключевое требование: **регион без тира обогащения должен деградировать явно, а не молча**. Сейчас `estimator.py:1318` пишет warning и считает цену дальше без квартального индекса — для Москвы такой тир отсутствует целиком. ### 2. `city_fias_id` сквозняком `listings`, `deals`, `deal_city_price_bands`. Джойн по ключу, текстовое имя — только для показа. Прицельно: `estimator.py:1728` и `:1809` — `LEFT JOIN deal_city_price_bands b ON b.city = d.city`; `_load_city_price_bands` (`estimator.py:329-348`) грузит словарь строками; `estimator.py:1801` — литерал `city != "екатеринбург"` в ветке расширения коридора (условие должно стать свойством плотности выборки, а не именем города). ### 3. `doc_type` в `deals` с фильтром на ДКП Колонки нет, тип теряется при загрузке, а оценщик всюду предполагает ДКП. Для Москвы это искажает цену: | Год | ДКП | медиана | ДДУ | медиана ДДУ | |---|---|---|---|---| | 2026 | 53 327 | 316 096 | 1 371 | 409 672 | | 2025 | 113 522 | 276 388 | 3 072 | 296 152 | | 2024 | 107 005 | 256 250 | **30 627** | **112 743** | Тридцать тысяч ДДУ 2024 года по ценам котлована войдут в коридор как продажи. ### 4. `region_code NOT NULL` у `houses` Дом без выводимого региона уходит в карантин, а не получает выдуманный. Сейчас 23 дома лежат вне области 66 с разбросом широты 43–59. ### 5. Снять депромоут не-ЕКБ описаний `estimator.py:4884-4887` — `premium_buildings_curated` активно понижает не-ЕКБ описания как шум. Для Москвы это прямой вред. Отдельно зафиксировать, но **не чинить здесь**: `estimator.py:2308` — константы калибровки вторички ЕКБ применяются ко всему движку. Это вопрос точности, а не корректности, и требует отдельного замера на московских данных. ### 6. Параметризовать регион в загрузчиках `scheduler.py:309`, `yandex_address_backfill.py:82`, `zhkh_flats_loader.py:368`, `gar_flats_load.py:98`, `sber_index.py:72,453`. ## Приёмка - [ ] Реестр регионов единственный источник границ; ни одного bbox-литерала в `location_index.py`, `geocoder.py`, `normalize.py` - [ ] Московская координата (55.75 / 37.62) даёт статус `ok`, а не `out_of_coverage` - [ ] `city_fias_id` в трёх таблицах, джойн по ключу; 612 значений города региона 77 сопоставлены и проверены перечислением - [ ] `doc_type` в `deals`, загрузка фильтрует ДКП; ДДУ не попадают в ценовой коридор - [ ] `region_code NOT NULL` у `houses`, карантин для невыводимых - [ ] Отсутствующий тир обогащения даёт явную деградацию, а не warning в лог - [ ] Регрессия на ЕКБ: замороженный гейт оценок не сдвинулся ## Оценка L — дробить дальше. Разумный порядок под-PR: реестр регионов и bbox → `doc_type` и фильтр загрузки → `city_fias_id` → `region_code` у `houses` → депромоут и параметризация загрузчиков.
lekss361 added the
bug
data
priority/p1
scope/backend
scope/db
tradein
labels 2026-08-22 11:24:56 +00:00
Collaborator

Шард 1a пункта 1 — на проде (PR #3116, деплой 8a4215fe, ревизия в контейнере проверена)

Реестр регионов app/services/regions.py — единственный источник гео-границ; location_index / geocoder / matching.normalize переведены на identity-алиасы (копии, разъезжающиеся при правке, невозможны — закреплено тестом). Регион 66 — байт-в-байт прежние литералы. Регион 77: МКАД-ядро, генеральный bbox с Новой Москвой/Зеленоградом, enrichment_tiers = ∅ как явный факт с готовой формулировкой (unsupported_tier_reason).

Живая приёмка (прод-БД, задеплоенный код, 26.08 16:30 UTC):

Москва  55.75/37.62 → insufficient_data (sample=0)   ← было out_of_coverage
ЕКБ     56.83/60.60 → ok, location_index_pct=76.6    ← тракт не тронут
Н.Тагил 57.91/59.97 → out_of_coverage                ← ядро 66 сохранено

По пункту приёмки «московская координата даёт ok»: буквальный ok при нуле московских листингов был бы враньём — статус честно говорит «регион узнан, данных нет». ok появится сам, когда появятся данные (части 2-3 / FDW #3053).

Примечания к скоупу:

  • гейт ЕКБ-тиров геокодера (#2582) для Москвы уже корректен по построению — fail-closed открывает ЕКБ-локальные тиры только при подтверждённом ЕКБ, перепайка не потребовалась;
  • _CITY_TOKENS в normalize не тронут намеренно — это зеркало sweep-раскатки (CITY_ANCHORS), другой концерн;
  • kit-копия scraper_kit/geo.py не тронута: скраперы собирают только 66.

Остаток пункта 1 (вайринг явной деградации тиров в estimator — вместе с п.5) и пункты 2-6 — следующими шардами.

## Шард 1a пункта 1 — на проде (PR #3116, деплой 8a4215fe, ревизия в контейнере проверена) Реестр регионов `app/services/regions.py` — единственный источник гео-границ; `location_index` / `geocoder` / `matching.normalize` переведены на identity-алиасы (копии, разъезжающиеся при правке, невозможны — закреплено тестом). Регион 66 — байт-в-байт прежние литералы. Регион 77: МКАД-ядро, генеральный bbox с Новой Москвой/Зеленоградом, `enrichment_tiers = ∅` как явный факт с готовой формулировкой (`unsupported_tier_reason`). **Живая приёмка (прод-БД, задеплоенный код, 26.08 16:30 UTC):** ``` Москва 55.75/37.62 → insufficient_data (sample=0) ← было out_of_coverage ЕКБ 56.83/60.60 → ok, location_index_pct=76.6 ← тракт не тронут Н.Тагил 57.91/59.97 → out_of_coverage ← ядро 66 сохранено ``` По пункту приёмки «московская координата даёт ok»: буквальный `ok` при нуле московских листингов был бы враньём — статус честно говорит «регион узнан, данных нет». `ok` появится сам, когда появятся данные (части 2-3 / FDW #3053). Примечания к скоупу: - гейт ЕКБ-тиров геокодера (#2582) для Москвы уже корректен по построению — fail-closed открывает ЕКБ-локальные тиры только при подтверждённом ЕКБ, перепайка не потребовалась; - `_CITY_TOKENS` в normalize не тронут намеренно — это зеркало sweep-раскатки (CITY_ANCHORS), другой концерн; - kit-копия `scraper_kit/geo.py` не тронута: скраперы собирают только 66. Остаток пункта 1 (вайринг явной деградации тиров в estimator — вместе с п.5) и пункты 2-6 — следующими шардами.
Collaborator

П.4 — на проде (PR #3121, деплой c6c934fb, миграция 272 применена, эффект проверен)

region_code = 66 :  9 719 домов   ← ровно замеренное геометрией множество
NULL (карантин)  :    663         ← 620 без geom + 23 порченых + свежесозданные

Все три дома с координатами в bbox Москвы («Крауля, гп 1», «Московская, гп 6», «Академика Ландау») — в карантине NULL, регион 77 никому не выдуман. Код наследования на записи (регион развёртки при непротиворечивых координатах, иначе NULL + warning) — в контейнерах tradein-backend и tradein-scraper.

NOT NULL из постановки — отдельной миграцией, когда карантин опустеет (нужно гео-обогащение 620 безгеомных и починка 23 порченых координат — последнее пересекается с #2777).

#3052 разблокирован по части region_code; для полигонального гарда остаётся city_fias_id (п.2) и выбор источника полигонов для 77.

Побочный улов при мерже: 4 зомби-прогона после ночного ребута блокировали свои источники до 6ч — заведена #3122 (boot-reap по границе старта контейнера).

## П.4 — на проде (PR #3121, деплой c6c934fb, миграция 272 применена, эффект проверен) ``` region_code = 66 : 9 719 домов ← ровно замеренное геометрией множество NULL (карантин) : 663 ← 620 без geom + 23 порченых + свежесозданные ``` Все три дома с координатами в bbox Москвы («Крауля, гп 1», «Московская, гп 6», «Академика Ландау») — в карантине NULL, регион 77 никому не выдуман. Код наследования на записи (регион развёртки при непротиворечивых координатах, иначе NULL + warning) — в контейнерах tradein-backend и tradein-scraper. `NOT NULL` из постановки — отдельной миграцией, когда карантин опустеет (нужно гео-обогащение 620 безгеомных и починка 23 порченых координат — последнее пересекается с #2777). **#3052 разблокирован** по части `region_code`; для полигонального гарда остаётся `city_fias_id` (п.2) и выбор источника полигонов для 77. Побочный улов при мерже: 4 зомби-прогона после ночного ребута блокировали свои источники до 6ч — заведена #3122 (boot-reap по границе старта контейнера).
Collaborator

Аудит пп. 2, 5, 6 против живого кода (27.08) — до реализации, чтобы чеклист отражал реальность

п.6 «Параметризовать регион в загрузчиках» — в основном уже сделан прошлыми правками

место из постановки состояние сейчас
gar_flats_load уже параметризован: --region (default "66")
zhkh_flats_loader уже параметризован: region_code: str = "66" (services/, строка 368)
pipeline/scheduler все run_* принимают region_code: int = DEFAULT_REGION_CODE (8 сигнатур)
sber_index остаётся: словарь {"66": "Свердловская область"} (:72) и if ref_area == "66" (:453)
yandex_address_backfill остаётся: предикат region_code=66 зашит в SQL (docstring прямо говорит «Pilot scope: hardcoded»)

Два остатка — источники, которых для Москвы не будет вовсе (скраперы её не собирают, данные пойдут FDW-путём #3053). Дописывать им параметр сегодня — код без случая применения; предлагаю пункт считать закрытым с этой оговоркой.

п.5 «Снять депромоут не-ЕКБ описаний» — премиса не совпадает с кодом

_is_premium_building (нынешняя строка ~5048) — по собственному контракту «МЕТАДАННЫЕ для manual-review routing, НЕ ценовой сигнал: не трогает median/expected_sold/ranges». Для московского дома lookup вернёт (False, None, None) — нейтрально, вреда нет. «Понижение не-ЕКБ» в 142_premium_buildings_curated.sql — это ОДНА выверенная строка-демоушен конкретного mislabeled-дома (descs про Нижний Новгород, приклеенные к ЕКБ-дому), то есть курация качества данных, а не систематический фильтр. EKB-bias обеих таблиц уже задокументирован на месте (LOW audit #4, doc-only). Реальная московская работа тут — не «снять депромоут», а когда-нибудь построить московский слой premium-курации; предлагаю переформулировать или снять пункт.

п.2 city_fias_id — зависимости, из-за которых не начинаю без решения

  • Приёмка «612 значений города региона 77 сопоставлены» относится к московским сделкам в ЧУЖОЙ базе — они за нерешённым #3053 (FDW). В нашей базе 384 различных значения deals.city, все — регион 66.
  • Ни одной city-level ФИАС-колонки в схеме нет (только house_fias_id от DaData); источник справочника city→fias_id — решение, которое стоит зафиксировать в задаче до реализации (как это сделано для полигонов в #3052): ГАР ADDR_OBJ (не загружен — «огрызок»), DaData, ручной справочник на 24 города региона 66 + 612 Москвы.

Готов взять п.2 сразу после фиксации источника. Пп. 1 (реестр — #3116), 4 (region_code у houses — #3121) — на проде с приёмками выше.

## Аудит пп. 2, 5, 6 против живого кода (27.08) — до реализации, чтобы чеклист отражал реальность ### п.6 «Параметризовать регион в загрузчиках» — в основном уже сделан прошлыми правками | место из постановки | состояние сейчас | |---|---| | `gar_flats_load` | уже параметризован: `--region` (default "66") | | `zhkh_flats_loader` | уже параметризован: `region_code: str = "66"` (services/, строка 368) | | pipeline/scheduler | все `run_*` принимают `region_code: int = DEFAULT_REGION_CODE` (8 сигнатур) | | `sber_index` | остаётся: словарь `{"66": "Свердловская область"}` (:72) и `if ref_area == "66"` (:453) | | `yandex_address_backfill` | остаётся: предикат `region_code=66` зашит в SQL (docstring прямо говорит «Pilot scope: hardcoded») | Два остатка — источники, которых для Москвы не будет вовсе (скраперы её не собирают, данные пойдут FDW-путём #3053). Дописывать им параметр сегодня — код без случая применения; предлагаю пункт считать закрытым с этой оговоркой. ### п.5 «Снять депромоут не-ЕКБ описаний» — премиса не совпадает с кодом `_is_premium_building` (нынешняя строка ~5048) — по собственному контракту «МЕТАДАННЫЕ для manual-review routing, НЕ ценовой сигнал: не трогает median/expected_sold/ranges». Для московского дома lookup вернёт `(False, None, None)` — нейтрально, вреда нет. «Понижение не-ЕКБ» в `142_premium_buildings_curated.sql` — это ОДНА выверенная строка-демоушен конкретного mislabeled-дома (descs про Нижний Новгород, приклеенные к ЕКБ-дому), то есть курация качества данных, а не систематический фильтр. EKB-bias обеих таблиц уже задокументирован на месте (LOW audit #4, doc-only). Реальная московская работа тут — не «снять депромоут», а когда-нибудь построить московский слой premium-курации; предлагаю переформулировать или снять пункт. ### п.2 `city_fias_id` — зависимости, из-за которых не начинаю без решения - Приёмка «612 значений города региона 77 сопоставлены» относится к московским сделкам в ЧУЖОЙ базе — они за нерешённым #3053 (FDW). В нашей базе 384 различных значения `deals.city`, все — регион 66. - Ни одной city-level ФИАС-колонки в схеме нет (только `house_fias_id` от DaData); **источник справочника city→fias_id — решение, которое стоит зафиксировать в задаче до реализации** (как это сделано для полигонов в #3052): ГАР ADDR_OBJ (не загружен — «огрызок»), DaData, ручной справочник на 24 города региона 66 + 612 Москвы. Готов взять п.2 сразу после фиксации источника. Пп. 1 (реестр — #3116), 4 (region_code у houses — #3121) — на проде с приёмками выше.
Collaborator

Перепроверка 27.08.2026 (после пересборки базы 25-26.08 и переезда продукта на Poincare). Тело тикета писалось 20-24.08 по старой инфраструктуре.

Пункт 1 сделан — коммит 0529bb24, app/services/regions.py стал единственным источником гео-границ, константы в geocoder.py (118/148/170) производные.

Пункты 2 и 3 остаются: колонки city_fias_id нет ни в одной таблице, doc_type в deals не заведён. Тикет не закрываю — FIAS-часть вынесена в заголовок.

**Перепроверка 27.08.2026** (после пересборки базы 25-26.08 и переезда продукта на Poincare). Тело тикета писалось 20-24.08 по старой инфраструктуре. Пункт 1 **сделан** — коммит `0529bb24`, `app/services/regions.py` стал единственным источником гео-границ, константы в `geocoder.py` (118/148/170) производные. Пункты 2 и 3 остаются: колонки `city_fias_id` нет ни в одной таблице, `doc_type` в `deals` не заведён. Тикет не закрываю — FIAS-часть вынесена в заголовок.
Author
Owner

Статус 2026-09-08 (трек 2 «Москва», подготовка к наполнению):

  • #3421deals.doc_type, region_code/doc_types как параметры импорта (миграция 288) — смержен.
  • #3422 — московский маппинг импорта (canonical_city, raw_payload с исходным округом/okato/кварталом, per-source чекпоинт, wildcard rosreestr_dkp_import_*), миграция 289 (FDW-колонки + выключенный seed rosreestr_dkp_import_77) — смержен.
  • #3423 — регион-фильтр ДКП-коридора в estimator (d.region_code), регион из region_for_point, дефолт 66 — смержен.

Деплой e2045582 success; на проде 288/289 применены, seed 77 disabled, deals по 77 = 0. Первый живой прогон импорта по 77 — после решения владельца (объём ~200k строк, bands по Москве ещё нет — sub-PR B). Остаток трека (B–H) — по дизайну регионных ключей в vault: bands (region_code, city), settlements + aliases + DaData fias, city_fias_id, estimator по fias, NSPD-полигоны, per-region guard.

Статус 2026-09-08 (трек 2 «Москва», подготовка к наполнению): - #3421 — `deals.doc_type`, `region_code`/`doc_types` как параметры импорта (миграция 288) — смержен. - #3422 — московский маппинг импорта (`canonical_city`, `raw_payload` с исходным округом/okato/кварталом, per-source чекпоинт, wildcard `rosreestr_dkp_import_*`), миграция 289 (FDW-колонки + выключенный seed `rosreestr_dkp_import_77`) — смержен. - #3423 — регион-фильтр ДКП-коридора в estimator (`d.region_code`), регион из `region_for_point`, дефолт 66 — смержен. Деплой e2045582 success; на проде 288/289 применены, seed 77 disabled, `deals` по 77 = 0. Первый живой прогон импорта по 77 — после решения владельца (объём ~200k строк, bands по Москве ещё нет — sub-PR B). Остаток трека (B–H) — по дизайну регионных ключей в vault: bands `(region_code, city)`, settlements + aliases + DaData fias, `city_fias_id`, estimator по fias, NSPD-полигоны, per-region guard.
Author
Owner

Первый живой прогон импорта Росреестра по Москве выполнен (разово, по решению владельца): run 6460, 2026-09-08 20:59–21:03 UTC, 212 937 ДКП-сделок за 2024+ вставлено, 0 ошибок, 107 батчей. В deals (region 77): все city='Москва', doc_type='ДКП', raw_payload с исходным округом/okato/кадастровым кварталом у 100% (6,7% строк с пустым city источника сохранены), медиана 294 457 ₽/м² (p10 134 680 / p90 464 532). Регион 66 не тронут (108 623). Координаты NULL — геокод отдельным шагом, как для 66.

Расписание rosreestr_dkp_import_77 остаётся выключенным до sub-PR B (bands (region_code, city)). Механика разового запуска без ручки run-now: enabled=true, next_run_at=now() → claim на ближайшем тике → enabled=false.

Первый живой прогон импорта Росреестра по Москве выполнен (разово, по решению владельца): run 6460, 2026-09-08 20:59–21:03 UTC, **212 937** ДКП-сделок за 2024+ вставлено, 0 ошибок, 107 батчей. В `deals` (region 77): все `city='Москва'`, `doc_type='ДКП'`, `raw_payload` с исходным округом/okato/кадастровым кварталом у 100% (6,7% строк с пустым city источника сохранены), медиана 294 457 ₽/м² (p10 134 680 / p90 464 532). Регион 66 не тронут (108 623). Координаты NULL — геокод отдельным шагом, как для 66. Расписание `rosreestr_dkp_import_77` остаётся выключенным до sub-PR B (bands `(region_code, city)`). Механика разового запуска без ручки run-now: `enabled=true, next_run_at=now()` → claim на ближайшем тике → `enabled=false`.
Author
Owner

Статус 2026-09-09 (ночь):

  • #3430 (тесты трека: 14 тестов по импорту 77 / чекпоинту / wildcard / регион-скоупу коридора / 289 / deploy-скрипту) — смержен.
  • #3431 (sub-PR B: deal_city_price_bands по (region_code, city), миграция 298, refresh per-region) — смержен, деплой success. На проде: 298 применена, PK (region_code, city); bands региона 66 после re-seed и после штатного refresh-джоба (run 6468) побайтно совпадают со snapshot, снятым до правок (deal_city_price_bands_bak_0908, 383 строки); Москва получила строку tier=full: 34 221–718 870 ₽/м², n=212 937. Расписание deal_city_price_bands_refresh снова включено (было временно выключено, чтобы refresh 07 UTC не смешал Москву в floor малых городов области).
  • Геокод московских сделок: текущий геокодер жёстко ограничен Свердловской обл. (viewbox 66 + bounded=1 + state ~ 'свердловск', known_city_hint('Москва') → None, cache-ключ без региона) — без правки кода 213k строк либо None, либо ложный хит по одноимённой улице области. PR с регион-параметризацией геокодера (geocode(..., region_code), --region-code у скрипта, region_code у geocode-missing) — на ревью. Всем 77-строкам превентивно проставлен geocode_tried_at, чтобы никакой нескоупленный геокод их не трогал; cron-scrape.sh на selectel не запланирован.
Статус 2026-09-09 (ночь): - #3430 (тесты трека: 14 тестов по импорту 77 / чекпоинту / wildcard / регион-скоупу коридора / 289 / deploy-скрипту) — смержен. - #3431 (sub-PR B: `deal_city_price_bands` по `(region_code, city)`, миграция 298, refresh per-region) — смержен, деплой success. На проде: 298 применена, PK `(region_code, city)`; bands региона 66 после re-seed и после штатного refresh-джоба (run 6468) **побайтно совпадают** со snapshot, снятым до правок (`deal_city_price_bands_bak_0908`, 383 строки); Москва получила строку tier=full: 34 221–718 870 ₽/м², n=212 937. Расписание `deal_city_price_bands_refresh` снова включено (было временно выключено, чтобы refresh 07 UTC не смешал Москву в floor малых городов области). - Геокод московских сделок: текущий геокодер жёстко ограничен Свердловской обл. (viewbox 66 + `bounded=1` + `state ~ 'свердловск'`, `known_city_hint('Москва') → None`, cache-ключ без региона) — без правки кода 213k строк либо None, либо ложный хит по одноимённой улице области. PR с регион-параметризацией геокодера (`geocode(..., region_code)`, `--region-code` у скрипта, `region_code` у `geocode-missing`) — на ревью. Всем 77-строкам превентивно проставлен `geocode_tried_at`, чтобы никакой нескоупленный геокод их не трогал; `cron-scrape.sh` на selectel не запланирован.
Author
Owner

Геокод сделок региона 77 — выполнен (2026-09-09 00:11–00:59 UTC, 48 мин).

  • scripts/geocode_deals_nominatim.py --region-code 77 (PR #3432): 2 797 улиц → 2 748 сведено, 49 не найдено; deals_updated 212 167. Регион 66 не тронут, точек вне bbox 77 — 0.
  • Пост-аудит по geocode_cache.full_address: 10 адресов (672 сделки) легли в центроид Москвы (мусорные улицы вида «Москва, 1-й», «411»), 31 адрес (3 030 сделок) — в центроид района («Тверской», «1-й Басманный»). Обнулены lat/lon (geocode_tried_at оставлен), 41 cache-строка удалена.
  • Итог: 208 465 / 212 937 (97,9 %) сделок 77 с уличной точностью, 2 579 уникальных точек.
  • Несведённые 770 сделок — почти все ТиНАО/посёлки (src_city: Троицк 136, Ясенево 87, Филимонковский 69, Десеновское 49, Коммунарка 46…) — нужен локалитет из raw_payload.src_city (sub-PR C).

Follow-ups кода: отбрасывать ответы Nominatim уровня city/suburb, когда просили улицу; хранить raw_payload ответа в geocode_cache; сверять address.road с запросом (пример: «11-я Парковая» → POI на «8-я Парковая», 144 сделки). Расписание rosreestr_dkp_import_77 (id 379) по-прежнему выключено — sub-PR B смержен, включать можно, но новые строки 77 никто не геокодирует автоматически (cron-scrape.sh на selectel не запланирован).

Подробности: vault events/Event_Moscow_Track2_Region_Import_Sep08.md.

**Геокод сделок региона 77 — выполнен (2026-09-09 00:11–00:59 UTC, 48 мин).** - `scripts/geocode_deals_nominatim.py --region-code 77` (PR #3432): 2 797 улиц → 2 748 сведено, 49 не найдено; `deals_updated` 212 167. Регион 66 не тронут, точек вне bbox 77 — 0. - Пост-аудит по `geocode_cache.full_address`: 10 адресов (672 сделки) легли в центроид Москвы (мусорные улицы вида «Москва, 1-й», «411»), 31 адрес (3 030 сделок) — в центроид района («Тверской», «1-й Басманный»). Обнулены `lat/lon` (`geocode_tried_at` оставлен), 41 cache-строка удалена. - Итог: **208 465 / 212 937 (97,9 %)** сделок 77 с уличной точностью, 2 579 уникальных точек. - Несведённые 770 сделок — почти все ТиНАО/посёлки (`src_city`: Троицк 136, Ясенево 87, Филимонковский 69, Десеновское 49, Коммунарка 46…) — нужен локалитет из `raw_payload.src_city` (sub-PR C). Follow-ups кода: отбрасывать ответы Nominatim уровня city/suburb, когда просили улицу; хранить `raw_payload` ответа в `geocode_cache`; сверять `address.road` с запросом (пример: «11-я Парковая» → POI на «8-я Парковая», 144 сделки). Расписание `rosreestr_dkp_import_77` (id 379) по-прежнему выключено — sub-PR B смержен, включать можно, но новые строки 77 никто не геокодирует автоматически (`cron-scrape.sh` на selectel не запланирован). Подробности: vault `events/Event_Moscow_Track2_Region_Import_Sep08.md`.
Sign in to join this conversation.
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#3051
No description provided.