From ec681441e5cbc6b872310d8eba4e5294f00cf231 Mon Sep 17 00:00:00 2001 From: lekss361 Date: Tue, 12 May 2026 01:14:29 +0300 Subject: [PATCH] =?UTF-8?q?fix(site-finder):=20unique=20factor=20key=20(X1?= =?UTF-8?q?=20#47)=20=E2=80=94=20prevent=20React=20collision?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #87 auto-review нашёл: два POI одной категории на одинаковом округлённом расстоянии (например two аптеки 450м в плотном районе центра ЕКБ) давали duplicate factor key "pharmacy_450m" → silent React reconciliation errors. Fix: добавил enumerate index в slug: f"{cat}_{round(distance_m)}m_{idx}". 1 строка, backward compat (factor — opaque slug, не парсится клиентом). Per auto-review on 97dc4ba. --- backend/app/api/v1/parcels.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/app/api/v1/parcels.py b/backend/app/api/v1/parcels.py index b2b73422..9f8e7029 100644 --- a/backend/app/api/v1/parcels.py +++ b/backend/app/api/v1/parcels.py @@ -802,7 +802,7 @@ def analyze_parcel( by_category: dict[str, list[dict[str, Any]]] = {} # X1 (#47): per-POI breakdown с verbal explain для UI factors_detailed: list[dict[str, Any]] = [] - for p in poi_rows: + for idx, p in enumerate(poi_rows): cat: str = p["category"] w = _POI_WEIGHTS.get(cat, 0.0) # distance decay: 1.0 на 0м, 0.5 на ~500м, ~0 на 1000м @@ -826,7 +826,10 @@ def analyze_parcel( continue factors_detailed.append( { - "factor": f"{cat}_{round(distance_m)}m", + # Include idx чтобы избежать React key collision: два POI одной + # категории на одинаково округлённом расстоянии иначе дали бы + # дубль (например, two аптеки 450м в плотном районе). + "factor": f"{cat}_{round(distance_m)}m_{idx}", "category": cat, "category_ru": _POI_CATEGORY_RU.get(cat, cat), "group": _POI_GROUP.get(cat, "Прочее"),