feat(tradein/domklik): ЖК в свою колонку вместо только raw_payload (#3076)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m47s
Deploy Trade-In / deploy (push) Successful in 1m55s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
Deploy Trade-In / test (push) Successful in 3m46s
Deploy Trade-In / deploy-status (push) Successful in 1s
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m47s
Deploy Trade-In / deploy (push) Successful in 1m55s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
Deploy Trade-In / test (push) Successful in 3m46s
Deploy Trade-In / deploy-status (push) Successful in 1s
This commit is contained in:
parent
083b6bcdfe
commit
7c916082e8
2 changed files with 54 additions and 0 deletions
|
|
@ -90,6 +90,42 @@ def test_map_item_basic_mapping() -> None:
|
||||||
assert lot.lon == pytest.approx(60.612)
|
assert lot.lon == pytest.approx(60.612)
|
||||||
|
|
||||||
|
|
||||||
|
def test_map_item_puts_complex_slug_into_newbuilding_id() -> None:
|
||||||
|
"""flatComplex.slug доезжает до ScrapedLot.newbuilding_id (#3064).
|
||||||
|
|
||||||
|
Слаг, а не id: докстринг ScrapedLot задаёт формат «federatsiya-ekaterinburg»,
|
||||||
|
и avito — единственный источник, который это поле заполняет, кладёт туда слаг.
|
||||||
|
|
||||||
|
ЭТО НЕ привязка к дому. house_source/house_ext_id намеренно не трогаются:
|
||||||
|
все активные domklik-листинги — вторичка, а flatComplex — идентификатор ЖК,
|
||||||
|
а не здания (116 значений на 737 листингов по проду). Ключ здания
|
||||||
|
(domclick_building_guid) приходит detail-путём — отдельная развилка в #3064.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
fixture_path = Path(__file__).parent / "fixtures" / "domclick_bff_offers_sample.json"
|
||||||
|
items = json.loads(fixture_path.read_text(encoding="utf-8"))["result"]["items"]
|
||||||
|
|
||||||
|
config = SimpleNamespace(browser_http_endpoint="http://tradein-browser:9000")
|
||||||
|
scraper = DomClickScraper(config, delay_provider=lambda _name: 8.0)
|
||||||
|
|
||||||
|
# item 1001: flatComplex.slug='malysheva' -> слаг доезжает до колонки.
|
||||||
|
lot_with_complex = scraper._map_item(items[0])
|
||||||
|
assert lot_with_complex is not None
|
||||||
|
assert lot_with_complex.newbuilding_id == "malysheva"
|
||||||
|
# Привязка к дому НЕ появилась — это стережёт границу правки.
|
||||||
|
assert lot_with_complex.house_source is None
|
||||||
|
assert lot_with_complex.house_ext_id is None
|
||||||
|
|
||||||
|
# item 1002: flatComplex отсутствует -> None, а не пустая строка: пустая
|
||||||
|
# строка попала бы в колонку как значение и читалась бы как «ЖК есть, но без
|
||||||
|
# имени», что неотличимо от настоящего ЖК с пустым слагом.
|
||||||
|
lot_no_complex = scraper._map_item(items[1])
|
||||||
|
assert lot_no_complex is not None
|
||||||
|
assert lot_no_complex.newbuilding_id is None
|
||||||
|
|
||||||
|
|
||||||
def test_map_item_promotes_rosreestr_from_bff_fixture() -> None:
|
def test_map_item_promotes_rosreestr_from_bff_fixture() -> None:
|
||||||
"""isRosreestrApproved из BFF-фикстуры доезжает до
|
"""isRosreestrApproved из BFF-фикстуры доезжает до
|
||||||
ScrapedLot.is_rosreestr_checked (#3064 п.1).
|
ScrapedLot.is_rosreestr_checked (#3064 п.1).
|
||||||
|
|
|
||||||
|
|
@ -668,6 +668,23 @@ class DomClickScraper(BaseScraper):
|
||||||
is_rosreestr_checked: bool | None = item.get("isRosreestrApproved")
|
is_rosreestr_checked: bool | None = item.get("isRosreestrApproved")
|
||||||
|
|
||||||
flat_complex = item.get("flatComplex") or {}
|
flat_complex = item.get("flatComplex") or {}
|
||||||
|
# ── ЖК в свою колонку, а не только в raw_payload (#3064) ──────────
|
||||||
|
# newbuilding_id — слаг ЖК (докстринг ScrapedLot: e.g.
|
||||||
|
# "federatsiya-ekaterinburg"), поэтому берём slug, а НЕ id.
|
||||||
|
#
|
||||||
|
# ЭТО НЕ ПРИВЯЗКА К ДОМУ. house_source/house_ext_id намеренно НЕ
|
||||||
|
# трогаются: замер на проде (#3064) — все 1351 активных domklik-
|
||||||
|
# листингов ВТОРИЧКА, а flatComplex.id даёт 116 значений на 737
|
||||||
|
# листингов (~6.4 на ключ). Использовать его как house_ext_id значило
|
||||||
|
# бы схлопнуть разные здания одного ЖК в один «дом» и заставить якорь
|
||||||
|
# того же дома в оценщике сравнивать квартиры из разных корпусов.
|
||||||
|
# Правильный ключ здания — domclick_building_guid (467 значений на
|
||||||
|
# 619 листингов), но он приходит detail-путём, где match_or_create_house
|
||||||
|
# не вызывается. Развилка вынесена в issue, здесь — только захват ЖК.
|
||||||
|
#
|
||||||
|
# Риска нет: newbuilding_id бэкендом не читается нигде (проверено),
|
||||||
|
# в upsert защищён COALESCE, на проде заполнен только у avito.
|
||||||
|
newbuilding_id: str | None = (flat_complex.get("slug") or None) if flat_complex else None
|
||||||
raw_payload: dict[str, Any] = {
|
raw_payload: dict[str, Any] = {
|
||||||
"isRosreestrApproved": item.get("isRosreestrApproved"),
|
"isRosreestrApproved": item.get("isRosreestrApproved"),
|
||||||
"squarePrice": square_price_raw,
|
"squarePrice": square_price_raw,
|
||||||
|
|
@ -720,6 +737,7 @@ class DomClickScraper(BaseScraper):
|
||||||
description_minhash=description_minhash,
|
description_minhash=description_minhash,
|
||||||
agency_name=agency_name,
|
agency_name=agency_name,
|
||||||
is_rosreestr_checked=is_rosreestr_checked,
|
is_rosreestr_checked=is_rosreestr_checked,
|
||||||
|
newbuilding_id=newbuilding_id,
|
||||||
raw_payload=raw_payload,
|
raw_payload=raw_payload,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue