fix(tradein-phase-c): prepend region prefix for IMV geocoder (#540)
All checks were successful
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 32s
Deploy Trade-In / changes (push) Successful in 5s

This commit is contained in:
lekss361 2026-05-24 15:39:56 +00:00
parent 490bc8ca5d
commit 5b1fb6633f

View file

@ -70,6 +70,46 @@ def _map_house_type(raw: str | None) -> str:
return _HOUSE_TYPE_DEFAULT
return _HOUSE_TYPE_TO_IMV.get(raw.lower().strip(), _HOUSE_TYPE_DEFAULT)
# Bounding boxes for known regions in our DB.
# When house.lat/lon falls inside one, we prepend the region name to address
# before sending to Avito (resolves ambiguity — e.g. "Орджоникидзевский район" exists
# in EKB AND in Khakasia republic).
_REGION_BBOX = [
# (region_name, lat_min, lat_max, lon_min, lon_max)
("Свердловская область, Екатеринбург", 56.5, 57.1, 59.9, 61.0),
("Свердловская область", 56.0, 61.0, 58.0, 65.0), # rest of region
("Кировская область, Киров", 58.4, 58.8, 49.4, 49.9),
("Ставропольский край, Ставрополь", 44.9, 45.2, 41.7, 42.2),
("Тюменская область, Тюмень", 57.0, 57.3, 65.3, 65.8),
("Челябинская область, Челябинск", 55.0, 55.4, 61.2, 61.7),
]
_REGION_DEFAULT = "Свердловская область, Екатеринбург" # bulk of our data is EKB
def _detect_region_prefix(lat: float | None, lon: float | None) -> str:
if lat is None or lon is None:
return _REGION_DEFAULT
for name, lat_min, lat_max, lon_min, lon_max in _REGION_BBOX:
if lat_min <= lat <= lat_max and lon_min <= lon <= lon_max:
return name
return _REGION_DEFAULT
def _enrich_address_for_imv(raw: str, lat: float | None, lon: float | None) -> str:
"""Prepend region prefix if address lacks one (ambiguity fix for Avito geocoder)."""
addr = (raw or "").strip()
# Already has region marker? skip
addr_lower = addr.lower()
if any(
m in addr_lower
for m in ("область,", " обл.,", " обл,", "край,", "респ.,", "республика,")
):
return addr
prefix = _detect_region_prefix(lat, lon)
return f"{prefix}, {addr}"
DATABASE_URL = os.environ.get("DATABASE_URL")
if not DATABASE_URL:
raise SystemExit(
@ -317,8 +357,14 @@ async def process_one(db: Session, house: dict) -> str:
mark_status(db, house["id"], "no_address", "house.address is NULL")
return "no_address"
# Enrich with region prefix to prevent Avito geocoder mis-resolving ambiguous
# street names to wrong regions (e.g. "улица Победы" exists in EKB and Khakasia).
enriched = _enrich_address_for_imv(address, house.get("lat"), house.get("lon"))
if enriched != address:
logger.debug("enriched address house=%d %r -> %r", house["id"], address, enriched)
try:
result = await evaluate_via_imv(address=address, **params)
result = await evaluate_via_imv(address=enriched, **params)
except IMVAddressNotFoundError as e:
mark_status(db, house["id"], "not_found", str(e)[:200])
return "not_found"