Reminders Were Easier Than Expected
Adding pre-start reminders to tasks. Turns out a single computed field was all it took.
Reminders Were Easier Than Expected
In Fecit, you can set a start time for tasks. Meeting at 2pm, gym at 7pm. But setting a start time and then forgetting about it defeats the purpose. I needed reminders.
Reminders. The word alone conjures complexity. Schedulers, timezone handling, recurring notifications, local vs push. I’d been putting it off.
Turns out it was surprisingly simple.
The Key Idea: A Computed Field
My first instinct was to query for tasks at “current time + offset” in the batch job. 5 minutes before, 15 minutes before, 30 minutes before — a separate query condition for each offset.
Then I realized there’s a simpler way.
reminder_at = start_date - reminder_offset
When saving reminder_offset (how many minutes before), compute reminder_at (the actual notification time) and store it alongside. Then the batch query becomes:
task_record_collection.find({
'reminder_at': {'$gte': now, '$lt': now_end},
'state': TaskState.REGISTERED,
})
Doesn’t matter how many offset options exist. Adding new ones doesn’t change the query. Only one index needed: reminder_at.
What If start_date Changes?
reminder_at is derived from two values: start_date and reminder_offset. If either changes, reminder_at needs recalculation.
- When
reminder_offsetchanges: readstart_date, recompute - When
start_datechanges: readreminder_offset, recompute - If either is null:
reminder_at = null(no reminder)
Follow this rule and it’s always correct.
The UI
The reminder picker only shows when a start date exists. No start date, no reminder — it wouldn’t make sense.
Options are straightforward:
- At start date
- 5 min before start date
- 15 min before start date
- 30 min before start date
- 1 hour before start date
- 1 day before start date
Select one, it saves to the server, reminder_at is computed automatically. To clear, tap the X button next to the value — same pattern as the start date clear button.
Looking Back
I overthought it. The core insight was just “pre-compute the notification time so the query stays simple.” Everything else followed existing patterns.
Should have done it sooner.