МЕРА v2: клик по «Предыдущим оценкам» после отправки открывает выбранную оценку #3549

Merged
bot-backend merged 1 commit from fix/v2-history-click into main 2026-09-17 09:17:03 +00:00
Collaborator

#2425 — клик по «Предыдущие оценки» после отправки оценки ничего не менял

Что было. Пользователь отправляет оценку, не перезагружая страницу открывает «Предыдущие оценки» и кликает по другой строке. URL меняется на ?id=<строка>, а на экране остаётся только что посчитанная оценка.

Почему. В tradein-mvp/frontend/src/app/v2/page.tsx после submit выставлен freshResult. Обработчик onSelectEstimate ставил pendingRestoreId, вызывал router.replace и закрывал оверлей, но freshResult не сбрасывал. Дальше:

  • useEstimate(freshResult === null ? urlId : null) получал null, поэтому запрос выбранной записи не уходил вообще. В issue сказано, что фетч корректен; на деле его не было;
  • estimate = freshResult ?? restored.data и currentEstimateId = freshResult?.estimate_id ?? urlId продолжали брать старый результат.

Рядом есть правильный образец: handleNew сбрасывает оба состояния.

Что сделано. В onSelectEstimate перед setPendingRestoreId(id) добавлен setFreshResult(null). Теперь свежий результат и восстановление по id взаимоисключающие в обе стороны. Диф: +5 строк, из них 4 комментарий.

Улика, что это корень. Новый тест, запущенный на неисправленном main (34642e1d), падает ровно на этом месте: useEstimate вызван с null, а не с id строки.

Тесты

src/app/v2/__tests__/historyClickAfterSubmit.test.tsx рендерит страницу. Хуки данных и дочерние компоненты заменены заглушками, мапперы настоящие, фикстура FIXTURE_ESTIMATE. Сценарий: submit → в HeroBar fresh-1, в форме «ул. Свежая, 1» → открыть оверлей → клик по строке hist-1. Проверяется по значению:

  • последний вызов useEstimate("hist-1");
  • router.replace("/v2?id=hist-1");
  • HeroBar получил hist-1;
  • форма получила адрес исторической записи.

Прогоны в tradein-mvp/frontend (npm ci --legacy-peer-deps, как в CI):

  • npx tsc --noEmit: rc=0
  • npx vitest run: rc=0, 33 файла, 296 тестов passed
  • npx eslint src/app/v2/page.tsx src/app/v2/__tests__/historyClickAfterSubmit.test.tsx: rc=0

Фальсификация

В исправленном page.tsx строка setFreshResult(null); в onSelectEstimate заменена комментарием, тест прогнан, исходник восстановлен из копии (diff -q пустой). Красный прогон (rc=1):

× #2425 — строка истории после submit > клик по другой оценке показывает её, а не только что посчитанную
AssertionError: expected last "spy" call to have been called with [ 'hist-1' ]
- Expected
+ Received
  [
-   "hist-1",
+   null,
  ]
 ❯ src/app/v2/__tests__/historyClickAfterSubmit.test.tsx:116:29

Приёмка на проде (после деплоя tradein-frontend)

Проверка в браузере, со скриншотами до и после:

  1. Открыть https://gendsgn.ru/trade-in/v2 и отправить оценку.
  2. Не перезагружая страницу, открыть «Предыдущие оценки» и кликнуть по другой строке.
  3. Ожидается: на экране адрес и параметры выбранной строки, ?id= в URL совпадает с её id. В сетевых запросах есть GET оценки по этому id.

До деплоя по состоянию на 17.09.2026 баг воспроизводится по коду: origin/main 34642e1d.

Деплой пересоздаёт только tradein-frontend. Миграций нет.

Closes #2425

🤖 Generated with Claude Code

## #2425 — клик по «Предыдущие оценки» после отправки оценки ничего не менял **Что было.** Пользователь отправляет оценку, не перезагружая страницу открывает «Предыдущие оценки» и кликает по другой строке. URL меняется на `?id=<строка>`, а на экране остаётся только что посчитанная оценка. **Почему.** В `tradein-mvp/frontend/src/app/v2/page.tsx` после submit выставлен `freshResult`. Обработчик `onSelectEstimate` ставил `pendingRestoreId`, вызывал `router.replace` и закрывал оверлей, но `freshResult` не сбрасывал. Дальше: - `useEstimate(freshResult === null ? urlId : null)` получал `null`, поэтому запрос выбранной записи не уходил вообще. В issue сказано, что фетч корректен; на деле его не было; - `estimate = freshResult ?? restored.data` и `currentEstimateId = freshResult?.estimate_id ?? urlId` продолжали брать старый результат. Рядом есть правильный образец: `handleNew` сбрасывает оба состояния. **Что сделано.** В `onSelectEstimate` перед `setPendingRestoreId(id)` добавлен `setFreshResult(null)`. Теперь свежий результат и восстановление по id взаимоисключающие в обе стороны. Диф: +5 строк, из них 4 комментарий. **Улика, что это корень.** Новый тест, запущенный на неисправленном `main` (34642e1d), падает ровно на этом месте: `useEstimate` вызван с `null`, а не с id строки. ## Тесты `src/app/v2/__tests__/historyClickAfterSubmit.test.tsx` рендерит страницу. Хуки данных и дочерние компоненты заменены заглушками, мапперы настоящие, фикстура `FIXTURE_ESTIMATE`. Сценарий: submit → в HeroBar `fresh-1`, в форме «ул. Свежая, 1» → открыть оверлей → клик по строке `hist-1`. Проверяется по значению: - последний вызов `useEstimate("hist-1")`; - `router.replace("/v2?id=hist-1")`; - HeroBar получил `hist-1`; - форма получила адрес исторической записи. Прогоны в `tradein-mvp/frontend` (`npm ci --legacy-peer-deps`, как в CI): - `npx tsc --noEmit`: rc=0 - `npx vitest run`: rc=0, 33 файла, 296 тестов passed - `npx eslint src/app/v2/page.tsx src/app/v2/__tests__/historyClickAfterSubmit.test.tsx`: rc=0 ## Фальсификация В исправленном `page.tsx` строка `setFreshResult(null);` в `onSelectEstimate` заменена комментарием, тест прогнан, исходник восстановлен из копии (`diff -q` пустой). Красный прогон (rc=1): ``` × #2425 — строка истории после submit > клик по другой оценке показывает её, а не только что посчитанную AssertionError: expected last "spy" call to have been called with [ 'hist-1' ] - Expected + Received [ - "hist-1", + null, ] ❯ src/app/v2/__tests__/historyClickAfterSubmit.test.tsx:116:29 ``` ## Приёмка на проде (после деплоя tradein-frontend) Проверка в браузере, со скриншотами до и после: 1. Открыть https://gendsgn.ru/trade-in/v2 и отправить оценку. 2. Не перезагружая страницу, открыть «Предыдущие оценки» и кликнуть по другой строке. 3. Ожидается: на экране адрес и параметры выбранной строки, `?id=` в URL совпадает с её id. В сетевых запросах есть `GET` оценки по этому id. До деплоя по состоянию на 17.09.2026 баг воспроизводится по коду: `origin/main` 34642e1d. Деплой пересоздаёт только tradein-frontend. Миграций нет. Closes #2425 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bot-backend added 1 commit 2026-09-17 07:24:24 +00:00
МЕРА v2: клик по «Предыдущие оценки» после отправки показывает выбранную оценку (#2425)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 13s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m19s
f1f0d297cf
После отправки оценки freshResult оставался выставленным, и клик по строке
истории ничего не менял на экране: useEstimate получал null (восстановление
по id вообще не запускалось), а estimate и currentEstimateId брались из
только что посчитанного результата. onSelectEstimate теперь сбрасывает
freshResult так же, как это делает handleNew.

Тест рендерит страницу с заглушками хуков: submit, затем клик по другой
строке истории — в useEstimate уходит id строки, HeroBar и форма получают
её id и адрес. Без правки тест красный (useEstimate вызван с null).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bot-backend merged commit 404b583682 into main 2026-09-17 09:17:03 +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#3549
No description provided.