Devices now belong to Identity instead of User, allowing a single
device registration to work across all accounts an identity has
access to.
- Move User::Devices to Identity::Devices
- Update DevicesController to use Current.identity
- Update NotificationPusher::Native to use user.identity.devices
- Clean up tests to use @identity directly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix reference to `user.devices`, left-over from the identity switch
- Use RESTful DELETE /devices/:id where :id can be token or database ID
- Remove redundant unregister collection route
- Remove old Users::DevicesController
- Return 404 when device not found instead of silently succeeding
- Return 422 for invalid platform via ActiveRecord validation
- Update action_push_native to main branch (includes validate: true on enum)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove Users namespace from DevicesController (now just DevicesController)
- Create ApplicationPushDevice model extending ActionPushNative::Device
- Move device registration logic (find_or_initialize + update) to model
- Update User::Devices concern to use ApplicationPushDevice
- Fix push notification tests (endpoint validation, job count expectations)
- Update push_config_test to use ActionPushNative.config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove UUID column from devices table entirely
- Update unique index from (owner, uuid) to (owner, token)
- Simplify create action to just create device records
- Add token-based unregister route for API clients
- Consolidate error handling with rescue_from
- Update fixtures to remove uuid references
Devices are now identified by (owner, token) instead of UUID.
This simplifies the client-side registration flow.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename SaasAdminController to Admin::AuditController
- Override require_authentication to support bearer tokens alongside
session auth, allowing API access to audit console
- Add migration for audits1984_auditor_tokens table
- Add controller tests for authentication scenarios including staff
validation on token-based access
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* 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
* Add self-service account deletion
* Disable access to cancelled accounts & implement Stripe interactions
* Add tests
* Fix failing tests
* Remove cancelled accounts from lists
* Fix incorrect redirect
* Use _path instead of _url for consistency
* Don't track how far the inicieration job got
We still want the step tracking so that the job can be interrupted. But, since the scope is idempotent, we don't need to track how far it got.
* Specify the exact time when the data will be deleted
* Fix crash due to unadvancable cursor
* Rename up_for_incineration to due_for_incineration
* Regenrate the schema
* Fix incorrect path check
* Migrate the SQLite schema
* Only show the cancel button on cancellable accounts
* Check that a subscirption method exists before calling it
* Ignore job failures due to missing records when an account gets deleted
* Skip sending notifications on cancelled accounts
* Use collbacks to integrate
* Add a blank line between queue_as and discard_on
* Break checks into methods
* Inline methods
* Rename Account::IncinerateJob
* Run migrations
* Migrate SQLite
Before, we were relying on just changing the cards_count in account, but this
could create problems where the system to calculate the next card number fails due
to the unique constraint.
Instead:
- Always let you create drafts when pressing "Add card"
- Prevent creations of published cards via API
- Prevent publication of cards in all cases when the limit is exceeded