fix(deleter): clean up all billing and kyc records during org delete - #1838
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe PR adds deletion methods for checkout records, credit transactions, and KYC records. It integrates these deletions into the cascade deleter, reorders organization and customer cleanup to remove billing data first, and improves subscription cancellation to handle offline customers and provider-side state synchronization. ChangesBilling and KYC deletion
Estimated code review effort: 4 (Complex) | ~50 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
billing/subscription/service.go (1)
1100-1107: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winCancel non-active provider-backed subscriptions before local delete.
IsActive()allows onlyactiveandtrialing, butStatePastDueis a known local/Stripe status. Apast_duesubscription can therefore skipCancel()inDeleteByCustomer()and leave the Stripe subscription billable after the local row is deleted. Treat non-terminal non-active states the same way, or add a non-terminal check before deletion.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: bc4f87c9-2cfb-4014-b174-8902b6d224d3
📒 Files selected for processing (15)
billing/checkout/service.gobilling/credit/mocks/transaction_repository.gobilling/credit/service.gobilling/subscription/service.gocmd/serve.gocore/deleter/mocks/checkout_service.gocore/deleter/mocks/credit_service.gocore/deleter/mocks/kyc_service.gocore/deleter/service.gocore/deleter/service_test.gocore/kyc/mocks/repository.gocore/kyc/service.gointernal/store/postgres/billing_checkout_repository.gointernal/store/postgres/billing_transactions_repository.gointernal/store/postgres/kyc_repository.go
6b61473 to
f4396c3
Compare
rohilsurana
left a comment
There was a problem hiding this comment.
Verified the new order against the schema FKs: subscriptions, invoices, checkouts, and transactions all go before the customer hard delete, and org_kyc goes before the owner policies. Every earlier step is idempotent on retry, so a failure at any point leaves the org owned and the delete can just run again. The test rewrite with strict mocks pins exactly that ordering, nice work. Two notes inline.
…1835) Organization delete could fail halfway and leave the org without owners and with a billing account pointing to a deleted Stripe customer. Checkout and kyc rows were never removed, so their foreign keys made the hard delete of billing_customers and organizations fail after the Stripe customer was already gone. Retrying hit the same error forever. - delete checkout rows before the billing customer row - delete the org_kyc row before the org row - delete credit transactions instead of orphaning them - always remove local subscription and invoice rows, also for offline billing accounts - tear down billing first and org policies near the end, so a failure at any step leaves the org owned and the delete retryable Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A kyc delete failure after the policy loop left the org without owners. Moving it earlier keeps the org owned when the kyc delete fails. Also drop a redundant comment in DeleteCustomers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9505aac to
5fbb56b
Compare
Coverage Report for CI Build 30970587297Coverage increased (+0.02%) to 47.5%Details
Uncovered Changes
Coverage Regressions3 previously-covered lines in 1 file lost coverage.
Coverage Stats
💛 - Coveralls |
Fixes #1835. Top layer of the cleanup stack — uses the delete methods added in #1841, #1842, #1843 and relies on the retryable teardown from #1844.
Problem
Organization delete could fail halfway and leave the org in a broken state: no owners, and a billing account pointing to a Stripe customer that was already deleted. Checkout and kyc rows were never removed, so their foreign keys made the hard delete of
billing_customersandorganizationsfail after the Stripe customer was gone. Retrying hit the same error forever.Changes
org_kycrow before the org row.Testing
core/deleter/service_test.goto cover the new deletion order and the checkout, credit, and kyc steps.🤖 Generated with Claude Code