berrypod/lib/berrypod_web/live/admin
jamey 2f4cd81f98 add abandoned cart recovery
When a Stripe checkout session expires without payment, if the customer
entered their email, we record an AbandonedCart and schedule a single
plain-text recovery email (1h delay via Oban).

Privacy design:
- feature is off by default; shop owner opts in via admin settings
- only contacts customers who entered their email at Stripe checkout
- single email, never more (emailed_at timestamp gate)
- suppression list blocks repeat contact; one-click unsubscribe via
  signed token (/unsubscribe/:token)
- records pruned after 30 days (nightly Oban cron)
- no tracking pixels, no redirected links, no HTML

Legal notes:
- custom_text added to Stripe session footer when recovery is on
- UK PECR soft opt-in; EU legitimate interests both satisfied by this design

Files:
- migration: abandoned_carts + email_suppressions tables
- schemas: AbandonedCart, EmailSuppression
- context: Orders.create_abandoned_cart, check_suppression, add_suppression,
  has_recent_paid_order?, get_abandoned_cart_by_session, mark_abandoned_cart_emailed
- workers: AbandonedCartEmailWorker (checkout queue), AbandonedCartPruneWorker (cron)
- notifier: OrderNotifier.deliver_cart_recovery/3
- webhook: extended checkout.session.expired handler
- controller: UnsubscribeController, admin settings toggle
- tests: 28 new tests across context, workers, and controller

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:02:37 +00:00
..
providers fix admin font loading and theme CSS cache miss bug 2026-02-20 18:39:41 +00:00
theme replace --color-* with --t-* tokens, delete bridge and .preview-frame 2026-02-21 00:13:33 +00:00
analytics.ex add analytics CSV export 2026-02-24 09:37:45 +00:00
dashboard.ex add Stripe connection step to launch checklist 2026-02-21 23:26:13 +00:00
email_settings.ex gate magic link login on verified email delivery 2026-02-21 22:25:27 +00:00
order_show.ex rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
orders.ex rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
product_show.ex extract setup wizard to dedicated /admin/setup page 2026-02-18 23:55:42 +00:00
products.ex rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
settings.ex add abandoned cart recovery 2026-02-24 10:02:37 +00:00