[tradein] v2: клик по «Предыдущие оценки» не переключает вид, если в этой же SPA-сессии уже был submit свежей оценки #2425

Open
opened 2026-07-04 14:17:10 +00:00 by lekss361 · 0 comments
Owner

Найдено ревьюером при фиксе гонки клика по истории (PR со строками «Предыдущие оценки», см. фикс pendingRestoreId в tradein-mvp/frontend/src/app/v2/page.tsx). Не блокировало тот фикс, заводится отдельно.

Баг

const estimate: AggregatedEstimate | null = freshResult ?? restored.data ?? null;
const currentEstimateId = restoreNotFound ? null : (freshResult?.estimate_id ?? urlId);

freshResult имеет приоритет над restored.data безусловно. Сценарий:

  1. Пользователь заполняет форму и жмёт «ОЦЕНИТЬ КВАРТИРУ» → freshResult устанавливается свежим estimate.
  2. Не перезагружая страницу, открывает оверлей «ПРЕДЫДУЩИЕ ОЦЕНКИ» и кликает по ДРУГОЙ (исторической) строке.
  3. pendingRestoreId/urlId корректно обновляются на id исторической записи, useEstimate(urlId) корректно фетчит её — но на экране всё равно показывается СТАРЫЙ freshResult, потому что он ничем не перебивается кликом по строке истории.

Клик по строке истории визуально «не работает» в этом конкретном сценарии (сработавший в предыдущей SPA-сессии submit продолжает перекрывать любой последующий restore).

Fix (черновой)

onSelectEstimate в page.tsx должен также сбрасывать freshResult (setFreshResult(null)) одновременно с установкой pendingRestoreId — симметрично тому, как handleSubmit's onSuccess уже сбрасывает pendingRestoreId при установке freshResult. Два состояния (freshResult для «только что посчитанного» и restore-by-id для «загружаем сохранённое») должны быть взаимоисключающими в обе стороны, а не только в одну.

Риск

Низкий — узкий, единичный edge-case (тот же SPA-сессия, тот же tab, без reload), но легко воспроизводим и напрямую подрывает смысл кликабельных строк истории.

Refs #2424

Найдено ревьюером при фиксе гонки клика по истории (PR со строками «Предыдущие оценки», см. фикс `pendingRestoreId` в `tradein-mvp/frontend/src/app/v2/page.tsx`). Не блокировало тот фикс, заводится отдельно. ## Баг ```js const estimate: AggregatedEstimate | null = freshResult ?? restored.data ?? null; const currentEstimateId = restoreNotFound ? null : (freshResult?.estimate_id ?? urlId); ``` `freshResult` имеет приоритет над `restored.data` безусловно. Сценарий: 1. Пользователь заполняет форму и жмёт «ОЦЕНИТЬ КВАРТИРУ» → `freshResult` устанавливается свежим estimate. 2. Не перезагружая страницу, открывает оверлей «ПРЕДЫДУЩИЕ ОЦЕНКИ» и кликает по ДРУГОЙ (исторической) строке. 3. `pendingRestoreId`/`urlId` корректно обновляются на id исторической записи, `useEstimate(urlId)` корректно фетчит её — но на экране всё равно показывается СТАРЫЙ `freshResult`, потому что он ничем не перебивается кликом по строке истории. Клик по строке истории визуально «не работает» в этом конкретном сценарии (сработавший в предыдущей SPA-сессии submit продолжает перекрывать любой последующий restore). ## Fix (черновой) `onSelectEstimate` в page.tsx должен также сбрасывать `freshResult` (`setFreshResult(null)`) одновременно с установкой `pendingRestoreId` — симметрично тому, как `handleSubmit`'s onSuccess уже сбрасывает `pendingRestoreId` при установке `freshResult`. Два состояния (`freshResult` для «только что посчитанного» и restore-by-id для «загружаем сохранённое») должны быть взаимоисключающими в обе стороны, а не только в одну. ## Риск Низкий — узкий, единичный edge-case (тот же SPA-сессия, тот же tab, без reload), но легко воспроизводим и напрямую подрывает смысл кликабельных строк истории. Refs #2424
Sign in to join this conversation.
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#2425
No description provided.