Files
memoir_bot/current-task.md
2026-07-06 13:30:48 +03:00

5.3 KiB
Raw Permalink Blame History

План изменений: расписание напоминаний

Цели

  1. Добавить расписание для напоминаний: бот должен писать только в явно разрешенные часы.
  2. По умолчанию разрешенное окно: с 07:00 до 23:00 по МСК.
  3. Если пользователь сам написал заметку, следующий reminder должен быть отложен минимум на 1 час.

План

1. Расширить конфиг

  • Добавить переменные в .env.example и README.md:
    • REMINDER_START_HOUR
    • REMINDER_END_HOUR
    • REMINDER_TIMEZONE
  • Значения по умолчанию:
    • REMINDER_START_HOUR=7
    • REMINDER_END_HOUR=23
    • REMINDER_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.