gendesign/backend/app/api/v1
Light1YT 2a68c2e202
Some checks failed
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Successful in 8s
Deploy / build-backend (push) Has been cancelled
Deploy / build-worker (push) Has been cancelled
fix(parcels): guard NULL geom + None lat/lon в isochrones/poi-score (#1201)
`cad_parcels_geom` — VIEW над `cad_parcels` где `geom` nullable (~964 prod-
строк с NULL geom задокументировано в analyze:1504-1507). Без фильтра
`geom IS NOT NULL` в UNION-ветках:
- NULL-строка из ранней ветки (`cad_quarters_geom`) ПЕРЕКРЫВАЕТ валидную
  геометрию из поздней (`cad_parcels_geom`) — LIMIT 1 берёт первую попавшуюся.
- ST_Centroid(NULL) → NULL → coord_row.lat = NULL → float(None) → TypeError
  → 500 (вместо честного 404).

Guard `if not coord_row` НЕ ловил эту дыру: RowMapping с None-полями
truthy. Зеркало паттерна из analyze (parcels.py:1418-1438) для обоих
эндпоинтов (`/isochrones` + `/poi-score`):
1. `AND geom IS NOT NULL` во ВСЕХ ветках UNION.
2. Belt-and-suspenders: явная проверка `coord_row.get("lat") is None`
   на случай топологически битого polygon'а (NOT-NULL geom, NULL centroid).

26 analyze/isochrones/poi-score юнит-тестов зелёные. ruff clean.

Closes #1201
2026-06-13 05:24:25 +00:00
..
__init__.py init 2026-04-25 13:45:19 +03:00
admin_cadastre.py refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
admin_etl.py refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
admin_jobs.py refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
admin_leads.py refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
admin_scrape.py feat(sf): cross-load ETL tradein→gendesign newbuilding_listings — вариант A (#976) 2026-06-12 11:18:47 +03:00
admin_weight_profiles.py refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
analytics.py feat(recommend): horizon-aware recommend_mix opt-in overlay (#982, 953-A) (#1014) 2026-06-03 07:40:33 +00:00
chat.py feat(chat): LLM tool-loop + §19 redaction wiring for #957 (Step 2+3) 2026-06-08 17:45:01 +05:00
concepts.py init 2026-04-25 13:45:19 +03:00
custom_pois.py feat(#254): user_custom_pois — backend schema + CRUD + scoring integration 2026-05-17 09:34:33 +03:00
insights.py feat(insights): manual-entry Insight entity CRUD + §19 audit (#948 part A) 2026-06-08 12:41:39 +05:00
landing.py feat(sf-fe-a12): Landing redesign + PilotCTA с real B3/B4 data (v2 rebased) (#367) 2026-05-18 05:16:57 +00:00
locations.py feat(location): district-level Location entity + indices (#948 part B) 2026-06-08 13:28:19 +05:00
me.py feat(rbac): role-based access control via X-Authenticated-User middleware (#585) 2026-05-26 06:18:40 +00:00
own_projects.py feat(site-finder): own-portfolio data source for §25.3 cannibalization (#1169 PR1) 2026-06-08 16:21:53 +05:00
parcels.py fix(parcels): guard NULL geom + None lat/lon в isochrones/poi-score (#1201) 2026-06-13 05:24:25 +00:00
photos.py fix ui 2026-04-27 20:42:18 +03:00
pilot.py fix(pilot): drop pydantic EmailStr — email-validator dep missing → backend startup crash (#337) 2026-05-17 21:32:23 +00:00
ping.py feat(backend): add /api/v1/ping liveness endpoint (#634) 2026-05-29 15:53:29 +00:00
trade_in.py feat(trade-in): TI-2 PDF export 4-page + frontend enable button (#319) 2026-05-17 17:16:48 +00:00
users.py feat(sf-b2): GET /users/me/recent-parcels — stub endpoint (auth TODO) (#329) 2026-05-17 21:04:16 +00:00