berrypod/priv/repo/migrations
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
..
.formatter.exs mix phx.new simpleshop_theme --database sqlite3 --adapter bandit --binary-id 2025-12-30 12:26:26 +00:00
20251230122634_create_users_auth_tables.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20251230213057_create_settings.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20251230213058_create_images.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260121220351_add_image_metadata_and_oban.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260128235845_create_provider_connections.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260128235846_create_products.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260128235847_create_product_images.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260128235848_create_product_variants.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260131232618_add_image_id_to_product_images.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260207005141_create_orders.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260207084327_add_encrypted_value_to_settings.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260207234225_add_fulfilment_fields_to_orders.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260208165931_add_error_tracker.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260213005639_add_cached_product_fields.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260213020000_create_products_search.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260214004900_create_shipping_rates.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260214004901_add_shipping_cost_to_orders.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260215205353_add_color_to_product_images.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
20260222112942_create_analytics_events.exs add privacy-first analytics with progressive event collection 2026-02-22 12:50:55 +00:00
20260224000001_create_abandoned_carts.exs add abandoned cart recovery 2026-02-24 10:02:37 +00:00