Snapshot-PDF: блок «Конкуренты (топ 5)» отбирает крупнейшие ЖК по flat_count, а не ближайшие — расходится с комментарием кода #1591

Closed
opened 2026-06-16 17:13:55 +00:00 by bot-backend · 0 comments
Collaborator

Severity: low · Категория: logic/data-selection · Файл: backend/app/services/exporters/snapshot_pdf.py:162-167

Где: SQL в parcels.py:3377-3409 (эндпоинт parcel_snapshot_pdf) + snapshot_pdf.py:162-167.

Суть: запрос, питающий generate_snapshot_pdf, отбирает конкурентов в радиусе 3 км через ORDER BY flat_count DESC NULLS LAST LIMIT 20 (parcels.py:3402) — то есть 20 КРУПНЕЙШИХ ЖК по числу квартир. Далее snapshot_pdf.py:164-167 берёт competitor_rows[:competitors_limit] (=5) и пересортировывает уже-отобранную пятёрку по distance_m. Комментарий snapshot_pdf.py:162-163 гласит «берём топ N ближайших … переупорядочиваем по distance_m для удобства чтения», но фактический критерий отбора — размер (flat_count), а не близость.

Импакт: клиентский 1-страничный PDF в блоке «Конкуренты в радиусе 3 км (топ 5)» показывает не непосредственное конкурентное окружение пятна, а 5 крупнейших ЖК из радиуса. Близкий небольшой конкурент (например 300 м, 40 квартир) молча вытесняется далёким крупным (2900 м, 1200 квартир). Это искажает локальный конкурентный контекст и дезориентирует мейнтейнера (комментарий лжёт). Примечательно: ПАРАЛЛЕЛЬНЫЙ запрос для UI/JSON на parcels.py:1656-1658 уже сортирует корректно — ORDER BY CASE site_status … , distance_m ASC — то есть в snapshot-PDF просто не применили тот же критерий близости.

Фикс (один из): (1) в parcels.py:3402 заменить ORDER BY flat_count DESC NULLS LAST на ORDER BY distance_m ASC (как в запросе строки 1656) — тогда top-20→top-5 будут действительно ближайшими; либо (2) если намеренно нужны крупнейшие — убрать вводящий в заблуждение re-sort по distance в snapshot_pdf.py:164-167 и исправить комментарий/подпись блока на «крупнейшие ЖК», чтобы убрать ложное обещание «ближайших». Тривиально, не требует миграций.

Почему баг: Карточка участка (1-страничный PDF, отдаётся клиенту) в блоке «Конкуренты в радиусе 3 км (топ 5)» претендует показать конкурентное окружение пятна, но из 20 кандидатов выживают крупнейшие по flat_count, а не ближайшие. Re-sort по distance ВНУТРИ уже-отобранной по размеру пятёрки создаёт иллюзию «топ ближайших», хотя ближайшие мелкие ЖК в выборку не попали. Это искажает непосредственный конкурентный контекст участка и расходится с собственным комментарием кода (последний дезориентирует будущего мейнтейнера). Не краш и не порча данных — выход детерминирован и валиден, поэтому low; но это смысловое несоответствие между заявленным («ближайшие») и фактическим («крупнейшие») критерием отбора в клиентском артефакте.

Как чинить: Определиться с семантикой и синхронизировать SQL + код + комментарий + заголовок шаблона. Если нужны ближайшие — в SQL ORDER BY distance_m ASC LIMIT 20 (или сортировать competitor_rows по distance перед срезом [:limit]). Если намеренно показываем крупнейших — поправить комментарий на «топ N крупнейших по числу квартир» и уточнить заголовок в parcel_snapshot.html. Текущая комбинация «отбор по flat_count + re-sort по distance + комментарий про ближайших» внутренне противоречива.


deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.92 · unit B21

**Severity:** low · **Категория:** logic/data-selection · **Файл:** `backend/app/services/exporters/snapshot_pdf.py:162-167` Где: SQL в parcels.py:3377-3409 (эндпоинт parcel_snapshot_pdf) + snapshot_pdf.py:162-167. Суть: запрос, питающий generate_snapshot_pdf, отбирает конкурентов в радиусе 3 км через `ORDER BY flat_count DESC NULLS LAST LIMIT 20` (parcels.py:3402) — то есть 20 КРУПНЕЙШИХ ЖК по числу квартир. Далее snapshot_pdf.py:164-167 берёт competitor_rows[:competitors_limit] (=5) и пересортировывает уже-отобранную пятёрку по distance_m. Комментарий snapshot_pdf.py:162-163 гласит «берём топ N ближайших … переупорядочиваем по distance_m для удобства чтения», но фактический критерий отбора — размер (flat_count), а не близость. Импакт: клиентский 1-страничный PDF в блоке «Конкуренты в радиусе 3 км (топ 5)» показывает не непосредственное конкурентное окружение пятна, а 5 крупнейших ЖК из радиуса. Близкий небольшой конкурент (например 300 м, 40 квартир) молча вытесняется далёким крупным (2900 м, 1200 квартир). Это искажает локальный конкурентный контекст и дезориентирует мейнтейнера (комментарий лжёт). Примечательно: ПАРАЛЛЕЛЬНЫЙ запрос для UI/JSON на parcels.py:1656-1658 уже сортирует корректно — `ORDER BY CASE site_status … , distance_m ASC` — то есть в snapshot-PDF просто не применили тот же критерий близости. Фикс (один из): (1) в parcels.py:3402 заменить `ORDER BY flat_count DESC NULLS LAST` на `ORDER BY distance_m ASC` (как в запросе строки 1656) — тогда top-20→top-5 будут действительно ближайшими; либо (2) если намеренно нужны крупнейшие — убрать вводящий в заблуждение re-sort по distance в snapshot_pdf.py:164-167 и исправить комментарий/подпись блока на «крупнейшие ЖК», чтобы убрать ложное обещание «ближайших». Тривиально, не требует миграций. **Почему баг:** Карточка участка (1-страничный PDF, отдаётся клиенту) в блоке «Конкуренты в радиусе 3 км (топ 5)» претендует показать конкурентное окружение пятна, но из 20 кандидатов выживают крупнейшие по flat_count, а не ближайшие. Re-sort по distance ВНУТРИ уже-отобранной по размеру пятёрки создаёт иллюзию «топ ближайших», хотя ближайшие мелкие ЖК в выборку не попали. Это искажает непосредственный конкурентный контекст участка и расходится с собственным комментарием кода (последний дезориентирует будущего мейнтейнера). Не краш и не порча данных — выход детерминирован и валиден, поэтому low; но это смысловое несоответствие между заявленным («ближайшие») и фактическим («крупнейшие») критерием отбора в клиентском артефакте. **Как чинить:** Определиться с семантикой и синхронизировать SQL + код + комментарий + заголовок шаблона. Если нужны ближайшие — в SQL `ORDER BY distance_m ASC LIMIT 20` (или сортировать competitor_rows по distance перед срезом [:limit]). Если намеренно показываем крупнейших — поправить комментарий на «топ N крупнейших по числу квартир» и уточнить заголовок в parcel_snapshot.html. Текущая комбинация «отбор по flat_count + re-sort по distance + комментарий про ближайших» внутренне противоречива. --- <sub>deep-audit backend v2 (после PR #1543) · verify+harden, confidence 0.92 · unit B21</sub>
bot-backend added the
week ревью 1
label 2026-06-16 17:13:55 +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#1591
No description provided.