Add embeddability hooks and transfer expiration policies (v0.2.0)#1
Merged
Merged
Conversation
This release makes wallets embeddable by other gems (like usage_credits) and adds expiration-aware transfers that preserve source bucket expirations by default. Embeddability: - Wallet, Transaction, Allocation, Transfer models now support subclassing with overridable table names, config providers, callbacks, and related model class names via class_attribute hooks - Multiple wallet systems can coexist in the same Rails app without collision - Transfers now enforce same-class constraint to prevent accidental cross-system transfers Transfer expiration policies: - New `expiration_policy` column on transfers (preserve/none/fixed) - :preserve (default) keeps source bucket expirations; splits into multiple inbound legs when consuming buckets with different expirations - :none creates evergreen inbound credits - :fixed applies a specific expires_at to all inbound credits - Configurable default via `config.transfer_expiration_policy` Schema changes: - Added expiration_policy column to transfers table - Removed outbound_transaction_id/inbound_transaction_id FKs from transfers (now derived via transfer_id on transactions to support multiple inbound legs) Rails compatibility: - Extended support back to Rails 6.1 (was 7.2+) - Added Appraisals for Rails 6.1, 7.0, 7.1, 7.2, 8.0 CI improvements: - Test workflow now runs db:migrate:reset before tests to catch migration template / schema drift early Documentation: - Major README rewrite with wallets vs usage_credits comparison - Real-world examples: telecom, games, marketplaces, loyalty, gig economy - Transfer expiration behavior fully documented Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MySQL 8+ doesn't allow default values on JSON columns. Use conditional helper methods to set jsonb for PostgreSQL, json for others, and skip the default value for MySQL (models handle nil gracefully). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This release makes
walletsembeddable by other gems (likeusage_credits) and adds expiration-aware transfers that preserve source bucket expirations by default.Embeddability Hooks
The core models (
Wallet,Transaction,Allocation,Transfer) now support subclassing so other gems can reuse the wallet ledger with their own:embedded_table_nameclass attributeconfig_providerlambda/objectcallbacks_modulefor custom dispatchtransaction_class_name,allocation_class_name,transfer_class_nameThis allows
usage_credits(and similar gems) to build on the same ledger core with their own tables, configuration, and callbacks — without colliding with vanillawalletsusage in the same app.Transfers now enforce a same-class constraint to prevent accidental cross-system transfers (
Wallets::Walletcannot transfer directly toUsageCredits::Wallet).Transfer Expiration Policies
New
expiration_policyfield on transfers with three modes::preserve(default):none:fixedexpires_aton all inbound credits.Configurable default:
Schema Changes
expiration_policycolumn to transfers table (default:"preserve")outbound_transaction_idandinbound_transaction_idFK columns from transfers — now derived viatransfer_idon transactions (supports multiple inbound legs)Rails Compatibility
CI Improvements
Test workflow now runs
db:migrate:resetbefore tests to catch migration template / schema drift early in the default matrix.Documentation
walletsvsusage_creditscomparisonTest plan
🤖 Generated with Claude Code