Skip to content
This repository was archived by the owner on Apr 6, 2026. It is now read-only.

feat(reminder): rewrite module with smart loop, calendar scheduling, and timezone support#199

Merged
karaktaka merged 10 commits into
mainfrom
feat/reminder-rewrite
Feb 19, 2026
Merged

feat(reminder): rewrite module with smart loop, calendar scheduling, and timezone support#199
karaktaka merged 10 commits into
mainfrom
feat/reminder-rewrite

Conversation

@karaktaka
Copy link
Copy Markdown
Contributor

@karaktaka karaktaka commented Feb 18, 2026

Summary

Closes #175

  • Smart hybrid loop: Replaces the old 30-second polling loop with a dynamic interval (5s-60s) that queries WHERE NextFire <= NOW() and adjusts sleep based on the next due reminder
  • Two command UX: /reminder create in:<delay> message [channel] [repeat] for interval-based reminders, /reminder schedule for calendar-based (daily/weekly/monthly) with timezone autocomplete
  • New data model: Absolute NextFire timestamps, ScheduleType column (once/interval/daily/weekly/monthly), per-reminder Timezone (IANA), with Alembic migration preserving existing data
  • Utilities: parse_duration() for human-friendly input (2h30m, 1d12h, 1w), compute_next_fire() for DST-aware calendar recomputation
  • Pause/resume: Paused reminders skip firing; resume recalculates NextFire if it's in the past
  • UX cleanup: Renamed duration param to in (reads naturally), removed confusing start param

Test plan

  • 252 tests passing (including 13 cog tests, 17 schedule tests, 13 duration tests, 14 model tests)
  • Ruff check + format clean
  • Manual smoke test: create one-shot, repeating, daily, and weekly reminders
  • Verify migration on a copy of production DB
  • Test pause/resume cycle with past NextFire

🤖 Generated with Claude Code

karaktaka and others added 9 commits February 19, 2026 11:08
Introduce parse_duration() backed by pytimeparse2 for human-friendly
duration strings (e.g. '2h30m', '1d12h', '90s'). Bare integers are
treated as minutes for backward compatibility. Enforces a 60-second
minimum. Includes full test suite (12 tests).

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…olumns

Co-Authored-By: Claude <noreply@anthropic.com>
…lumns

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
The 'duration' parameter was ambiguous (delay vs runtime?) and 'start'
created confusing interactions with 'duration' depending on repeat mode.
Renamed to 'in' (reads naturally: "remind in 2h30m") using
@app_commands.rename, and removed 'start' entirely since /reminder
schedule already covers calendar-based timing.

Co-Authored-By: Claude <noreply@anthropic.com>
Add new utility modules (duration, schedule) to the utilities section
and document gotchas discovered during the rewrite: plans gitignored,
app_commands.callback testing pattern, rename decorator, and
dialect-aware Alembic migrations.

Co-Authored-By: Claude <noreply@anthropic.com>
@karaktaka karaktaka force-pushed the feat/reminder-rewrite branch from 9a917e6 to 8dfa025 Compare February 19, 2026 10:09
@karaktaka karaktaka merged commit 20395e8 into main Feb 19, 2026
7 checks passed
@karaktaka karaktaka deleted the feat/reminder-rewrite branch February 19, 2026 14:39
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rewrite reminder module: absolute timestamps, scheduled triggers, and task-based execution

1 participant