fix(ptica): «0 мм осадков» перестаёт означать «данных нет» (#2464) #2947

Merged
bot-backend merged 1 commit from fix/2464-precipitation-unknown-not-zero into main 2026-08-20 07:00:04 +00:00

1 commit

Author SHA1 Message Date
9ae7af5753 fix(ptica): «0 мм осадков» перестаёт означать «данных нет» (#2464)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
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 1m11s
CI / openapi-codegen-check (pull_request) Successful in 2m3s
CI / backend-tests (pull_request) Successful in 17m10s
weather_cache отдавал 0, когда open-meteo не прислал ряд осадков:

    "precipitation_total_mm": round(sum(precip), 1) if precip else 0
    "total_precip_mm":        round(sum(precip), 0) if precip else 0   (сезонные)

Ноль здесь — утверждение о погоде («сухо»), а пустой ряд значит, что мы не знаем.
Разница видна пользователю: ptica-adapt заворачивал значение в real(...)
БЕЗУСЛОВНО, то есть подавал его как измеренную величину.

Непоследовательность внутри одного литерала: шесть соседних агрегатов при пустых
данных дают None (min_c / max_c / avg_max_c / avg_min_c / uv_index_max /
max_speed_m_s). В сезонном блоке ещё нагляднее — avg_precip_per_day_mm и
total_precip_mm считаются из ОДНОГО списка соседними строками, первый даёт None,
второй давал 0.

В репозитории уже был решён ровно этот класс: раздел 7 тестов weather_cache —
«wind_d all-None → dominant_direction_deg = None, а не 0.0° (= север)». Новые
тесты зеркалят его структуру, включая заголовок раздела.

Фронт: оба поля стали nullable, и TypeScript сам нашёл всех потребителей —
четыре ошибки в двух файлах плюс сезонный блок. Везде «нет данных» вместо числа.
В ptica-adapt применён образец соседней строки avg_min_c: есть значение → real(),
нет → notReal().

Тесты: 2 красных на origin/main —
«AssertionError: ожидался None, получено 0 — ноль здесь читается как
«осадков не будет»». Контроль отдельный: настоящая сухая неделя (precip=[0,0,0])
обязана давать ИЗМЕРЕННЫЙ 0.0, а не None — без него правку можно было бы «сделать»
так, что осадки всегда None, и оба теста стали бы зелёными по неверной причине.

pytest tests/services: 3089 passed, 14 skipped, rc=0 (перепрогнано после хуков)
tsc --noEmit rc=0 · vitest 36 файлов / 279 тестов rc=0
2026-08-20 11:10:29 +05:00