fix(site-finder): попап конкурента — NUMERIC-поля приходят строкой (цена/площадь не рендерились) #2114

Merged
bot-backend merged 1 commit from fix/competitor-popup-numeric-strings into main 2026-06-30 14:01:01 +00:00
Collaborator

Баг (найден прод-верификацией #2113)

Прямая проверка живого /analyze показала: avg_price_per_m2_rub и avg_area_pd приходят с бэкенда строкой («160345», «47.5»), потому что Pydantic v2 сериализует Decimal (из ROUND(…::numeric)) в JSON-строку. Гварды в попапе конкурента typeof === "number" / Number.isFinite(строка) → false, поэтому:

  • цена конкурента вообще не показывалась (pre-existing, formatPrice);
  • добавленная в #2113 «Ср. площадь кв.» не рендерилась.

(units_sold/units_available/lots_with_price/distance_m/flat_count — int/float → числа, не задеты.)

Фикс (frontend-only, контракт не меняется)

  • toFiniteNumber(v: number | string | null)number | null (coerce + finite-check).
  • formatPrice использует его → цена снова показывается.
  • avg_area_pd рендерится через toFiniteNumber.
  • Типы avg_price_per_m2_rub / avg_area_pd расширены до number | string | null — честно отражает рантайм Decimal-сериализации.

tsc/eslint/prettier . После deploy — прод-verify попапа конкурента (Застройщик + цена + Ср. площадь кв.).

## Баг (найден прод-верификацией #2113) Прямая проверка живого `/analyze` показала: `avg_price_per_m2_rub` и `avg_area_pd` приходят с бэкенда **строкой** («160345», «47.5»), потому что Pydantic v2 сериализует `Decimal` (из `ROUND(…::numeric)`) в JSON-строку. Гварды в попапе конкурента `typeof === "number"` / `Number.isFinite(строка)` → false, поэтому: - **цена конкурента вообще не показывалась** (pre-existing, `formatPrice`); - добавленная в [#2113](https://git.gendsgn.ru/lekss361/gendesign/pulls/2113) «Ср. площадь кв.» **не рендерилась**. (units_sold/units_available/lots_with_price/distance_m/flat_count — int/float → числа, не задеты.) ## Фикс (frontend-only, контракт не меняется) - `toFiniteNumber(v: number | string | null)` → `number | null` (coerce + finite-check). - `formatPrice` использует его → цена снова показывается. - `avg_area_pd` рендерится через `toFiniteNumber`. - Типы `avg_price_per_m2_rub` / `avg_area_pd` расширены до `number | string | null` — честно отражает рантайм Decimal-сериализации. `tsc`/eslint/prettier ✅. После deploy — прод-verify попапа конкурента (Застройщик + цена + Ср. площадь кв.).
bot-backend added 1 commit 2026-06-30 13:58:07 +00:00
fix(site-finder): попап конкурента — NUMERIC-поля приходят строкой, рендерим цену и площадь
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m5s
CI / openapi-codegen-check (pull_request) Successful in 2m3s
9d75ca4874
Прод-verify #2113 вскрыл: avg_price_per_m2_rub и avg_area_pd приходят с бэкенда
СТРОКОЙ («160345», «47.5») — Pydantic v2 сериализует Decimal (ROUND(::numeric))
в строку. Гварды `typeof === "number"` / `Number.isFinite(str)` молча роняли поля:
цена конкурента вообще не показывалась, а добавленная в #2113 «Ср. площадь кв.»
не рендерилась.

- toFiniteNumber(v) — приводит number|string→number|null.
- formatPrice использует его (цена снова показывается).
- avg_area_pd рендерится через toFiniteNumber.
- Типы avg_price_per_m2_rub/avg_area_pd расширены до number|string|null (честно
  отражает рантайм).

Frontend-only, контракт не меняется.
bot-backend merged commit 663f04b777 into main 2026-06-30 14:01:01 +00:00
bot-backend deleted branch fix/competitor-popup-numeric-strings 2026-06-30 14:01:01 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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#2114
No description provided.