Event email reminders — handoff for next agent¶
Branch: feature/event-email-reminders (rebase from origin/master before PR if needed).
Done in latest commits¶
feat(email): event reminder send path with Cosmos idempotency—EventReminderSentDoc,CosmosDbEventReminderSentService.TryClaimSendAsync,EventEmailReminderSchedulerService,EventEmailServicereminder send,TriggerScheduleEmailinRaklet.WebJobs.Secondary/Email/EmailFunctions.cs.chore(social): remove dashboard Welcome Back copy— social dashboard template/styles,en.json/tr.json,RoleTestsHelperassertion.- Reminder UX + scheduler hardening (origin + follow-ups) — empty reminder-template dropdown / recurring copy (
event-upsert.html); scheduler recipient filter!= Error, Cosmos claim resilience, deterministic id separator (6ffd9ba4d,0a146e199). - JSON merge + provisioning + manager (2026-04-04) — API dedupe when Pascal + camel lists merge (
EventEmailReminderValidation); default Event reminder Template V2 from CDN with blob MJML (NewOrganisationGenericService); manager stripsEmailReminderson load/save;Cdn-Versionbump; consoleCdn-PathforEmailCacheService(4b63dc2d4…2db6235b9). - Public event details — removed top recurring series info banner from
Application/Areas/Events/Views/Home/Details.cshtml(occurrence list in sidebar unchanged). - Materialized reminder instances (2026-04-04+) — Cosmos
EventReminderInstanceDoc(eventreminderinstance);EventEmailReminderInstanceSyncServicerebuild on event update + sync on ticket payment create/update; scheduler processes pending stored rows in the minute window (no full payment scan); manager Per registrant table +GET .../email-reminder-instances; legacyeventremindersentmerged on rebuild;Content/dist/is gitignored; run Grunt locally or in deploy to build bundles.
Intentionally not committed (review locally)¶
- Line-ending-only “modified” files — e.g.
SubmembersEdit,events-list.*,events.scss,membership.scss— restore if they show as modified with no substantive diff. Models/WebJobModels/EventEmailReminderQueueMsg.cs— deleted (unused; scheduler runs inline in WebJob tick, not queue).
Untracked (do not auto-commit unless you mean to)¶
.context/,.gstack/,.pr-body-*.md- Use
docs/events/event-email-reminders-pr.mdfor the current PR description (materialized instances + UI).
Todo for next agent¶
- [x]
git fetch origin masterand confirm branch base; open PR againstmasterwhen ready. (See PR linked from branch / GitHub.) - [x]
.\scripts\dev\build-fast.ps1 Debug(stopRaklet.WebJobs.Secondaryif DLL copy fails — file locked). (Also:-Project Raklet.WebJobs.Secondarywhen that project changed.) - [ ] Run
scripts/dev/run-local-tests.ps1or your usual test pass; fix any failures. (MSTest:EventEmailReminderValidationTests,EventEmailReminderScheduleMathTests.) - [ ] Manual QA (hosted admin):
- Templates / event form: As before (default template, distinct offsets, dedupe, clone).
- Per registrant list: Event Details → Reminders — table loads from Cosmos (
eventreminderinstance); rows after registration; Sent at / status after WebJob processes duePendingrows. - Scheduler: Reminder fires in the correct minute window; pending instance rows are claimed (
Pending→Sent) then email sends. Recipients: same eligibility as before (non-error event ticket payments, not archived, buyer email present). - Event date/time changes: Saving the event runs rebuild — all instance rows for that event are recreated from current
EmailReminders+ start time + ticket payments; then legacyeventremindersentdocs are merged so historical sends stay Sent. Moving start after a reminder already sent for(event, offset, payment)still leaves that instance Sent (idempotent); new offsets or new payments get new rows. - Self-heal: First
GET email-reminder-instanceswith no instance docs but valid reminders triggers RebuildForEventAsync once (can be heavier on large registration lists). - [x] Details.cshtml recurring banner — removed (2026-04-04).
- [ ] Push branch after commits; paste
docs/events/event-email-reminders-pr.mdinto the GitHub PR body (or link). - Cosmos: No new container — same DB, new
DocTypefor instances.
Reference: architecture snapshot¶
| Concern | Where |
|---|---|
| Config on event | EventDoc.EmailReminders |
| Stored send rows | EventReminderInstanceDoc per payment × offset |
| Legacy idempotency marker | EventReminderSentDoc (merged on rebuild, not used for new claims in scheduler) |
| Scheduler entry | EmailFunctions.TriggerScheduleEmail → EventEmailReminderSchedulerService.ProcessDueRemindersForScheduleWindowAsync |
| Manager list API | V2EventsController.GetEmailReminderInstances |