Skip to content

Events: notify guests on cancellation and keep cancelled pages visible - #294

Merged
alexeygrigorev merged 2 commits into
mainfrom
events-cancellation-notifications
Sep 22, 2026
Merged

alexeygrigorev merged 2 commits into
mainfrom
events-cancellation-notifications

Conversation

@alexeygrigorev

Copy link
Copy Markdown
Member

Goal

Make event cancellation a package feature: guests are notified when an event is cancelled, the invite can be removed from their calendar, and the event page says "Cancelled" instead of 404ing. Requested by the product owner after cancelling a live event on the AISL site (which ships its own copy in the old-generation app); this brings the capability to every site via community_base.events.

What changed

  • cancel_event is idempotent (re-cancelling no longer re-bumps ics_sequence or re-notifies), skips the event's pending reminders, and after commit dispatches an events.notify_cancellation job.
  • The job mails one events.event_cancelled delivery per active registration (pending_verification/confirmed), deduped by events.cancellation:{registration}:{ics_sequence}. Inactive registrations are never mailed; series subscribers are covered because they are enrolled as regular registrations at publish time.
  • mail_context resolves the absolute event_url and calendar_cancel_url for the new purpose (requires SITE_URL, per the C7.27 rule).
  • calendar.ics serves a METHOD:CANCEL / STATUS:CANCELLED invite for cancelled events, so the email's one-click link removes the calendar entry. The package mail pipeline carries no attachments; the cancel invite is link-based, not inline.
  • Cancelled events keep their detail page (Cancelled badge, schema.org EventCancelled JSON-LD) instead of 404ing, while staying out of public listings; registration stays closed (_require_available already rejects non-upcoming events).
  • The reminder send handler skips reminders whose event is no longer upcoming (event_inactive).
  • Relay-side, the events.event_cancelled template is an operator step in the transactional catalog, as for the other events purposes.

Verification

  • uv run ruff check . — clean; uv run ruff format --check . — 846 files formatted.
  • uv run python testproject/manage.py check — no issues; makemigrations --check --dry-run — no changes detected (no model change).
  • uv sync --all-extras; uv run pytest tests/ — 2211 passed (events: 118, incl. 9 new tests).
  • uv run pytest tests/test_boundaries.py — passed.
  • Consumer (DataTalksClub/website checkout, linked via P1 playbook to this branch): events/tests, core/tests (kernel, repository contracts, homepage), event_registrants, review_import/tests/test_workflow.py — 137 passed + 228 subtests.

Notes for adoption

  • Consumers pick this up by bumping the pin to v0.5.6 (version bumped here).
  • Each site needs an events.event_cancelled template in its Relay transactional catalog (context: event_url, calendar_cancel_url, event_title, event_start, event_timezone, manage-style registration context) before cancellation mails deliver; until then deliveries fail loudly and retry, per the SITE_URL/purpose rule.

Cancel now reaches the guests, not just the database. cancel_event is
idempotent, skips the event's pending reminders, and after commit
dispatches an events.notify_cancellation job that mails one
events.event_cancelled delivery per active registration, deduped by
registration and ics_sequence. The mail context resolves the absolute
event URL and a calendar_cancel_url; for a cancelled event calendar.ics
serves a METHOD:CANCEL invite so the guest can remove the calendar entry
(the package mail pipeline carries no attachments, so the cancel invite
is a one-click link rather than an inline attachment).

A cancelled event keeps its detail page with a Cancelled badge and
schema.org EventCancelled status instead of 404ing, while staying out of
public listings; registration remains closed. The reminder send handler
skips reminders whose event is no longer upcoming. Relay-side, the
events.event_cancelled template is an operator step in the transactional
catalog, as for the other events purposes.
@alexeygrigorev
alexeygrigorev merged commit 724eb25 into main Sep 22, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant