discordBot/ISSUES.md

6.0 KiB
Raw Blame History

ISSUES — Задачи и баг-трекер

Высокий приоритет

  • run_morning fallback может отправить дайджест в несколько каналов — при неудаче в _target_channel_id перебирает bot.get_all_channels() и шлёт в первый доступный. Пользователь получит сообщение не там, где ожидает (utils/morning_runner.py, _run_morning)
  • !nw: последовательные вызовы API вместо параллельныхfetch_rss(RSS_URL_ARTICLES) ждёт, затем fetch_rss(RSS_URL_POSTS). В !morning используется asyncio.gather(). Привести !nw к тому же паттерну (commands/news.py)
  • format_weather_data_for_console выводит None в текст — если API вернёт null для поля (temp_C, FeelsLikeC), dict.get() вернёт None и f-string покажет "None°C". Добавить проверку на None (utils/pogoda.py)

Средний приоритет

  • _parse_date хрупкий fallbackpub_date[:10].replace("-", ".") для невалидной строки вернёт мусор (например "invalid.da"). Добавить валидацию формата (utils/news.py)
  • wmo_to_russian создаёт dict на каждый вызов — mapping из 30+ элементов пересоздаётся. Вынести в модульную константу (utils/pogoda.py)
  • TextHelpCommand пропускает команды без cogif cog_or_none is None: continue скроет standalone-команды из справки (bot.py)
  • translate_weather(" ") возвращает пробелы вместо "—" — строка из пробелов не считается пустой, проходит через mapping без совпадений и возвращается как есть (utils/pogoda.py)
  • pressure_to_mmhg(mb: Any)Any скрывает контракт. Заменить на float | int | str | None (utils/pogoda.py)

Низкий приоритет

  • conftest.py и bot.py дублируют monkey-patch — идентичный asyncio.iscoroutinefunction = ... в двух файлах. Вынести в compat.py
  • RateLimiter тесты зависят от реального времениtime.monotonic() в _refill делает тесты потенциально flaky на медленном CI. Добавить time.monotonic mock
  • Dockerfile не копирует conftest.pyCOPY пропускает conftest.py. Тесты в контейнере упадут без monkey-patch
  • requirements.txt без пиннинга версий>= допускает мажорные обновления. Для production использовать == или ~=
  • Закомментированный тест pressure_to_mmhg(0) вводит в заблуждение(0, "\u2014"), # 0 — falsy, возвращается '\u2014' (баг) закомментирован, но test_pressure_zero проходит. Удалить закомментированную строку (tests/test_pogoda.py)
  • format_articles(None) бросает TypeError — нет валидации articles на None. Вызывает краш вместо graceful fallback (utils/news.py)

Исправлено

  • Эмодзи в embed-сообщениях — удалены 🌅, , из utils/morning_runner.py
  • f-string в logger — замена на %-формат в bot.py
  • import time внутри __init__ — перенесён на уровень модуля в bot.py
  • Проверка наличия .env.env в .gitignore, есть .env.example
  • Команда !msg в BotRunner — удалена из проекта
  • Отсутствует .gitignore — файл существует
  • Отсутствует Dockerfile — файл существует
  • Отсутствует .env.example — файл существует
  • Type hints в production-коде — добавлены аннотации ко всем 20 функциям
  • asyncio.iscoroutinefunction deprecated — monkey-patch в bot.py + conftest.py
  • Утечка корутины Scheduler в тестах — mock _start_scheduler вместо asyncio.create_task
  • Graceful shutdown (SIGTERM) — реализован через on_shutdown listener + async with self.bot
  • Пустой __init__ в Morning — удалён
  • Global RateLimiter на модульном уровне — добавлены factory-функции make_*_limiter()
  • Type hints в тестах — добавлены -> None ко всем 140 test-функциям
  • import внутри функций в тестах — вынесены наверх модулей (35 вхождений)
  • Добавить pre-commit хуки.pre-commit-config.yaml (ruff + ruff-format), requirements-dev.txt
  • Интеграционные тесты — 9 тестов загрузок когов, команд и утилит
  • format_weather_for_embed отсутствует в коде — заменено на format_weather_for_message в README.md (README.md)
  • _WEATHER_MAPPING не отсортирован по убыванию длины ключей — отсортирован список по убыванию len(key), добавлен комментарий (utils/pogoda.py)
  • Глобальные requests.Session не закрываются — добавлена close_all_sessions() в utils/__init__.py, вызов из _on_shutdown в bot.py