discordBot/ISSUES.md

48 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ISSUES — Задачи и баг-трекер
## Средний приоритет
- [ ] **`_parse_date` хрупкий fallback** — `pub_date[:10].replace("-", ".")` для невалидной строки вернёт мусор (например `"invalid.da"`). Добавить валидацию формата (`utils/news.py`)
- [ ] **`wmo_to_russian` создаёт dict на каждый вызов** — mapping из 30+ элементов пересоздаётся. Вынести в модульную константу (`utils/pogoda.py`)
- [ ] **`TextHelpCommand` пропускает команды без cog** — `if 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.py`** — `COPY` пропускает `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`)
---
## Исправлено
- [x] ~~Эмодзи в embed-сообщениях~~ — удалены `🌅`, `✅`, `❌` из `utils/morning_runner.py`
- [x] ~~f-string в logger~~ — замена на `%`-формат в `bot.py`
- [x] ~~`import time` внутри `__init__`~~ — перенесён на уровень модуля в `bot.py`
- [x] ~~Проверка наличия `.env`~~`.env` в `.gitignore`, есть `.env.example`
- [x] ~~Команда `!msg` в BotRunner~~ — удалена из проекта
- [x] ~~Отсутствует `.gitignore`~~ — файл существует
- [x] ~~Отсутствует Dockerfile~~ — файл существует
- [x] ~~Отсутствует `.env.example`~~ — файл существует
- [x] **Type hints в production-коде** — добавлены аннотации ко всем 20 функциям
- [x] **`asyncio.iscoroutinefunction` deprecated** — monkey-patch в `bot.py` + `conftest.py`
- [x] **Утечка корутины Scheduler в тестах** — mock `_start_scheduler` вместо `asyncio.create_task`
- [x] **Graceful shutdown (SIGTERM)** — реализован через `on_shutdown` listener + `async with self.bot`
- [x] **Пустой `__init__` в Morning** — удалён
- [x] **Global RateLimiter на модульном уровне** — добавлены factory-функции `make_*_limiter()`
- [x] **Type hints в тестах** — добавлены `-> None` ко всем 140 test-функциям
- [x] **`import` внутри функций в тестах** — вынесены наверх модулей (35 вхождений)
- [x] **Добавить pre-commit хуки**`.pre-commit-config.yaml` (ruff + ruff-format), `requirements-dev.txt`
- [x] **Интеграционные тесты** — 9 тестов загрузок когов, команд и утилит
- [x] **`format_weather_for_embed` отсутствует в коде** — заменено на `format_weather_for_message` в README.md (`README.md`)
- [x] **`_WEATHER_MAPPING` не отсортирован по убыванию длины ключей** — отсортирован список по убыванию `len(key)`, добавлен комментарий (`utils/pogoda.py`)
- [x] **Глобальные `requests.Session` не закрываются** — добавлена `close_all_sessions()` в `utils/__init__.py`, вызов из `_on_shutdown` в `bot.py`
- [x] **`run_morning` fallback может отправить дайджест в несколько каналов** — fallback перебирает каналы целевого сервера вместо `bot.get_all_channels()` (`utils/morning_runner.py`)
- [x] **`!nw`: последовательные вызовы API вместо параллельных** — заменено на `asyncio.gather()` (`commands/news.py`)
- [x] **`format_weather_data_for_console` выводит `None` в текст** — добавлена явная проверка `is None` для всех полей (`utils/pogoda.py`), обновлён тест (`tests/test_commands_pg.py`)