One opt-out ledger, topics, pauses and a history of every change

Featurekamo-shared-library
Shipped
September 12, 2026 at 6:08 AM UTC
Author
Kamo
Commit
5d4aa03

The do-not-email list could be written to but not read, changed or explained. This adds the one place it is read and written from, for every service: email_optout_topics an address that stopped one kind of mail, or paused all of it email_optout_events insert-only history: who (recipient, member, system), from where (client IP, the whole X-Forwarded-For chain, user agent, language, host, referer, session hash), why (reason, source, note, feedback), through what (campaign, lead), and the state before and after email_suppressions keeps its meaning, so every sender that already honours it still does. EmailOptOutLedger answers "may this be sent" from all three and writes one history row per part of the state a change actually moved. A member allowing mail again must say why; that note is the record of consent. Until the new tables exist the ledger falls back to the list alone and refuses changes it cannot record, rather than failing sends. Plain class, not a @Service: every service scans com.kamo, and one without the email repositories would fail to start constructing it. Each service declares it with @Bean. Also MANAGE_EMAIL_OPT_OUTS (320), the org right for Settings -> Email -> Opt Out, a child of MANAGE_EMAIL_SETTINGS.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing