5.3 KiB
5.3 KiB
План изменений: расписание напоминаний
Цели
- Добавить расписание для напоминаний: бот должен писать только в явно разрешенные часы.
- По умолчанию разрешенное окно: с 07:00 до 23:00 по МСК.
- Если пользователь сам написал заметку, следующий reminder должен быть отложен минимум на 1 час.
План
1. Расширить конфиг
- Добавить переменные в
.env.exampleиREADME.md:REMINDER_START_HOURREMINDER_END_HOURREMINDER_TIMEZONE
- Значения по умолчанию:
REMINDER_START_HOUR=7REMINDER_END_HOUR=23REMINDER_TIMEZONE=Europe/Moscow
- В
config.pyпарсить часы какint, timezone черезzoneinfo.ZoneInfo.
2. Изменить модель напоминаний
- Сейчас
send_reminders()просто спит случайное число секунд между min/max. - Нужно рассчитывать следующий момент отправки с учетом:
- разрешенного окна времени;
- случайного интервала
REMINDER_MIN_HOURS/REMINDER_MAX_HOURS; - timezone;
- ночного периода, когда отправка запрещена.
3. Добавить сброс после ручной заметки
- В
main.pyпосле успешногоjournal.append(...)сообщать планировщику, что пользователь сам написал заметку. - Простой вариант: передать в
send_reminders()общий объект состояния, напримерReminderSchedulerилиReminderState. - В состоянии хранить
last_manual_entry_at. - При ручной записи следующий reminder должен быть не раньше
last_manual_entry_at + 1 hour.
4. Сделать отдельную логику планирования
- Минимально оставить
send_reminders()вmodules/reminders.py, но добавить функции:is_allowed_time(now, start_hour, end_hour)next_window_start(now, start_hour, timezone)calculate_next_reminder(...)
- Не усложнять классами без необходимости, но небольшой объект состояния между handler и background task может быть оправдан.
5. Учесть edge cases
- Если сейчас ночь, следующий reminder переносится на 07:00 МСК.
- Если случайный интервал попадает за 23:00, reminder переносится на следующее 07:00.
- Если пользователь написал заметку в 22:30, минимальная задержка до 23:30, но окно уже закрыто, значит следующий reminder не раньше 07:00 следующего дня.
- Если пользователь написал ночью, reminder не раньше max(
+1 hour, ближайшее 07:00). - Если
REMINDER_START_HOUR >= REMINDER_END_HOUR, лучше сразу падать с понятной ошибкой, чтобы не поддерживать ночные окна.
6. Обновить документацию
- README на русском: описать новое окно отправки.
.env.example: добавить новые переменные.- При необходимости обновить
AGENTS.md, чтобы зафиксировать новые env vars и правило про timezone.
7. Проверка
- Запустить
uv run python -m compileall main.py config.py modules. - Если добавятся чистые функции расчета времени, можно добавить тесты позже, но сейчас отдельной тестовой инфраструктуры нет.
Лог реализации
- Шаг 1: добавлены настройки
REMINDER_START_HOUR,REMINDER_END_HOUR,REMINDER_TIMEZONEвconfig.py; часы валидируются как диапазон 0-23, окно должно быть start < end. - Шаг 2: в
modules/reminders.pyдобавлен минимальныйReminderState, расчет следующего reminder с учетом окна времени и пробуждение sleep черезasyncio.Eventпри ручной записи. - Шаг 3:
main.pyсоздаетReminderState, передает его вsend_reminders()и вызываетmark_manual_entry()после успешного сохранения заметки. - Шаг 4: обновлены
.env.example,README.mdиAGENTS.mdс новыми настройками окна напоминаний, timezone и правилом задержки после ручной заметки. - Проверка:
uv run python -m compileall main.py config.py modulesпрошла успешно;uvсоздал локальную.venv, она игнорируется.gitignore.