Skip to content

Event email reminders — handoff for next agent

Branch: feature/event-email-reminders (rebase from origin/master before PR if needed).

Done in latest commits

  1. feat(email): event reminder send path with Cosmos idempotencyEventReminderSentDoc, CosmosDbEventReminderSentService.TryClaimSendAsync, EventEmailReminderSchedulerService, EventEmailService reminder send, TriggerScheduleEmail in Raklet.WebJobs.Secondary/Email/EmailFunctions.cs.
  2. chore(social): remove dashboard Welcome Back copy — social dashboard template/styles, en.json / tr.json, RoleTestsHelper assertion.
  3. 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).
  4. 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 strips EmailReminders on load/save; Cdn-Version bump; console Cdn-Path for EmailCacheService (4b63dc2d42db6235b9).
  5. Public event details — removed top recurring series info banner from Application/Areas/Events/Views/Home/Details.cshtml (occurrence list in sidebar unchanged).
  6. Materialized reminder instances (2026-04-04+) — Cosmos EventReminderInstanceDoc (eventreminderinstance); EventEmailReminderInstanceSyncService rebuild 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; legacy eventremindersent merged 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.scssrestore if they show as modified with no substantive diff.
  • Models/WebJobModels/EventEmailReminderQueueMsg.csdeleted (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.md for the current PR description (materialized instances + UI).

Todo for next agent

  • [x] git fetch origin master and confirm branch base; open PR against master when ready. (See PR linked from branch / GitHub.)
  • [x] .\scripts\dev\build-fast.ps1 Debug (stop Raklet.WebJobs.Secondary if DLL copy fails — file locked). (Also: -Project Raklet.WebJobs.Secondary when that project changed.)
  • [ ] Run scripts/dev/run-local-tests.ps1 or 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 due Pending rows.
  • Scheduler: Reminder fires in the correct minute window; pending instance rows are claimed (PendingSent) 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 legacy eventremindersent docs 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-instances with 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.md into the GitHub PR body (or link).
  • Cosmos: No new container — same DB, new DocType for 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.TriggerScheduleEmailEventEmailReminderSchedulerService.ProcessDueRemindersForScheduleWindowAsync
Manager list API V2EventsController.GetEmailReminderInstances