diff --git a/tradein-mvp/backend/app/services/scrapers/avito_imv.py b/tradein-mvp/backend/app/services/scrapers/avito_imv.py index bd9b8aa6..3113b89d 100644 --- a/tradein-mvp/backend/app/services/scrapers/avito_imv.py +++ b/tradein-mvp/backend/app/services/scrapers/avito_imv.py @@ -334,6 +334,8 @@ def _raise_for_status_categorized(resp: Any, context: str) -> None: if status >= 500: raise IMVTransientError(f"Avito {context}: HTTP {status} — transient server error") if status >= 400: + body_preview = (resp.text or "")[:200] + logger.warning("Avito %s HTTP %d: body=%r", context, status, body_preview) resp.raise_for_status() # other 4xx → standard HTTPStatusError diff --git a/tradein-mvp/scripts/backfill-house-imv.py b/tradein-mvp/scripts/backfill-house-imv.py index 3b58658f..48b8a38b 100644 --- a/tradein-mvp/scripts/backfill-house-imv.py +++ b/tradein-mvp/scripts/backfill-house-imv.py @@ -51,6 +51,25 @@ logging.basicConfig( ) logger = logging.getLogger("phase-c") +# Avito IMV API accepts only these house_type values (verified 2026-05-24). +# Our `listings.house_type` may contain pre-2026 values like 'monolith' / 'monolith_brick'. +_HOUSE_TYPE_TO_IMV = { + "panel": "panel", + "brick": "brick", + "monolith": "monolithic", # API renamed; raw value rejected with 400 + "monolithic": "monolithic", + "monolith_brick": "monolithic", # API doesn't accept hybrid → fall back to monolithic + "block": "block", + "wood": "wood", +} +_HOUSE_TYPE_DEFAULT = "panel" # most common in EKB; safe default for unknown + + +def _map_house_type(raw: str | None) -> str: + if not raw: + return _HOUSE_TYPE_DEFAULT + return _HOUSE_TYPE_TO_IMV.get(raw.lower().strip(), _HOUSE_TYPE_DEFAULT) + DATABASE_URL = os.environ.get("DATABASE_URL") if not DATABASE_URL: raise SystemExit( @@ -92,12 +111,8 @@ def pick_lot_params(db: Session, house_id: int) -> dict: "rooms": int(row["rooms"]), "area_m2": float(row["area_m2"]), "floor": int(row["floor"] or 1), - "floor_at_home": int( - row["total_floors"] or (house and house["total_floors"]) or 9 - ), - "house_type": ( - row["house_type"] or (house and house["house_type"]) or "panel" - ), + "floor_at_home": int(row["total_floors"] or (house and house["total_floors"]) or 9), + "house_type": _map_house_type(row["house_type"] or (house and house["house_type"])), "renovation_type": "cosmetic", "has_balcony": True, "has_loggia": False,