Add named reminders with multiple times and day schedules

This commit is contained in:
syntaxbullet
2026-09-08 07:36:49 +02:00
parent 8ba23961ef
commit 8e846fa11b
12 changed files with 1341 additions and 53 deletions

View File

@@ -379,27 +379,39 @@ existing delivery does not consume quota. Rejected attempts consume quota too;
An empty list permits all signed-in accounts. Restricted users can still preview
and download PNGs. Quota rows expire and are pruned after 24 hours.
### Daily reminders
### Reminders
Open **Settings → Daily reminders** to opt into one private Discord DM when habits
remain unfinished. Choose a local time and quiet hours; times follow the account
timezone. Quiet-hour start is inclusive, end is exclusive, and equal times disable
quiet hours. If the scheduled time falls in quiet hours, delivery waits until they
end that same local day. A reminder missed for the whole day is not carried forward.
Open **Settings → Reminders** to configure up to 20 reminders, each with an optional
name (up to 80 characters), local time, and selected weekdays or a specific date.
Select all seven days for a daily reminder. Discord messages include any reminder names that were set, along with the
unfinished-habit count and app link. Combined nudges include the applicable names. Reminders
only send when habits remain unfinished, and times follow the account timezone.
Quiet-hour start is inclusive, end is exclusive, and equal times disable quiet
hours. Overdue reminders are combined into one nudge when quiet hours end or the
server resumes, then later scheduled times continue normally. Overlapping entries
at the same time produce one nudge. Missed reminders never carry into another day.
Editing a name or removing and re-adding a time does not resend an already delivered
slot that day; adding a past time can trigger a nudge on the next worker tick.
The production server checks once a minute. `DISCORD_BOT_TOKEN` enables delivery;
a sharing channel is not required for reminders. Users must be reachable by the
bot (normally a shared Discord server and enabled DMs). A message contains only
the unfinished-habit count and app link. Settings show the most recent delivery
result, including blocked DMs or unconfirmed delivery. Uncheck the option and save
to opt out. No reminders are enabled by default.
a sharing channel is not required. Users must be reachable by the bot (normally a
shared Discord server and enabled DMs). Settings show the most recent delivery
result. Uncheck the option and save to opt out. Reminders are disabled by default.
`GET /api/reminders` returns settings and last delivery status. `PUT /api/reminders`
requires authentication, matching Origin, and `{enabled, time, quietStart, quietEnd}`
with `HH:MM` times. Per-user/date reservations persist across restarts and concurrent
workers. Discord 429 retry deadlines are persisted; ambiguous message sends are
not retried that day. Delivery records expire after 90 days. Restore disables
reminders in the recovered database until users opt in again.
requires authentication, matching Origin, and `{enabled, reminders, quietStart,
quietEnd}`. Times use `HH:MM`. Each reminder is either
`{type: "weekly", name?: string, time: "09:00", days: [1, 3, 5]}` (Sunday is 0) or
`{type: "date", name?: string, time: "18:00", date: "2026-09-08"}`.
The legacy single `time` input remains supported. Existing settings retain their
daily schedule; pre-upgrade deliveries prevent another nudge that same day.
Per-user/date/time reservations persist across restarts and concurrent workers.
Discord 429 retry deadlines are persisted; ambiguous sends are not retried for
that time slot. Later reminders can still send. Delivery records expire after
90 days. Account export includes schedules and names; restore disables reminders
until users opt in again.
The disposable `SHARE_PREVIEW=1 bun scripts/dashboard-preview.ts` mode also runs a
reminder worker against a local transport stub. Set a reminder to `14:00` (its fixed