docs: обновлён ISSUES.md — 3 критические задачи перенесены в исправленные

This commit is contained in:
deadzilla 2026-07-11 23:31:27 +05:00
parent c5c6a51cd2
commit e2289e5092

View File

@ -1,5 +1,30 @@
# 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` хрупкий 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`
@ -10,19 +35,16 @@
- [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] **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`