events: reschedule notifications + 7 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s

ev/reschedule-notifications: when an event carries per-occurrence overrides,
reads the roster at each overridden occurrence's original occ-key and emits a
reschedule message per booked attendee (old-start/new-start/new-duration).
Idempotency key = original-key/reschedule/new-start. 272/272 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 07:47:00 +00:00
parent 98ed2eebdf
commit 07e4cb5f4a
5 changed files with 121 additions and 7 deletions

View File

@@ -208,6 +208,61 @@
(get empty-dig :items)
(list)))))))))
;; ---- reschedule notifications ----
(define
ev-rm-rs-run-all!
(fn
()
(let
((b (persist/open))
(ev (ev-event (quote yoga) (ev-dt 2026 6 1 9 0) 60 {:freq :daily :count 3} 20)))
(let
((occ2 (ev-occ (quote yoga) (ev-dt 2026 6 2 9 0) 60)))
(do
(ev/book-occ! b (ev/add-event (ev/empty) ev) (quote nia) occ2)
(ev/book-occ! b (ev/add-event (ev/empty) ev) (quote ola) occ2)
;; reschedule the Jun 2 occurrence to 14:00 / 90 min
(let
((moved (ev-with-override ev (ev-dt 2026 6 2 9 0) (ev-dt 2026 6 2 14 0) 90)))
(let
((ns (ev/reschedule-notifications b moved)))
(do
(ev-rm-check!
"every booked attendee is notified of the reschedule"
(map (fn (n) (get n :recipient)) ns)
(list (quote nia) (quote ola)))
(ev-rm-check!
"reschedule carries old and new start"
(list (get (first ns) :old-start) (get (first ns) :new-start))
(list (ev-dt 2026 6 2 9 0) (ev-dt 2026 6 2 14 0)))
(ev-rm-check!
"reschedule carries the new duration"
(get (first ns) :new-duration)
90)
(ev-rm-check!
"reschedule idempotency key encodes original key + new start"
(get (first ns) :id)
(str (ev-occ-key occ2) "/reschedule/" (ev-dt 2026 6 2 14 0)))
(ev-rm-check!
"reschedule projects to notify wire shape"
(ev/reschedule-notify->msg (first ns))
(list
(str (ev-occ-key occ2) "/reschedule/" (ev-dt 2026 6 2 14 0))
(quote nia)
(list :rescheduled (quote yoga) (ev-dt 2026 6 2 9 0) (ev-dt 2026 6 2 14 0)))))))
;; an override on an occurrence nobody booked notifies no one
(let
((moved2 (ev-with-override ev (ev-dt 2026 6 3 9 0) (ev-dt 2026 6 3 10 0) 60)))
(ev-rm-check!
"rescheduling an unbooked occurrence notifies no one"
(len (ev/reschedule-notifications b moved2))
0))
;; an event with no overrides yields no reschedule notifications
(ev-rm-check!
"event without overrides has no reschedule notifications"
(len (ev/reschedule-notifications b ev))
0))))))
(define
ev-reminders-tests-run!
(fn
@@ -217,4 +272,5 @@
(set! ev-rm-fail 0)
(set! ev-rm-failures (list))
(ev-rm-run-all!)
(ev-rm-rs-run-all!)
{:failures ev-rm-failures :total (+ ev-rm-pass ev-rm-fail) :passed ev-rm-pass :failed ev-rm-fail})))