-
Notifications
You must be signed in to change notification settings - Fork 10
Fix incomplete fulfillment update on subscription plan upgrade #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
## Problem When upgrading between subscription plans with different fulfillment periods, only the `metadata["plan"]` field was being updated. The `fulfillment_period` and `next_fulfillment_at` fields were left with the old plan's values. This caused: - Future fulfillments to remain on the old plan's schedule - Incorrect display of fulfillment period in the database - Potential delays in credit delivery when upgrading to plans with shorter periods Example bug scenario: 1. User on Starter plan (15-second fulfillment period) 2. Upgrades to Studio plan (5-second fulfillment period) 3. `fulfillment_period` still shows "15 seconds" instead of "5 seconds" 4. `next_fulfillment_at` remains on 15-second schedule instead of 5-second 5. User experiences delayed credit delivery ## Solution Updated `handle_plan_upgrade` to properly update ALL fulfillment fields: - `fulfillment_period`: Updated to new plan's period display string - `next_fulfillment_at`: Recalculated based on new plan's parsed period - `metadata["plan"]`: Updated to new processor plan ID (already working) The fix ensures that when users upgrade, their fulfillment schedule immediately switches to match the new plan's cadence. ## Debug Logging Added Added comprehensive debug logging throughout the plan change flow to help diagnose future issues: - Plan change detection with old/new plan comparison - Credit comparison logic (upgrade vs downgrade detection) - Detailed upgrade process tracking (balance before/after, periods, etc.) - Fulfillment record updates (old vs new values) This logging will help diagnose intermittent issues like silent transaction rollbacks or race conditions with webhook processing. ## Testing Added two comprehensive regression tests: 1. `test_REGRESSION:_upgrade_updates_fulfillment_period_and_next_fulfillment_at` - Verifies upgrade between plans with different periods (1 day → 7 days) - Confirms fulfillment_period and next_fulfillment_at are updated - Ensures new schedule is significantly different from old schedule 2. `test_REGRESSION:_upgrade_between_plans_with_same_period_only_updates_metadata` - Verifies upgrade between plans with same period (month → month) - Ensures next_fulfillment_at is still recalculated from upgrade time - Confirms metadata and period string are updated All 614 tests pass with 1364 assertions ✅ Line Coverage: 88.29% (1169/1324) Branch Coverage: 82.13% (432/526) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
@claude is this PR safe to merge? |
|
Claude finished @rameerez's task in 2m 3s —— View job ✅ Safe to Merge - Comprehensive Review CompleteTodo List:
🎯 Executive SummaryRecommendation: SAFE TO MERGE ✅ This PR fixes a legitimate bug where upgrading subscription plans didn't update the fulfillment schedule. The fix is well-implemented, thoroughly tested, and has low risk. 🔍 Code ReviewWhat ChangedCore Fix (lib/usage_credits/models/concerns/pay_subscription_extension.rb:467-473): fulfillment.update!(
fulfillment_period: new_plan.fulfillment_period_display, # ← NEW
next_fulfillment_at: Time.current + new_plan.parsed_fulfillment_period, # ← NEW
metadata: fulfillment.metadata
.except("pending_plan_change", "plan_change_at")
.merge("plan" => processor_plan)
)Before: Only updated ✅ Strengths
🔍 Potential Concerns (All Low Risk)1. Log Verbosity
2. next_fulfillment_at Calculation
3. Edge Case: Very Fast Plan Changes
🛡️ Security AssessmentNo security concerns identified:
🧪 Test QualityThe regression tests are well-designed: Test 1 (pay_subscription_extension_test.rb:803-879):
Test 2 (pay_subscription_extension_test.rb:881-940):
Minor suggestion: Could add a test for downgrade scenario to ensure it doesn't break fulfillment_period, but the existing downgrade tests probably cover this implicitly. 📊 CI StatusAll checks passing ✅:
🎬 Final VerdictSAFE TO MERGE with high confidence. Why it's safe:
Optional follow-up (non-blocking):
Risk Level: Very LowThe change is isolated to the upgrade flow, well-tested, and fixes incorrect behavior. Users will benefit from getting credits on the correct schedule after upgrading. Merge with confidence! 🚀 |
🐛 The Bug
When upgrading between subscription plans with different fulfillment periods, only the
metadata["plan"]field was being updated. Thefulfillment_periodandnext_fulfillment_atfields remained stuck on the old plan's values.Real-World Impact
Scenario that triggered discovery:
Root Cause
The
handle_plan_upgrademethod (line 423-428 before fix) only updated themetadata["plan"]field:This meant future fulfillments would:
next_fulfillment_atusing the OLDfulfillment_period❌✅ The Fix
Updated
handle_plan_upgradeto update ALL fulfillment fields (lines 467-473):What This Fixes
fulfillment_period: Now immediately updated to match new plannext_fulfillment_at: Recalculated from upgrade time using new plan's period🔍 Debug Logging Added
Added comprehensive debug logging throughout the plan change flow (lines 347-420):
On Plan Change Detection
During Upgrade Process
This logging helps diagnose:
🧪 Testing
New Regression Tests
Added 2 comprehensive tests covering different upgrade scenarios:
1.
test_REGRESSION_upgrade_updates_fulfillment_period_and_next_fulfillment_atTests upgrade between plans with significantly different periods (1 day → 7 days):
fulfillment_periodupdates from "1.0 days" to "7.0 days"next_fulfillment_atis recalculated (~7 days from upgrade time)2.
test_REGRESSION_upgrade_between_plans_with_same_period_only_updates_metadataTests upgrade between plans with the same period (both monthly):
next_fulfillment_atis still recalculated from upgrade timefulfillment_perioddisplay string is updatedTest Results
Manual Testing (Production-like scenario)
Tested in separate Rails demo app with real Stripe webhooks:
Test Flow:
Debug logs confirmed:
📋 Files Changed
Modified Files
lib/usage_credits/models/concerns/pay_subscription_extension.rb(+55, -2)handle_plan_upgradeto update all fulfillment fieldsTest Files
test/models/concerns/pay_subscription_extension_test.rb(+144)🔗 Related PRs
This fix builds on recent improvements:
⚡ Performance Impact
Minimal - Only adds:
fulfillment_period)next_fulfillment_at)All within the existing transaction, no additional queries.
✨ Summary
Before: Upgrading between plans left fulfillment schedule on old plan's cadence
After: Upgrading immediately switches to new plan's fulfillment schedule
Impact: Ensures users get credits at the correct frequency after upgrading
Risk: Very low - only affects upgrade path, all tests passing, backward compatible
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com