fix(ptica): пустой слой риск-зон перестаёт означать «рисков нет» (#2934) #2940

Merged
bot-backend merged 1 commit from fix/2934-risk-coverage-signal into main 2026-08-19 16:34:27 +00:00
Collaborator

Плашка «Риски не обнаружены» показывалась всегда

Бэкенд всегда присылает nspd_risk_zones — пустым списком, если ничего нет. Условие показа в LandTab (data.nspd_risk_zones !== undefined) поэтому истинно всегда, а ветка zones.length === 0 рисовала зелёную плашку (#f0fdf4 / #15803d):

Риски не обнаружены · Риск-зоны НСПД на участке не выявлены

Пустой список неоднозначен: «слой опрошен, на участке чисто» и «слой не дал ничего вообще» выглядят одинаково.

Замер на проде 19.08:

risks_count > 0 у дампов        0   из 669
zouit_count  > 0 у дампов     581   из 669   (для сравнения: ЗОУИТ работает)
объектов слоёв risk_*           0   на все 669 дампов

То есть плашка показывалась всегда и всегда без основания.

Три состояния вместо двух

Признак risks_count уже вычитывался из строки дампа (quarter_dump_lookup.py:277) и лежал в layer_counts — просто не выходил наружу.

risks_count > 0     -> «Риски не обнаружены»   законно: слой отработал по кварталу,
                                               отсутствие пересечений — факт
risks_count == 0    -> «Не проверено»          нейтральный серый, без success-стиля
risks_count is None -> «Не проверено»          дампа нет

None, а не 0, когда дампа нет: ноль означал бы «спросили и не нашли».

layers_fetched наружу не отдаю. layers_fetched.append(...) в nspd_client.py:956 стоит до запроса, поэтому как признак «слой опрошен» он лжёт — говорит лишь «собирались спросить». Записал это прямо в коде, чтобы следующий читатель не подхватил его как готовый признак покрытия.

Заодно: счётчик слоя на карте

Зоны риска 0 стояло в одном ряду с измеренными Конкуренты 14 и Красные линии 2. Такой ноль читается как измеренный. При пустом слое теперь «н/д».

Проверка

тест origin/main с правкой
слой не дал объектов → «Не проверено» красный: Unable to find an element with the text: Не проверено зелёный
дампа нет → «Не проверено» красный, тот же текст зелёный
слой отработал, участок чист → «Риски не обнаружены» законно зелёный зелёный
найденные зоны рисуются карточками зелёный зелёный

Два последних — контроли: без них правка могла бы свестись к «никогда не показывать зелёное», что было бы такой же неправдой с другой стороны.

tsc --noEmit: rc=0 · vitest: 35 файлов, 275 тестов, rc=0
pytest tests/test_quarter_dump_lookup.py: 23 passed · pytest tests/api/v1: 354 passed, 1 skipped, rc=0

Всё перепрогнано после того, как pre-commit прогнал ruff-format и prettier.

Про размер диффа

CpLayerControlPanel.tsx — 267 изменённых строк при правке в две. Это работа pre-commit prettier: файл не проходил prettier уже на origin/main (проверил отдельно, прогнав prettier по версии из main). Хук нормализовал его целиком, когда я его тронул.

Тот же класс, что расхождение ruff в #2864: хук гоняется только по staged-файлам, поэтому файлы, которых давно не касались, остаются нестандартизованными до первой правки.

Refs #2934

## Плашка «Риски не обнаружены» показывалась всегда Бэкенд **всегда** присылает `nspd_risk_zones` — пустым списком, если ничего нет. Условие показа в `LandTab` (`data.nspd_risk_zones !== undefined`) поэтому истинно всегда, а ветка `zones.length === 0` рисовала зелёную плашку (`#f0fdf4` / `#15803d`): > **Риски не обнаружены** · Риск-зоны НСПД на участке не выявлены Пустой список неоднозначен: «слой опрошен, на участке чисто» и «слой не дал ничего вообще» выглядят одинаково. Замер на проде 19.08: ``` risks_count > 0 у дампов 0 из 669 zouit_count > 0 у дампов 581 из 669 (для сравнения: ЗОУИТ работает) объектов слоёв risk_* 0 на все 669 дампов ``` То есть плашка показывалась **всегда** и **всегда без основания**. ## Три состояния вместо двух Признак `risks_count` уже вычитывался из строки дампа (`quarter_dump_lookup.py:277`) и лежал в `layer_counts` — просто не выходил наружу. ``` risks_count > 0 -> «Риски не обнаружены» законно: слой отработал по кварталу, отсутствие пересечений — факт risks_count == 0 -> «Не проверено» нейтральный серый, без success-стиля risks_count is None -> «Не проверено» дампа нет ``` `None`, а не `0`, когда дампа нет: ноль означал бы «спросили и не нашли». **`layers_fetched` наружу не отдаю.** `layers_fetched.append(...)` в `nspd_client.py:956` стоит **до** запроса, поэтому как признак «слой опрошен» он лжёт — говорит лишь «собирались спросить». Записал это прямо в коде, чтобы следующий читатель не подхватил его как готовый признак покрытия. ## Заодно: счётчик слоя на карте `Зоны риска 0` стояло в одном ряду с измеренными `Конкуренты 14` и `Красные линии 2`. Такой ноль читается как измеренный. При пустом слое теперь «н/д». ## Проверка | тест | `origin/main` | с правкой | |---|---|---| | слой не дал объектов → «Не проверено» | **красный**: `Unable to find an element with the text: Не проверено` | зелёный | | дампа нет → «Не проверено» | **красный**, тот же текст | зелёный | | слой отработал, участок чист → «Риски не обнаружены» законно | зелёный | зелёный | | найденные зоны рисуются карточками | зелёный | зелёный | Два последних — контроли: без них правка могла бы свестись к «никогда не показывать зелёное», что было бы такой же неправдой с другой стороны. `tsc --noEmit`: rc=0 · `vitest`: 35 файлов, 275 тестов, rc=0 `pytest tests/test_quarter_dump_lookup.py`: 23 passed · `pytest tests/api/v1`: 354 passed, 1 skipped, rc=0 Всё перепрогнано **после** того, как pre-commit прогнал ruff-format и prettier. ## Про размер диффа `CpLayerControlPanel.tsx` — 267 изменённых строк при правке в две. Это работа pre-commit prettier: файл **не проходил prettier уже на `origin/main`** (проверил отдельно, прогнав prettier по версии из main). Хук нормализовал его целиком, когда я его тронул. Тот же класс, что расхождение ruff в #2864: хук гоняется только по staged-файлам, поэтому файлы, которых давно не касались, остаются нестандартизованными до первой правки. Refs #2934
bot-backend added 1 commit 2026-08-19 16:06:26 +00:00
fix(ptica): пустой слой риск-зон перестаёт означать «рисков нет» (#2934)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m36s
CI / openapi-codegen-check (pull_request) Successful in 2m31s
CI / backend-tests (pull_request) Successful in 17m34s
a64119ad8f
Бэкенд ВСЕГДА присылает nspd_risk_zones — пустым списком, если ничего нет.
Условие показа в LandTab (`!== undefined`) поэтому истинно всегда, а ветка
zones.length === 0 рисовала ЗЕЛЁНУЮ плашку «Риски не обнаружены» с текстом
«Риск-зоны НСПД на участке не выявлены».

Пустой список неоднозначен: «слой опрошен, на участке чисто» и «слой не дал
ничего вообще» выглядят одинаково. Замер на проде 19.08: risks_count = 0 у ВСЕХ
669 дампов (для сравнения zouit_count > 0 у 581) — одиннадцать слоёв природного
риска ни разу не вернули ни одного объекта. То есть плашка показывалась всегда и
всегда без основания.

Провёл наружу risks_count из строки дампа (он уже вычитывался, в ответ не
попадал). Три состояния вместо двух:

    risks_count > 0     -> «Риски не обнаружены» — законно, слой отработал
    risks_count == 0    -> «Не проверено», нейтральным серым
    risks_count is None -> «Не проверено» (дампа нет; None, а не 0, потому что
                           ноль означал бы «спросили и не нашли»)

layers_fetched наружу НЕ отдаю: append в nspd_client.py:956 стоит ДО запроса,
поэтому как признак «слой опрошен» он лжёт. Записано в коде, чтобы следующий
читатель не подхватил его как готовый признак.

Заодно счётчик слоя в тумблере карты: при пустом слое «н/д» вместо «0». Ноль в
одном ряду с измеренными «Конкуренты 14» и «Красные линии 2» читался как
измеренный ноль.

Тесты двусторонние: на origin/main обе проверки падают с «Unable to find an
element with the text: Не проверено»; два контроля (слой отработал → зелёная
плашка законна; зоны найдены → карточки) зелёные с обеих сторон.

Большой дифф CpLayerControlPanel.tsx (267 строк при правке в две) — работа
pre-commit prettier: файл НЕ проходил prettier уже на origin/main (проверено
отдельно), хук нормализовал его целиком, когда я его тронул. Тот же класс, что
расхождение ruff в #2864: хук гоняется только по staged-файлам, поэтому файлы,
которых давно не касались, остаются нестандартизованными.

tsc --noEmit rc=0 · vitest 35 файлов / 275 тестов rc=0 (перепрогнано ПОСЛЕ хуков)
pytest tests/test_quarter_dump_lookup.py: 23 passed
pytest tests/api/v1 (контракт ответа): 354 passed, 1 skipped, rc=0

Refs #2934
bot-backend merged commit 5a7d558a5c into main 2026-08-19 16:34:27 +00:00
bot-backend deleted branch fix/2934-risk-coverage-signal 2026-08-19 16:34:27 +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#2940
No description provided.