[tradein][cian] SERP: промоут полей из raw_payload в колонки — kitchen_area_m2, mortgage_available (+ новые is_apartments, is_rosreestr_checked) #2008

Closed
opened 2026-06-27 16:56:53 +00:00 by lekss361 · 3 comments
Owner

Из аудита #2011 (код + живой замер). Cian — самый богатый SERP (BFF-JSON ~137 полей), часть распарсенных полей оседает в raw_payload вместо колонок.

⚠️ Класс фиксов — честно

Estimator НЕ читает kitchen_area_m2 / mortgage_available / is_apartments / is_rosreestr_checked при отборе/скоринге аналогов. Поэтому промоут этих полей = для дашборда покрытия + matching + будущих фич (follow-up #2012 с backtest), НЕ valuation-фича сейчас.

ЕДИНСТВЕННЫЙ valuation-релевантный кусок здесь — нормализация cian house_type (DoD п.4, добавлено в этот PR как CLASS A бонус): cian хранит materialType сырым camelCase, из которого monolithBrick (1143 строки) не матчит канон monolith_brick в estimator soft-penalty → ложный штраф этим аналогам.

Прод-замер (active cian, 2026-06-27)

поле в raw_payload в колонке
kitchen_area_m2 99% 4%
mortgage_allowed 99% 0% (mortgage_available)
is_apartments 99% — (колонки нет)
is_rosreestr_checked 99% — (колонки нет)
house_type = monolithBrick (не канон) 1143 строки

Корни (file:line)

  • kitchenAreacian.py:807,978 — колонка kitchen_area_m2 есть, SERP пишет только в raw_payload.
  • mortgageAllowedcian.py:979 — колонка mortgage_available есть, NULL.
  • isApartments/flatTypecian.py:973-976 — колонки нет.
  • isRosreestrCheckedcian.py:986-987 — колонки нет.
  • house_typecian.py:815: materialType сырым (monolithBrick ≠ канон monolith_brick).

DoD

  • В _offer_to_lot мапить kitchenAreakitchen_area_m2, mortgageAllowedmortgage_available (колонки есть).
  • Добавить колонки is_apartments boolean, is_rosreestr_checked boolean миграцией 141_* (ADD COLUMN IF NOT EXISTS, идемпотентно, auto-apply strict; проверить коллизию basename — 139 занят blocked-PR #2005) + расширить ScrapedLot + save_listings.
  • CLASS A: прогнать cian materialType через тот же house_type_normalizer, что в #2007 (monolithBrickmonolith_brick, gasSilicateBlock/aerocreteBlockblock, stalinbrick) + backfill существующих cian-строк в той же миграции.
  • Замер до/после: kitchen_area_m2 cian 4% → ~95%; mortgage_available 0% → ~95%; house_type — доля канона.

⚠️ cian.py — hot file (#1949). Зависит от #2007 (общий base.py + house_type_normalizer) → делать ПОСЛЕ влития #2007 / rebase. scope/backend, scope/db, scrapers, tradein.

Из аудита #2011 (код + живой замер). Cian — самый богатый SERP (BFF-JSON ~137 полей), часть распарсенных полей оседает в `raw_payload` вместо колонок. ## ⚠️ Класс фиксов — честно Estimator **НЕ читает** `kitchen_area_m2` / `mortgage_available` / `is_apartments` / `is_rosreestr_checked` при отборе/скоринге аналогов. Поэтому промоут этих полей = **для дашборда покрытия + matching + будущих фич** (follow-up #2012 с backtest), НЕ valuation-фича сейчас. ЕДИНСТВЕННЫЙ valuation-релевантный кусок здесь — **нормализация cian house_type** (DoD п.4, добавлено в этот PR как CLASS A бонус): cian хранит `materialType` сырым camelCase, из которого `monolithBrick` (**1143 строки**) не матчит канон `monolith_brick` в estimator soft-penalty → ложный штраф этим аналогам. ## Прод-замер (active cian, 2026-06-27) | поле | в `raw_payload` | в колонке | |---|:--:|:--:| | `kitchen_area_m2` | 99% | 4% | | `mortgage_allowed` | 99% | 0% (`mortgage_available`) | | `is_apartments` | 99% | — (колонки нет) | | `is_rosreestr_checked` | 99% | — (колонки нет) | | `house_type` = `monolithBrick` (не канон) | — | 1143 строки | ## Корни (file:line) - `kitchenArea` → `cian.py:807,978` — колонка `kitchen_area_m2` есть, SERP пишет только в raw_payload. - `mortgageAllowed` → `cian.py:979` — колонка `mortgage_available` есть, NULL. - `isApartments`/`flatType` → `cian.py:973-976` — колонки нет. - `isRosreestrChecked` → `cian.py:986-987` — колонки нет. - `house_type` — `cian.py:815`: `materialType` сырым (`monolithBrick` ≠ канон `monolith_brick`). ## DoD - В `_offer_to_lot` мапить `kitchenArea` → `kitchen_area_m2`, `mortgageAllowed` → `mortgage_available` (колонки есть). - Добавить колонки `is_apartments boolean`, `is_rosreestr_checked boolean` миграцией `141_*` (`ADD COLUMN IF NOT EXISTS`, идемпотентно, auto-apply strict; проверить коллизию basename — 139 занят blocked-PR #2005) + расширить `ScrapedLot` + `save_listings`. - **CLASS A:** прогнать cian `materialType` через тот же `house_type_normalizer`, что в #2007 (`monolithBrick`→`monolith_brick`, `gasSilicateBlock`/`aerocreteBlock`→`block`, `stalin`→`brick`) + **backfill** существующих cian-строк в той же миграции. - Замер до/после: `kitchen_area_m2` cian 4% → ~95%; `mortgage_available` 0% → ~95%; house_type — доля канона. ⚠️ `cian.py` — hot file (#1949). **Зависит от #2007** (общий `base.py` + `house_type_normalizer`) → делать ПОСЛЕ влития #2007 / rebase. scope/backend, scope/db, scrapers, tradein.
lekss361 added the
priority/p1
scope/backend
scope/db
scrapers
status/ready
tradein
labels 2026-06-27 16:58:05 +00:00
Author
Owner

Working on this in PR #2017 (если номер иной — см. открытый PR ветки feat/tradein-2008-cian-promote-house-type). code-reviewer APPROVE. Включает миграцию 141 (новые колонки is_apartments/is_rosreestr_checked + backfill cian house_type ~1208 строк) + нормализацию на ингесте через тот же house_type_normalizer, что в #2007.

Working on this in PR #2017 (если номер иной — см. открытый PR ветки `feat/tradein-2008-cian-promote-house-type`). code-reviewer ✅ APPROVE. Включает миграцию 141 (новые колонки is_apartments/is_rosreestr_checked + backfill cian house_type ~1208 строк) + нормализацию на ингесте через тот же house_type_normalizer, что в #2007.
Author
Owner

PR #2017 merged + deploy success; миграция 141 применена (в _schema_migrations).

cian house_type (CLASS A фикс) — ДО/ПОСЛЕ (прод, source='cian' active)

ДО ПОСЛЕ (миграция 141)
monolithBrickmonolith_brick 1143 1143 monolith_brick
gasSilicateBlock+aerocreteBlockblock 47+5 block 551→603
stalinbrick 13 brick 2135→2148

camelCase: 0 осталось — cian house_type теперь 100% канон → ~1208 cian-аналогов больше не получают ложный штраф в estimator soft-penalty.

CLASS B promote — растёт по новым скрейпам

Колонки is_apartments/is_rosreestr_checked созданы (миграция 141, проверено). Fill сейчас 0 / kitchen 4% / mortgage 0% — новых cian-скрейпов после деплоя ещё не было (cian SERP gated camoufox+мобильный прокси, #1949). Поднимутся по мере прогона. Дашборд/матчинг, не valuation (#2012).

✅ PR #2017 merged + deploy success; миграция `141` применена (в `_schema_migrations`). ## cian house_type (CLASS A фикс) — ДО/ПОСЛЕ (прод, `source='cian'` active) | | ДО | ПОСЛЕ (миграция 141) | |---|--:|--:| | `monolithBrick` → `monolith_brick` | 1143 | **1143 monolith_brick** ✓ | | `gasSilicateBlock`+`aerocreteBlock` → `block` | 47+5 | **block 551→603** ✓ | | `stalin` → `brick` | 13 | **brick 2135→2148** ✓ | **camelCase: 0 осталось** — cian `house_type` теперь 100% канон → ~1208 cian-аналогов больше не получают ложный штраф в estimator soft-penalty. ## CLASS B promote — растёт по новым скрейпам Колонки `is_apartments`/`is_rosreestr_checked` созданы (миграция 141, проверено). Fill сейчас 0 / kitchen 4% / mortgage 0% — новых cian-скрейпов после деплоя ещё не было (cian SERP gated camoufox+мобильный прокси, #1949). Поднимутся по мере прогона. Дашборд/матчинг, не valuation (#2012).
Author
Owner

Перепроверил живьём — issue уже полностью закрыт PR #2017 (коммиты c5227a16/2e44f482, 2026-06-27). Подтверждено grep'ом по cian.py: kitchen_area_m2/mortgage_available/is_apartments/is_rosreestr_checked промоучены в колонки, house_type идёт через shared house_type_normalizer (Class A бонус), миграция 141_cian_promote_house_type.sql на месте (basename-коллизии с занятым 139 нет). Зависимость от #2007 (shared normalizer) соблюдена — normalizer уже содержал cian-вокабуляр на момент этого PR.

Закрываю.

Перепроверил живьём — issue уже полностью закрыт PR #2017 (коммиты `c5227a16`/`2e44f482`, 2026-06-27). Подтверждено grep'ом по `cian.py`: `kitchen_area_m2`/`mortgage_available`/`is_apartments`/`is_rosreestr_checked` промоучены в колонки, `house_type` идёт через shared `house_type_normalizer` (Class A бонус), миграция `141_cian_promote_house_type.sql` на месте (basename-коллизии с занятым 139 нет). Зависимость от #2007 (shared normalizer) соблюдена — normalizer уже содержал cian-вокабуляр на момент этого PR. Закрываю.
Sign in to join this conversation.
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#2008
No description provided.