(low) site-finder/page.tsx FilterBarBridge: matchCount и totalCount из двух независимых запросов → транзиентный рассинхрон (matchCount может временно > totalCount) #1420

Closed
opened 2026-06-15 05:53:52 +00:00 by bot-backend · 0 comments
Collaborator

Severity: low · Категория: frontend · Файл: frontend/src/app/site-finder/page.tsx:60-69

page.tsx:60-61 — allInBbox = useParcelsBboxQuery(bbox, {}) и filtered = useParcelsBboxQuery(bbox, filters) — два useQuery с разными queryKey, когда фильтры активны (queryKey в site-finder-api.ts:157-168 включает фильтры). Запросы резолвятся независимо, порядок прихода ответов не гарантирован (staleTime 30s у обоих, но это не синхронизация). При смене bbox (пан/зум) один запрос обновляется раньше другого, и в подписи MapFilterBar.tsx:137-138 на короткое время смешиваются числа из РАЗНЫХ кадров карты: matchCount нового bbox / totalCount старого (или наоборот) → возможен показ matchCount > totalCount, что нарушает инвариант X ⊆ Y. Когда фильтров нет (filters={}), queryKey совпадают и React Query дедуплицирует → X===Y, баг не проявляется. Импакт: краевой транзиентный визуальный глитч только при активном фильтре во время движения карты. Фикс: считать matchCount как allInBbox.filter(applyFilters).length из ОДНОГО запроса allInBbox, не делать второй запрос; либо синхронизировать рендер по обоим isFetching.

Почему баг: Два отдельных useQuery без какой-либо синхронизации между ними; staleTime у обоих 30s, но порядок прихода ответов не гарантирован. Подпись «X / Y участков» предполагает X ⊆ Y из одного и того же снимка bbox, а здесь это два разных снимка. Когда фильтров нет (filters={}), queryKey совпадают и React Query дедуплицирует — тогда X===Y; баг проявляется только при активном фильтре, т.е. в краевом, но реальном сценарии.

Как чинить: Считать оба числа из ОДНОГО запроса: запросить allInBbox (filters={}) и применять applyFilters(allInBbox, filters) клиентски для matchCount — тогда оба числа гарантированно из одного снимка bbox. Либо завязать рендер счётчика на оба isFetching и не обновлять, пока оба не зарезолвились для текущего bbox.


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

**Severity:** low · **Категория:** frontend · **Файл:** `frontend/src/app/site-finder/page.tsx:60-69` page.tsx:60-61 — allInBbox = useParcelsBboxQuery(bbox, {}) и filtered = useParcelsBboxQuery(bbox, filters) — два useQuery с разными queryKey, когда фильтры активны (queryKey в site-finder-api.ts:157-168 включает фильтры). Запросы резолвятся независимо, порядок прихода ответов не гарантирован (staleTime 30s у обоих, но это не синхронизация). При смене bbox (пан/зум) один запрос обновляется раньше другого, и в подписи MapFilterBar.tsx:137-138 на короткое время смешиваются числа из РАЗНЫХ кадров карты: matchCount нового bbox / totalCount старого (или наоборот) → возможен показ matchCount > totalCount, что нарушает инвариант X ⊆ Y. Когда фильтров нет (filters={}), queryKey совпадают и React Query дедуплицирует → X===Y, баг не проявляется. Импакт: краевой транзиентный визуальный глитч только при активном фильтре во время движения карты. Фикс: считать matchCount как allInBbox.filter(applyFilters).length из ОДНОГО запроса allInBbox, не делать второй запрос; либо синхронизировать рендер по обоим isFetching. **Почему баг:** Два отдельных useQuery без какой-либо синхронизации между ними; staleTime у обоих 30s, но порядок прихода ответов не гарантирован. Подпись «X / Y участков» предполагает X ⊆ Y из одного и того же снимка bbox, а здесь это два разных снимка. Когда фильтров нет (filters={}), queryKey совпадают и React Query дедуплицирует — тогда X===Y; баг проявляется только при активном фильтре, т.е. в краевом, но реальном сценарии. **Как чинить:** Считать оба числа из ОДНОГО запроса: запросить allInBbox (filters={}) и применять applyFilters(allInBbox, filters) клиентски для matchCount — тогда оба числа гарантированно из одного снимка bbox. Либо завязать рендер счётчика на оба isFetching и не обновлять, пока оба не зарезолвились для текущего bbox. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.7 · unit U81</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:53:52 +00:00
bot-backend added the
scope/frontend
label 2026-06-15 11:02:01 +00:00
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#1420
No description provided.