feat: per-event organizer name + reply-to on ticket emails
Some checks failed
lint.yml / feat: per-event organizer name + reply-to on ticket emails (pull_request) Failing after 0s

Each organizer is different, so the sender identity of ticket emails is
now per event rather than per instance:

- `extra.organizer_name` → From display name "Organizer via <site title>"
  (site title alone when unset). The From address stays the instance
  mailbox — that is what DKIM signs — so this costs nothing in mail auth.
- `extra.reply_to_email` → Reply-To; blank falls back to the email on the
  LNbits account that owns the event wallet; no header when neither
  exists. When a reply-to exists the body says "Questions? Reply to this
  email and it reaches <organizer>", and "Organizer: <name>" is listed
  with the ticket details.

Both fields sit next to the existing per-event subject/body in the admin
dialog. The organizer's own wording (in whatever language) remains
`notification_body`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
This commit is contained in:
Padreug 2026-09-09 12:34:19 +02:00
commit 72b9c540f7
7 changed files with 193 additions and 25 deletions

View file

@ -31,6 +31,20 @@ class EventExtra(BaseModel):
nostr_notifications: bool = False
notification_subject: str = ""
notification_body: str = ""
# Sender identity for ticket emails, per event: the From display name
# becomes "<organizer_name> via <site title>" and replies go to
# `reply_to_email` (falls back to the event owner's account email).
# The From *address* stays the instance mailbox — that is what DKIM
# signs — so organizers get a human sender without touching mail auth.
organizer_name: str = ""
reply_to_email: EmailStr | None = None
@validator("reply_to_email", pre=True)
def blank_reply_to_is_none(cls, v):
if isinstance(v, str) and not v.strip():
return None
return v
# Rails the organizer accepts for this event. Empty = legacy rule
# ("lightning" always, "fiat" when allow_fiat) — see
# `effective_payment_methods`. Same field name/shape as upstream v2 so the