(medium) AnalogsTable.tsx сортировка по 'Дней': days_on_market=null трактуется как 0, пустые всплывают как самые свежие #1479

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

Severity: medium · Категория: frontend · Файл: frontend/src/components/trade-in/AnalogsTable.tsx:66-72

AnalogsTable.tsx:66-72 компаратор const av = a[sortKey] ?? 0; const bv = b[sortKey] ?? 0;. Поле days_on_market по типу number | null (frontend/src/types/trade-in.ts:36) и рендерится как '—' при null (строка 274). При сортировке по столбцу 'Дней' (sortKey='days_on_market') все строки с null получают 0 и при ASC поднимаются в самый верх, выглядя как объекты с минимальной экспозицией (0 дней / самые свежие/ликвидные), а при DESC уходят вниз. Импакт: искажённый порядок и восприятие ликвидности выборки в клиентской таблице; 'неизвестно' смешано с 'ноль дней'. price_rub/price_per_m2 не страдают (по типу number без null). Фикс: при сортировке по nullable-полю выносить null в конец независимо от направления (например, сравнивать с учётом null: null всегда после непустых), а не подставлять 0.

Почему баг: ?? 0 смешивает 'неизвестно' с 'ноль дней на рынке'. В клиентской таблице это даёт неверный порядок: лоты без данных о сроке экспозиции показываются как самые ликвидные/свежие при ASC и исчезают вниз при DESC, искажая восприятие выборки. Цена/цена-за-м² не страдают (там number без null по типу), но столбец days_on_market — реально nullable.

Как чинить: Для days_on_market при сортировке выносить null в конец независимо от направления (например, заменять на +Infinity при ASC и -Infinity при DESC, или фильтровать null в стабильный хвост), а не подменять на 0.


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

**Severity:** medium · **Категория:** frontend · **Файл:** `frontend/src/components/trade-in/AnalogsTable.tsx:66-72` AnalogsTable.tsx:66-72 компаратор `const av = a[sortKey] ?? 0; const bv = b[sortKey] ?? 0;`. Поле days_on_market по типу `number | null` (frontend/src/types/trade-in.ts:36) и рендерится как '—' при null (строка 274). При сортировке по столбцу 'Дней' (sortKey='days_on_market') все строки с null получают 0 и при ASC поднимаются в самый верх, выглядя как объекты с минимальной экспозицией (0 дней / самые свежие/ликвидные), а при DESC уходят вниз. Импакт: искажённый порядок и восприятие ликвидности выборки в клиентской таблице; 'неизвестно' смешано с 'ноль дней'. price_rub/price_per_m2 не страдают (по типу number без null). Фикс: при сортировке по nullable-полю выносить null в конец независимо от направления (например, сравнивать с учётом null: null всегда после непустых), а не подставлять 0. **Почему баг:** `?? 0` смешивает 'неизвестно' с 'ноль дней на рынке'. В клиентской таблице это даёт неверный порядок: лоты без данных о сроке экспозиции показываются как самые ликвидные/свежие при ASC и исчезают вниз при DESC, искажая восприятие выборки. Цена/цена-за-м² не страдают (там number без null по типу), но столбец days_on_market — реально nullable. **Как чинить:** Для days_on_market при сортировке выносить null в конец независимо от направления (например, заменять на +Infinity при ASC и -Infinity при DESC, или фильтровать null в стабильный хвост), а не подменять на 0. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.92 · unit U103</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:57:43 +00:00
bot-backend added the
scope/frontend
label 2026-06-15 11:02:11 +00:00
Owner

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

Текущее состояние кода: frontend/src/components/trade-in/AnalogsTable.tsx:66-72 (компаратор const av = a[sortKey] ?? 0; const bv = b[sortKey] ?? 0;), тип days_on_market: number | null в frontend/src/types/trade-in.ts:36, рендер '—' при null в AnalogsTable.tsx:273-275.

Корень: При сортировке по колонке «Дней» (sortKey='days_on_market', заголовок lines 177-182) строки с null через ?? 0 получают 0. ASC → они всплывают наверх как «самые ликвидные/0 дней»; DESC → уходят вниз. 'неизвестно' смешано с 'ноль дней'. price_rub/price_per_m2 не страдают (тип number без null). Канонический путь — frontend/src/components/trade-in/AnalogsTable.tsx (worktrees/forgejo-зеркала не трогать).

Что править:

  • Для nullable-поля выносить null в стабильный хвост независимо от направления, а не подменять на 0. Например в компараторе (lines 66-72): если a[sortKey] == null → всегда после непустых; иначе сравнивать как сейчас. Либо +Infinity при ASC / -Infinity при DESC.
  • price_rub/price_per_m2 можно оставить как есть (по типу не nullable) — менять только ветку days_on_market.

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

  • Код: AnalogsTable.tsx:66-72 + :273-275, types/trade-in.ts:36; добавить unit-тест на сортировку с null в выборке.
  • Vault: релевантных заметок не найдено.
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `frontend/src/components/trade-in/AnalogsTable.tsx:66-72` (компаратор `const av = a[sortKey] ?? 0; const bv = b[sortKey] ?? 0;`), тип `days_on_market: number | null` в `frontend/src/types/trade-in.ts:36`, рендер '—' при null в `AnalogsTable.tsx:273-275`. **Корень:** При сортировке по колонке «Дней» (`sortKey='days_on_market'`, заголовок lines 177-182) строки с `null` через `?? 0` получают 0. ASC → они всплывают наверх как «самые ликвидные/0 дней»; DESC → уходят вниз. 'неизвестно' смешано с 'ноль дней'. `price_rub`/`price_per_m2` не страдают (тип `number` без null). Канонический путь — `frontend/src/components/trade-in/AnalogsTable.tsx` (worktrees/forgejo-зеркала не трогать). **Что править:** - Для nullable-поля выносить null в стабильный хвост независимо от направления, а не подменять на 0. Например в компараторе (lines 66-72): если `a[sortKey] == null` → всегда после непустых; иначе сравнивать как сейчас. Либо `+Infinity` при ASC / `-Infinity` при DESC. - `price_rub`/`price_per_m2` можно оставить как есть (по типу не nullable) — менять только ветку days_on_market. **Что посмотреть:** - Код: `AnalogsTable.tsx:66-72` + `:273-275`, `types/trade-in.ts:36`; добавить unit-тест на сортировку с null в выборке. - 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#1479
No description provided.