← All stories

BRANCH · ef-051-email-designs-types

Email designs and message types

EF-051Persona: OrganizerRoots in: event-setup

An organizer creates reusable email designs, assigns message types such as invitation, confirmation, decline, save-the-date, manual, and ops, previews draft versus published state, and sends tests before any guest-facing send.

Preconditions

Organizer can access Event Setup and the fixture event has published and draft email designs plus invited, confirmed, bounced, and empty-audience recipients.

Happy path

  1. Open Email designs.

    The paginated design list shows design name, message type, draft/published status, and last test-send status.

  2. Edit a design body.

    The rich text editor preserves reusable design content separately from a single message send.

  3. Preview, publish, and send a test.

    Preview makes draft/published divergence obvious and test-send uses an idempotency key.

Failure modes

Send blocked on validation failure

Trigger: unresolved design token or invalid message type.

Resolution: send is blocked with 400 validation copy and no partial-send.

Bounced recipient tracked and suppressed

Trigger: a test recipient hard-bounces.

Resolution: bounce event is stored and future sends to that address are suppressed.

Scheduled-message edit window

Trigger: organizer edits a scheduled send using this design after the edit cutoff.

Resolution: API returns 409 PAST_EDIT_WINDOW and keeps the queued snapshot unchanged.

Retry on transient failure

Trigger: Cloudflare Email API returns 5xx during a design-backed send.

Resolution: retry uses the same Idempotency-Key and the recipient receives at most one email.

Idempotency-key on test-send

Trigger: organizer double-clicks Send test.

Resolution: one test email is queued and the per-test Idempotency-Key is sent.

Recipient resolution empty

Trigger: selected audience has zero recipients.

Resolution: API returns 409 NO_RECIPIENTS and the UI says no recipients match this audience.

Token rendering fallback

Trigger: {guest.firstName} is missing.

Resolution: preview and send use a fallback, never an awkward empty merge.

Cancel scheduled before send

Trigger: organizer cancels a scheduled design-backed message.

Resolution: queue pending count decrements, reserved sends are refunded, and cancellation is audited.

Preview versus published divergence

Trigger: draft content differs from the published design used for send.

Resolution: UI labels both snapshots and send uses the explicit selected snapshot.

Design-list pagination stability

Trigger: organizer changes page while filters are active.

Resolution: page and filter state remain URL-addressable and counts stay consistent.

Deployed-runtime gap

Trigger: deployed run on 2026-04-29 observed template API 404 for /admin/.../email-templates; the probe locks this in until the gap is closed.

Resolution: the story expects the documented 404 so a later 2xx fails the gap probe and prompts tightening.

Stable test attributes

Visibility teeth. Each attribute must be effectively visible when active.

data-testWherePurpose
email-designs-pagePageDesign manager
email-designs-tablePagePaginated designs
email-design-editorEditorDesign body
message-type-pickerFormMessage type
email-design-previewPreviewRendered snapshot
email-design-publish-ctaToolbarPublish
email-design-test-send-ctaToolbarTest-send
email-design-gap-panelPageRuntime gap
email-design-warningPageValidation warning

Agent test plan

- email-designs-renders
- publish-design
- test-send-idempotent
- deployed-runtime-gap