fix(parcels): _parse_floors handle int (post-migration #169 schema change)

After PR #169 cad_buildings schema migration, `floors` column is INT
(was TEXT in legacy schema). Existing `_parse_floors(r.get("floors"))`
call in analyze_parcel → _neighbors_summary crashes with:
  AttributeError: 'int' object has no attribute 'strip'

Fix: type union str | int | None. If int → return directly (no strip).
Preserve TEXT range parsing ("5-7" → 7) for backwards-compat with
any legacy data still in cad_buildings_old_apr26.
This commit is contained in:
lekss361 2026-05-15 14:50:22 +03:00
parent 8dee9546ae
commit 9197a539e9

View file

@ -639,16 +639,23 @@ _COST_PER_M2_MIN = 1000 # ₽/м² — ниже скорее всего оши
_COST_PER_M2_MAX = 500_000 # ₽/м² — выше скорее всего outlier
def _parse_floors(raw: str | None) -> int | None:
"""cad_buildings.floors хранится TEXT (могут быть диапазоны '1-2', '5-7').
def _parse_floors(raw: str | int | None) -> int | None:
"""cad_buildings.floors — после schema migration #169 теперь INT,
но historically мог быть TEXT с диапазоном '5-7'. Поддерживаем оба
для backwards-compat с legacy data + tests.
Возвращаем верхнюю границу (более консервативный сосед-высотка).
NB: `isdigit()` намеренно фильтрует malformed parts типа "5а-7"; для
multi-range "1-2-3" возвращается max(1,2,3)=3 (acceptable degradation).
"""
if raw is None or raw == "":
return None
# Post-migration: INT column → fast path
if isinstance(raw, int):
return raw if raw > 0 else None
raw = raw.strip()
if not raw:
return None
raw = raw.strip()
# range like "5-7" → 7
if "-" in raw:
parts = raw.split("-")