19-May-2026 — recipient send history and single-member mode ref: #275
build 649 — commit f9744c2
In plain English
When you send one of the automatic emails - for example the membership expiry warning - the composer remembers who has already been sent that same email and leaves them out, so re-running a send only reaches people who have not had it yet. Nobody is dropped silently: the composer tells you how many were left out, lets you see exactly who, and lets you send to them again if you really mean to.
Members already sent are left out
In this example the membership expiry warning is being sent to everyone with an email address. Six members had already received it on 13 June, so they are left out automatically and the recipient count is 354 rather than the full 360. A notice explains how many were excluded and when, and Show who lists exactly which members they are and the date each was last sent it. With the box left unticked, the email only reaches people who have not already had it.

With Re-send unticked, members who already received this email are left out - the notice and Show who list name them, and the count is 354 of 360.
Send to them again if you mean to
If you deliberately want the already-sent members included - for example you have revised the email and want everyone to get the new version - tick Re-send to members already sent this email. They are added back, the notice changes to say they are being re-sent, and the count returns to the full 360.

With Re-send ticked, the six already-sent members are added back in and the count returns to 360.
When an email type deletes its recipients
A few email types are set up to remove members after the email goes out - for example a final membership-expiry email that clears lapsed members from the database. When you choose one of these, the composer shows a clear warning at both the Recipients and Send steps, so it can never happen by accident. The Send step spells out exactly how many members will be permanently removed, and that it cannot be undone:

The Send step names the exact number of members that will be permanently removed - here 360 - and warns that it cannot be undone.
The technical detail
Follow-up work on the email composer for #275.
Recipient send history and de-duplication
- New
memberEmailSendscollection records every successful member send, tagged with the notification config used, exposed through a new/api/database/member-email-sendsendpoint.

- The recipient picker no longer auto-selects members who have already received the selected email type. They stay selectable and are labelled with the date they were last sent it, so an admin can still re-pick them deliberately. This applies to every email type, not only "Welcome to The Group".
Single-member mode
- Opening the composer from a member's "Send email" action now shows a dedicated single-member panel naming the recipient, instead of the recipient-mode and pre-filter controls that do not apply to a one-person send. A "choose recipients" link reopens the full picker, and "Start a new email" clears the mode.
Recipient selection
- "Missing from bulk load" selection compares each member's last bulk-load date against the email type's months-in-past, so a 2-month warning config and a 3-month expiry config select different members.
- The admin composer reads members through a new admin-only
privilegedFields()set (adding membershipNumber, memberStatus, memberTerm and updatedDate) rather than widening the fields served to every authenticated member. - The recipient-mode and "Choose members from" radios are hidden unless the "All with email" pre-filter is active, removing clutter from config-driven sends.
- The "Recipients chosen" summary now sits below the member list.
Bulk deletion safety
- When the selected email type is configured to delete its recipients, the Recipients and Send steps show a clear warning naming how many members will be permanently removed.
Composer fixes and UI
- The branded/unbranded toggle no longer leaves the email-type section empty.
- The unbranded sender-role alert shows the selected role's description.
- Fixed a crash when articleBlocks was undefined.
- Forwarded-email paste appends to the body instead of replacing it.
- The collapsed "group members" fieldset shows a hint, and "Recipients for this send" is collapsible.
- Recipient badges distinguish "Already saved" from "Will be saved for re-use".
- "Send email" on the member-admin row menu opens the composer with that member pre-selected.
- "Select All As Me" now sets the sign-off to the chosen role only, rather than every committee role the user holds.
- Events show a divider between them by default, matching the divider between articles, with even spacing either side.
- The placeholder title for an event awaiting details shows the event type in title case.
- Button hierarchy: solid yellow is reserved for wizard navigation; utility buttons use a new quiet style.