Fizzy is now free. Remove the entire Stripe billing system,
subscription management, and card/storage limit enforcement.
Removes from saas/: Plan model, Account::Billing, Account::Subscription,
Account::Limited, Account::OverriddenLimits, Account::BillingWaiver,
all subscription/billing controllers and views, Stripe webhook handler,
card creation/publishing limit enforcement, admin account override UI,
usage report rake task, and all related tests.
Removes from main app: Fizzy.saas? guards for subscription panel,
SaaS card footer override, near-limit notices, and saas.css stylesheet.
Adds migration to drop billing tables from the SaaS database.
Non-billing SaaS features (push notifications, signup, authorization,
telemetry, console1984/audits1984) are preserved.
Replace separate WebPushJob and NativePushJob with a single PushJob
that calls notification.push, which iterates over registered targets.
Each target handles its own delivery - Web pushes synchronously via
the pool, Native enqueues device-level jobs via deliver_later_to.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PushTarget#push reads more naturally than Push#push. The push target
is the thing that pushes notifications to a specific destination.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace NotificationPusher with a cleaner architecture:
- Add Notification::Pushable concern with push target registry
- Add Notification::Push base class with template methods
- Add Notification::Push::Web for web push (OSS)
- Add Notification::Push::Native for native push (SaaS)
- Add Notification::WebPushJob and Notification::NativePushJob
Key design:
- Registry pattern: Notification.register_push_target(:web)
- Template method: push calls should_push? then perform_push
- Subclasses override should_push? (with super) and perform_push
- Each target handles its own job enqueueing
Also:
- Add Notification#pushable? for checking push eligibility
- Add Notification#identity delegation to user
- Reorganize tests to match new class structure
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tidy up saas engine a bit more
* Sync owner email to Stripe when changed
When an account owner changes their email address, update the
corresponding Stripe customer record via a background job.
Also handles ownership transfers: when a user becomes the account
owner, their email is synced to Stripe.
Responsibility chain:
- User::NotifiesAccountOfEmailChange triggers on owner identity change
or when a user becomes owner
- Account::Billing#owner_email_changed enqueues sync job
- Account::SyncStripeCustomerEmailJob performs the update with
polynomial backoff retries
- Account::Subscription#sync_customer_email_to_stripe calls Stripe API
* Address PR feedback: error handling and test coverage
- Handle Stripe::InvalidRequestError in sync_customer_email_to_stripe
(mirrors cancel method behavior for deleted customers)
- Add test for deactivated owner (owner with nil identity)
- Add test for deleted Stripe customer scenario