Send subscription acknowledgments and yearly renewal notices

Merged
CO
6d ago
+758-7

Summary

Intent: Give paid Anarlog subscribers a retainable acknowledgment and yearly renewal notice with billing terms and cancellation instructions. Use Loops with a 30-day reminder target and catch-up through 15 days, within California’s 15–45-day window, while excluding Autumn customers from emails and owner metadata writes.

Delivery receipts persist across retries and renewals. Delivery is disabled by default until John approves publishing the Loops drafts and activation; no Stripe account settings change.

ANLG-519

Demo

Server-side transactional email flow; previews were sent only to john@fastrepl.com. Both templates remain unpublished:

Activation requires the database migration, billing deployment, approved template publication, and SUBSCRIPTION_NOTICES_ENABLED=true. Uncertain deliveries older than 23 hours require review because Loops expires idempotency keys after 24 hours.

Verification

  • Stripe typecheck and full Bun suite: 107 passed, including trigger, retry/idempotency, and Autumn isolation regressions.
  • Isolated Supabase migration and database suite: 68 files, 1,510 tests passed; local advisors reported no issues.
  • Concurrent delivery against local Postgres: one send and one durable receipt.
  • Changed-file formatting, root Node checks (95 tests), license-boundary and deployment-drain Python checks passed.
  • Offline zizmor scan completed with 337 existing findings; no workflow files changed. Authenticated audits were unavailable.

Summary by cubic

Sends paid Anarlog subscribers an acknowledgment email on signup and a yearly renewal reminder with billing terms and cancellation instructions.

Delivery is disabled by default (SUBSCRIPTION_NOTICES_ENABLED=false) until the Loops templates are published, and it requires the new database migration.

  • Persists delivery receipts in Postgres so retries and concurrent webhook events send at most once; deliveries older than 23 hours stop and require review because Loops expires idempotency keys after 24 hours.
  • Renewal reminders run hourly for yearly subscriptions and catch up from 30 down to 15 days before renewal.
  • Acknowledgments show the settled charge separately from the estimated renewal price, classify invoice history by settled value (so free promotions and credits don't suppress the first real charge), support tiered pricing, skip previously paid subscriptions, and are kept when a subscription is canceled.
  • Excludes Autumn-managed customers from emails and from owner metadata writes in syncBillingBridge.
  • Updates the Terms of Service and Privacy Policy to disclose the new subscription emails and cancellation instructions.