Allow users to choose digest schedule (time of day, day of week, timezone) #28
Loading…
Reference in a new issue
No description provided.
Delete branch "mailship-200-allow-users-to-choose-digest-schedule-ti-60c"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
mailship-200
Users currently receive digests on a fixed schedule: daily at 17:00 UTC, weekly on Monday at 17:00 UTC. This PR lets each user choose the time of day for their daily digest, and the time + day of week for their weekly digest, with per-user IANA timezone support.
DB migration — adds
hour(INTEGER DEFAULT 17),minute(INTEGER DEFAULT 0),day_of_week(INTEGER, nullable), andtimezone(TEXT DEFAULT 'UTC') columns to thesubscriptionstable. Existing rows backfill to 17:00 UTC — unchanged behaviour. The migration is idempotent: new tables get the columns from CREATE TABLE; existing databases run ALTER TABLE ADD COLUMN with duplicate-column error suppression.Cron & worker —
getCronExpressionnow accepts an optionaldayOfWeekparameter for weekly cron shapes. The digest worker reads the stored hour/minute/dayOfWeek/timezone from each subscription when creating the cron job and passes the IANA timezone toCronJob.from()instead of the hardcoded'UTC'. Changing a subscription (via the existingregisterSubscriptionpath) reschedules the running job immediately.API —
PUT /subscription/emailaccepts optionalhour(0–23),minute(0–59),dayOfWeek(1=Mon…7=Sun, only valid for weekly frequency), andtimezone(IANA, validated viaIntl.DateTimeFormat). Omitted fields fall back to the defaults (17:00 UTC).GET /subscription/emailreturns the schedule fields in its response.How to test —
pnpm run test:unitruns the full suite including the newtest/schedule-fields.test.ts(9 tests covering custom inserts, cron shaping, job registration, and field preservation through updates). Manual acceptance:PUT {email, frequency:"daily", hour:7, minute:30, timezone:"America/New_York"}fires the daily job at 07:30 wall-clock in that zone;PUT {frequency:"weekly", dayOfWeek:6, hour:9}fires Saturday 09:00.