discordBot/ISSUES.md

7.8 KiB
Raw Blame History

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


Исправлено

  • Эмодзи в 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
  • run_morning fallback может отправить дайджест в несколько каналов — fallback перебирает каналы целевого сервера вместо bot.get_all_channels() (utils/morning_runner.py)
  • !nw: последовательные вызовы API вместо параллельных — заменено на asyncio.gather() (commands/news.py)
  • format_weather_data_for_console выводит None в текст — добавлена явная проверка is None для всех полей (utils/pogoda.py), обновлён тест (tests/test_commands_pg.py)
  • _parse_date хрупкий fallback — валидация формата через regex, ISO даты конвертируются в DD.MM.YYYY (utils/news.py)
  • wmo_to_russian создаёт dict на каждый вызов — вынесен в константу _WMO_MAPPING (utils/pogoda.py)
  • TextHelpCommand пропускает команды без cog — standalone-команды показываются если не hidden (bot.py)
  • translate_weather(" ") возвращает пробелы — добавлен .strip() перед проверкой (utils/pogoda.py)
  • pressure_to_mmhg(mb: Any) — заменён на float | int | str | None (utils/pogoda.py)
  • conftest.py и bot.py дублируют monkey-patch — вынесен в utils/compat.py, оба файла импортируют оттуда
  • RateLimiter тесты зависят от реального времени — добавлен _time_func параметр, все тесты используют контролируемую функцию времени
  • Dockerfile не копирует conftest.py — добавлен COPY conftest.py .
  • requirements.txt без пиннинга версий>= заменён на ~= (compatible release)
  • Закомментированный тест pressure_to_mmhg(0) — удалена устаревшая закомментированная строка
  • format_articles(None) бросает TypeError — добавлена валидация None, graceful fallback с сообщением
  • setup_logging() создаёт дублирующиеся handlers — добавлен root.handlers.clear() (utils/logger.py)
  • Первый logger.info() теряетсяsetup_logging() вызывается до первого лога (bot.py)
  • translate_weather() уязвим к ложным substring-совпадениям — точное совпадение приоритизируется (utils/pogoda.py)

Открытые задачи

Критические

  • setup_logging() создаёт дублирующиеся handlers — добавлен root.handlers.clear() перед добавлением новых хендлеров (utils/logger.py)
  • Первый logger.info() теряетсяsetup_logging() перемещён до первого logger.info() (bot.py)
  • translate_weather() уязвим к ложным substring-совпадениям — добавлена проверка точного совпадения (case-insensitive) перед substring-matching (utils/pogoda.py)

Средние

  • fromstring импортирован внутри функции fetch_rss — вынесен на уровень модуля (utils/news.py)
  • Scheduler._start_scheduler() создаёт task синхронно__init__ больше не создаёт task; start() стал async-методом (utils/morning_runner.py, bot.py)
  • Pg.__init__ хранит self.api_url как инстанс-переменную — удалён __init__, используется API_URL_WEATHER напрямую (commands/pg.py)
  • fetch_cat() не передаёт x-api-key — добавлена поддержка CAT_API_KEY из окружения, заголовок x-api-key передаётся при наличии ключа (utils/cat.py)

Низкие

  • Глобальные экземпляры RateLimiter + factory-функции — factory-функции make_*_limiter() существуют, но production-код импортирует глобальные переменные напрямую (utils/rate_limiter.py, строки 94-97)
  • @pytest.mark.asyncio избыточенpytest.ini уже содержит asyncio_mode = auto (tests/test_integration.py)
  • Dockerfile не копирует tests/ — нельзя запустить pytest внутри контейнера, затрудняет отладку в Docker
  • Приватные атрибуты на объекте ботаself.bot._start_time и self.bot._scheduler нарушают инкапсуляцию (bot.py, строки 116, 148)
  • Избыточная проверка ctx в on_command_errorctx всегда передан и не может быть None (bot.py, строки 138-143)