(medium) PoiList2Gis/site-finder-api: «{totalScore}/100» может превышать 100 и в fallback показывает не POI-метрику #1470

Closed
opened 2026-06-15 05:56:51 +00:00 by bot-backend · 1 comment
Collaborator

Severity: medium · Категория: report · Файл: frontend/src/components/site-finder/analysis/PoiList2Gis.tsx:125-135

PoiList2Gis.tsx:125-135 рендерит «{totalScore.toFixed(0)} / 100». Корень — адаптер site-finder-api.ts:556-568: score_contribution = Math.round(p.weight100) для КАЖДОГО top_poi, и poi_weighted_score = сумма этих contributions без ограничения 100. Фикстура mocks/poi-score.json опровергает семантику адаптера: weight 0.25 → score_contribution 22 (не 25), сумма contributions нормирована (poi_weighted_score 76). При достаточном числе POI сумма round(weight100) легко превысит 100 → «137 / 100». Кроме того, fallback-ветка Section1ParcelInfo.tsx:303-314 передаёт в totalScore значение data.score (балл участка 0..100, тип number из ParcelAnalyze) — т.е. под подписью «POI · 2ГИС/OSM … X / 100» показывается совсем другая метрика (балл участка, а не POI-скор). Импакт: бессмысленное «>100/100» либо подмена метрики в клиентской карточке Section 1. Как чинить: брать нормированный score_contribution из backend (а не derive round(weight*100)) либо клампить/пересчитывать poi_weighted_score в 0..100; в fallback не подставлять data.score под POI-подпись.

Почему баг: Мок-фикстура poi-score.json подтверждает иную семантику: weight 0.25 → score_contribution 22 (а не 25), сумма contributions ≈ poi_weighted_score 76. То есть score_contribution — нормированный вклад в 0..100, а адаптер ошибочно приравнял его к round(weight*100), из-за чего сумма не ограничена 100. Компонент слепо делит на 100, давая бессмысленное «>100 / 100» в клиентской карточке Section 1.

Как чинить: Клампить отображение (Math.min(100, totalScore)) ИЛИ убрать «/ 100», если метрика не нормирована; в адаптере (site-finder-api.ts) перестать выводить score_contribution=round(weight*100) и нормировать вклад так, чтобы сумма по показываемым POI была ≤100, согласовав с фикстурой.


deep-audit «армия ботов 2» · verify+harden, confidence 0.82 · unit U100

**Severity:** medium · **Категория:** report · **Файл:** `frontend/src/components/site-finder/analysis/PoiList2Gis.tsx:125-135` PoiList2Gis.tsx:125-135 рендерит «{totalScore.toFixed(0)} / 100». Корень — адаптер site-finder-api.ts:556-568: score_contribution = Math.round(p.weight*100) для КАЖДОГО top_poi, и poi_weighted_score = сумма этих contributions без ограничения 100. Фикстура mocks/poi-score.json опровергает семантику адаптера: weight 0.25 → score_contribution 22 (не 25), сумма contributions нормирована (poi_weighted_score 76). При достаточном числе POI сумма round(weight*100) легко превысит 100 → «137 / 100». Кроме того, fallback-ветка Section1ParcelInfo.tsx:303-314 передаёт в totalScore значение data.score (балл участка 0..100, тип number из ParcelAnalyze) — т.е. под подписью «POI · 2ГИС/OSM … X / 100» показывается совсем другая метрика (балл участка, а не POI-скор). Импакт: бессмысленное «>100/100» либо подмена метрики в клиентской карточке Section 1. Как чинить: брать нормированный score_contribution из backend (а не derive round(weight*100)) либо клампить/пересчитывать poi_weighted_score в 0..100; в fallback не подставлять data.score под POI-подпись. **Почему баг:** Мок-фикстура poi-score.json подтверждает иную семантику: weight 0.25 → score_contribution 22 (а не 25), сумма contributions ≈ poi_weighted_score 76. То есть score_contribution — нормированный вклад в 0..100, а адаптер ошибочно приравнял его к round(weight*100), из-за чего сумма не ограничена 100. Компонент слепо делит на 100, давая бессмысленное «>100 / 100» в клиентской карточке Section 1. **Как чинить:** Клампить отображение (Math.min(100, totalScore)) ИЛИ убрать «/ 100», если метрика не нормирована; в адаптере (site-finder-api.ts) перестать выводить score_contribution=round(weight*100) и нормировать вклад так, чтобы сумма по показываемым POI была ≤100, согласовав с фикстурой. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.82 · unit U100</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:56:52 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:02:09 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода: Рендер — frontend/src/components/site-finder/analysis/PoiList2Gis.tsx:133 ({totalScore.toFixed(0)} / 100 под шапкой «POI · 2ГИС / OSM» :123). Адаптер сместился: сейчас frontend/src/lib/site-finder-api.ts:536-543 (строки 556-568 из тела заняты chat-контрактом). Fallback-ветка — Section1ParcelInfo.tsx:285-299 (totalScore={data.score}).

Корень: Адаптер деривит score_contribution: Math.round(p.weight * 100) для каждого top_poi (site-finder-api.ts:537, комментарий стр.536 «not in backend response — derive from weight») и суммирует их в poi_weighted_score без клампа (стр.539-541 items.reduce((s,p)=>s+p.score_contribution, 0)). При достаточном числе POI сумма round(weight*100) превышает 100 → компонент показывает «>100 / 100». Дополнительно fallback в Section 1 (Section1ParcelInfo.tsx:298) подставляет data.score (инвест-балл участка 0..100) под POI-подпись — другая метрика.

Что править:

  • В адаптере (site-finder-api.ts:533-543) не приравнивать score_contribution к round(weight*100); брать нормированный вклад из backend или пересчитывать так, чтобы сумма по показываемым POI была ≤100 (фикстура mocks/poi-score.json: weight 0.25 → contribution 22, сумма 76 — подтверждает нормировку).
  • В PoiList2Gis.tsx:133 как минимум клампить Math.min(100, totalScore) либо убрать «/ 100» если метрика ненормирована.
  • Fallback Section 1 (data.score под POI-метку) пересекается с #1466 — чинить там.

Что посмотреть:

  • Код: site-finder-api.ts:533-543, PoiList2Gis.tsx:113-134, Section1ParcelInfo.tsx:285-299, фикстура frontend/src/mocks/poi-score.json (если есть).
  • Vault: релевантных заметок не найдено.
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** Рендер — `frontend/src/components/site-finder/analysis/PoiList2Gis.tsx:133` (`{totalScore.toFixed(0)} / 100` под шапкой «POI · 2ГИС / OSM» `:123`). Адаптер сместился: сейчас `frontend/src/lib/site-finder-api.ts:536-543` (строки 556-568 из тела заняты chat-контрактом). Fallback-ветка — `Section1ParcelInfo.tsx:285-299` (`totalScore={data.score}`). **Корень:** Адаптер деривит `score_contribution: Math.round(p.weight * 100)` для каждого top_poi (`site-finder-api.ts:537`, комментарий стр.536 «not in backend response — derive from weight») и суммирует их в `poi_weighted_score` **без клампа** (стр.539-541 `items.reduce((s,p)=>s+p.score_contribution, 0)`). При достаточном числе POI сумма `round(weight*100)` превышает 100 → компонент показывает «>100 / 100». Дополнительно fallback в Section 1 (`Section1ParcelInfo.tsx:298`) подставляет `data.score` (инвест-балл участка 0..100) под POI-подпись — другая метрика. **Что править:** - В адаптере (`site-finder-api.ts:533-543`) не приравнивать `score_contribution` к `round(weight*100)`; брать нормированный вклад из backend или пересчитывать так, чтобы сумма по показываемым POI была ≤100 (фикстура `mocks/poi-score.json`: weight 0.25 → contribution 22, сумма 76 — подтверждает нормировку). - В `PoiList2Gis.tsx:133` как минимум клампить `Math.min(100, totalScore)` либо убрать «/ 100» если метрика ненормирована. - Fallback Section 1 (`data.score` под POI-метку) пересекается с #1466 — чинить там. **Что посмотреть:** - Код: `site-finder-api.ts:533-543`, `PoiList2Gis.tsx:113-134`, `Section1ParcelInfo.tsx:285-299`, фикстура `frontend/src/mocks/poi-score.json` (если есть). - Vault: релевантных заметок не найдено.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1470
No description provided.