feat: "Email sent" column and per-event copy-to-organizer BCC #47

Closed
padreug wants to merge 3 commits from feat/ticket-email-sent-copy into main
Owner

Stacked on #44 (rebased onto main as aio.14) — merge #44 first; after that this PR shows only its own commits.

After the first production sales the organizer had no way to see whether a ticket email went out short of the Postfix journal, and no copy of what the attendee received (LNbits submits over SMTP; nothing lands in a Sent folder).

  • Admin ticket table: "Email sent" column from extra.email_notification_sent — "✓ sent" / "not sent" / "unpaid" / "no email".
  • extra.copy_to_organizer: BCC every ticket email to the event's reply-to (explicit, else the owner's account email) on the SMTP envelope only — no Bcc/To header, skipped when the buyer is that address. Toggle sits with the other delivery switches in the admin form; webapp counterpart on aiolabs/webapp#148.

42 tests (new: envelope BCC without header leak); black / ruff / prettier clean. config.json → 1.6.1-aio.15.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo

Stacked on #44 (rebased onto `main` as `aio.14`) — **merge #44 first**; after that this PR shows only its own commits. After the first production sales the organizer had no way to see whether a ticket email went out short of the Postfix journal, and no copy of what the attendee received (LNbits submits over SMTP; nothing lands in a Sent folder). - Admin ticket table: **"Email sent"** column from `extra.email_notification_sent` — "✓ sent" / "not sent" / "unpaid" / "no email". - `extra.copy_to_organizer`: BCC every ticket email to the event's reply-to (explicit, else the owner's account email) on the **SMTP envelope only** — no Bcc/To header, skipped when the buyer *is* that address. Toggle sits with the other delivery switches in the admin form; webapp counterpart on aiolabs/webapp#148. 42 tests (new: envelope BCC without header leak); black / ruff / prettier clean. `config.json` → `1.6.1-aio.15`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
feat: per-event organizer name + reply-to on ticket emails (1.6.1-aio.14)
Some checks failed
lint.yml / feat: per-event organizer name + reply-to on ticket emails (1.6.1-aio.14) (pull_request) Failing after 0s
3d47862181
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
Organizers had no way to see whether a ticket email went out short of
reading the Postfix journal, and no copy of what the attendee received —
LNbits submits over SMTP, so nothing lands in a Sent folder.

- Admin ticket table gains an "Email sent" column derived from
  `extra.email_notification_sent` ("✓ sent" / "not sent" / "unpaid" /
  "no email").
- `extra.copy_to_organizer`: BCC every ticket email to the event's
  reply-to address (explicit, else the owner's account email) on the SMTP
  envelope only — no Bcc/To header, and skipped when the buyer *is* that
  address. Toggle sits with the other delivery switches in the admin form.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
docs: copy-to-organizer + Email sent column
Some checks failed
lint.yml / docs: copy-to-organizer + Email sent column (pull_request) Failing after 0s
60048a2687
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
padreug force-pushed feat/ticket-email-sent-copy from 60048a2687
Some checks failed
lint.yml / docs: copy-to-organizer + Email sent column (pull_request) Failing after 0s
to f04ff73b28
Some checks failed
lint.yml / docs: copy-to-organizer + Email sent column (pull_request) Failing after 0s
2026-09-13 16:19:38 +00:00
Compare
padreug changed title from feat: "Email sent" column and per-event copy-to-organizer BCC (v1.6.1-aio.15) to feat: "Email sent" column and per-event copy-to-organizer BCC 2026-09-13 16:20:12 +00:00
Author
Owner

Closing without merge: only the "Email sent" column is wanted now — re-cut as a single-commit PR off main (feat/ticket-email-sent-column). The copy-to-organizer BCC is deferred with #44's work; branch feat/ticket-email-sent-copy stays on origin.

Closing without merge: only the "Email sent" column is wanted now — re-cut as a single-commit PR off `main` (`feat/ticket-email-sent-column`). The copy-to-organizer BCC is deferred with #44's work; branch `feat/ticket-email-sent-copy` stays on origin.
padreug closed this pull request 2026-09-13 16:40:29 +00:00
Some checks failed
lint.yml / docs: copy-to-organizer + Email sent column (pull_request) Failing after 0s

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/events!47
No description provided.