Backend (parcels.py):
- _parse_floors() helper для TEXT column (cad_buildings.floors хранится как
строка, могут быть диапазоны "5-7"). Возвращает верхнюю границу.
- _neighbors_summary(db, geom_wkt, our_cad) — query соседей в 100м (GIST):
cad_num, building_name, floors, year_built, cost_value, area, address, distance.
Aggregate: avg_floors_100m, max_floors_100m, median_cost_per_m2_100m,
count_buildings_100m. Outliers cost/m² фильтруются (1k < x < 500k).
- Overlap check: ST_Intersects + ST_Area(ST_Intersection) > 50 m² (transformed
to UTM 32641 для метров). Если есть → has_existing_buildings: true +
overlap_buildings list.
- В response → neighbors_summary.
Frontend:
- Новый NeighborsBlock.tsx: hard red warn block для overlap (с building names +
overlap_m2 + "Инвестиции невозможны без сноса"); summary metrics (avg/max
floors, median price); toggle "Показать N ближайших" → таблица.
- Border меняется на красный при has_existing_buildings — visual cue.
- Добавлен в LandTab выше "Зонирование (ПЗЗ)".
- TS типы: NeighborBuilding, OverlapBuilding, NeighborsSummary.
Closes#46. Closes#21 (cad_buildings в Site Finder фильтрах).