(medium) BestLayoutsBlock/handleDownloadPdf: PDF собирается из живого состояния контролов, а не из показанного расчёта #1448

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

Severity: medium · Категория: report · Файл: frontend/src/components/site-finder/BestLayoutsBlock.tsx:682-711

BestLayoutsBlock.tsx:682-711 — handleDownloadPdf() вызывает buildRequest() (стр. 661-676), читающий radiusKm/timeWindow/targetTotalFlats/minVelocity напрямую из React-state. Эти значения меняются onChange-хендлерами контролов без перезапроса, а показанный data обновляется только при клике «Рассчитать» (mutate, стр. 678-680). Кнопка PDF доступна по наличию data (стр. 751) без проверки синхронности. Импакт: если менеджер после расчёта подвигал параметры и не нажал «Рассчитать» снова, PDF-ТЗ на проектирование уйдёт клиенту с radius/time_window/target, отличными от аналитики на экране. Серьёзность medium — рассинхрон клиентского деливерабла. Фикс: сохранять lastRequest при mutate и слать его в /pdf, либо блокировать/предупреждать PDF при расхождении контролов с показанным расчётом.

Почему баг: buildRequest() (стр. 661-676) читает radiusKm/timeWindow/targetTotalFlats/minVelocity из state, который меняется онченджами слайдеров (стр. 817, 846, 882, 907) без перезапроса. data обновляется только в mutate()/useBestLayouts при клике «Рассчитать» (стр. 678-680). Кнопка PDF доступна как только есть data (стр. 751), независимо от того, синхронны ли контролы с этим data. Итог: клиентский документ (ТЗ на проектирование) может не соответствовать тому, что менеджер видит на экране — рассинхрон параметров radius/period/target в выгружаемом отчёте.

Как чинить: Хранить параметры успешного расчёта (snapshot запроса) и отдавать в PDF именно их; либо дизейблить/прятать кнопку PDF при «грязных» контролах (показывать «Параметры изменены — пересчитайте»), либо повторно вызывать расчёт перед генерацией PDF.


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

**Severity:** medium · **Категория:** report · **Файл:** `frontend/src/components/site-finder/BestLayoutsBlock.tsx:682-711` BestLayoutsBlock.tsx:682-711 — handleDownloadPdf() вызывает buildRequest() (стр. 661-676), читающий radiusKm/timeWindow/targetTotalFlats/minVelocity напрямую из React-state. Эти значения меняются onChange-хендлерами контролов без перезапроса, а показанный `data` обновляется только при клике «Рассчитать» (mutate, стр. 678-680). Кнопка PDF доступна по наличию `data` (стр. 751) без проверки синхронности. Импакт: если менеджер после расчёта подвигал параметры и не нажал «Рассчитать» снова, PDF-ТЗ на проектирование уйдёт клиенту с radius/time_window/target, отличными от аналитики на экране. Серьёзность medium — рассинхрон клиентского деливерабла. Фикс: сохранять lastRequest при mutate и слать его в /pdf, либо блокировать/предупреждать PDF при расхождении контролов с показанным расчётом. **Почему баг:** buildRequest() (стр. 661-676) читает radiusKm/timeWindow/targetTotalFlats/minVelocity из state, который меняется онченджами слайдеров (стр. 817, 846, 882, 907) без перезапроса. `data` обновляется только в mutate()/useBestLayouts при клике «Рассчитать» (стр. 678-680). Кнопка PDF доступна как только есть `data` (стр. 751), независимо от того, синхронны ли контролы с этим `data`. Итог: клиентский документ (ТЗ на проектирование) может не соответствовать тому, что менеджер видит на экране — рассинхрон параметров radius/period/target в выгружаемом отчёте. **Как чинить:** Хранить параметры успешного расчёта (snapshot запроса) и отдавать в PDF именно их; либо дизейблить/прятать кнопку PDF при «грязных» контролах (показывать «Параметры изменены — пересчитайте»), либо повторно вызывать расчёт перед генерацией PDF. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.85 · unit U92</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:55:46 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:02:06 +00:00
Owner

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

Текущее состояние кода: frontend/src/components/site-finder/BestLayoutsBlock.tsxbuildRequest() стр. 661-676, handleCalculate()mutate стр. 678-680, handleDownloadPdf() стр. 682-711 (req собирается на стр. 685), кнопка PDF доступна {data && …} стр. 751.

Корень: handleDownloadPdf() (стр. 685) заново вызывает buildRequest(), который читает radiusKm/timeWindow/targetTotalFlats/minVelocity напрямую из React-state. Эти значения меняются onChange-хендлерами контролов (radius стр. 817, minVelocity стр. 846, timeWindow стр. 882, targetTotalFlats стр. 907) без перезапроса. Показанный data приходит только из mutate() (стр. 679). Кнопка PDF гейтится только наличием data (стр. 751), без проверки синхронности → если менеджер подвигал слайдеры и не нажал «Рассчитать», PDF уйдёт с параметрами, отличными от аналитики на экране.

Что править:

  • При успешном mutate сохранять snapshot запроса (lastRequest) и в handleDownloadPdf слать именно его, а не свежий buildRequest().
  • Либо: дизейблить/предупреждать кнопку PDF при «грязных» контролах (сравнить текущий buildRequest() с lastRequest, показать «Параметры изменены — пересчитайте»).

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

  • Код: BestLayoutsBlock.tsx:661-711, 751-779; useBestLayouts (frontend/src/hooks/useBestLayouts.ts) — добавить возврат/хранение последнего request. Тест: изменить state после mutate → PDF-body == snapshot.
  • Vault: domains/ui/components/Component_SiteFinder_Page.md (BestLayoutsBlock — «Анализ планировок», /best-layouts).
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `frontend/src/components/site-finder/BestLayoutsBlock.tsx` — `buildRequest()` стр. 661-676, `handleCalculate()`→`mutate` стр. 678-680, `handleDownloadPdf()` стр. 682-711 (req собирается на стр. 685), кнопка PDF доступна `{data && …}` стр. 751. **Корень:** `handleDownloadPdf()` (стр. 685) заново вызывает `buildRequest()`, который читает `radiusKm`/`timeWindow`/`targetTotalFlats`/`minVelocity` напрямую из React-state. Эти значения меняются onChange-хендлерами контролов (radius стр. 817, minVelocity стр. 846, timeWindow стр. 882, targetTotalFlats стр. 907) без перезапроса. Показанный `data` приходит только из `mutate()` (стр. 679). Кнопка PDF гейтится только наличием `data` (стр. 751), без проверки синхронности → если менеджер подвигал слайдеры и не нажал «Рассчитать», PDF уйдёт с параметрами, отличными от аналитики на экране. **Что править:** - При успешном `mutate` сохранять snapshot запроса (`lastRequest`) и в `handleDownloadPdf` слать именно его, а не свежий `buildRequest()`. - Либо: дизейблить/предупреждать кнопку PDF при «грязных» контролах (сравнить текущий `buildRequest()` с `lastRequest`, показать «Параметры изменены — пересчитайте»). **Что посмотреть:** - Код: `BestLayoutsBlock.tsx:661-711, 751-779`; `useBestLayouts` (`frontend/src/hooks/useBestLayouts.ts`) — добавить возврат/хранение последнего request. Тест: изменить state после mutate → PDF-body == snapshot. - Vault: `domains/ui/components/Component_SiteFinder_Page.md` (BestLayoutsBlock — «Анализ планировок», /best-layouts).
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#1448
No description provided.