🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

feat(deleter): write an audit record for each checkout removed during org delete - #1839

Merged
whoAbhishekSah merged 2 commits into
mainfrom
fix/org-delete-checkout-audit
Aug 5, 2026
Merged

feat(deleter): write an audit record for each checkout removed during org delete#1839
whoAbhishekSah merged 2 commits into
mainfrom
fix/org-delete-checkout-audit

Conversation

@whoAbhishekSah

Copy link
Copy Markdown
Member

Stacked on #1838. Review only the last commit here; the rest is the base PR.

Problem

#1838 hard-deletes the billing_checkouts rows during org delete. Those rows hold the only local reference to the Stripe checkout sessions (provider_id). Once they are gone, there is no local trace of what was removed.

Changes

  • New audit event app.billing.checkout.deleted, registered as a system event.
  • During DeleteCustomers, the deleter lists the checkouts before removing them and writes one audit record per checkout. Each record carries the provider session id, customer id, plan/product id, state, and payment status.
  • Audit writes are best effort: a failed write logs a warning and does not block the delete, same as the existing organization.deleted event.
  • The audits table is not part of the delete cascade, so these records survive the org delete. The Stripe sessions can still be found later from provider_id.

Testing

  • Extended core/deleter/service_test.go: the delete flow now expects the checkout list call, and a new case checks that a list failure stops the customer delete.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview Aug 5, 2026 3:39am

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Organization deletion now removes associated billing checkouts.
    • Deleted checkouts are recorded in the audit log with billing and payment details.
  • Bug Fixes

    • Checkout-related deletion failures now stop further customer cleanup, preventing incomplete deletion workflows.
    • Audit logging warnings no longer interrupt the deletion process.

Walkthrough

The deleter now lists and deletes billing checkouts during organization cleanup. It records checkout deletion events with checkout attributes, tolerates audit failures, and adds mock support and failure-path tests.

Changes

Checkout deletion audit

Layer / File(s) Summary
Audit event and service contract
core/audit/audit.go, core/deleter/service.go
Adds BillingCheckoutDeletedEvent and exposes checkout listing through CheckoutService.
Checkout cleanup and audit flow
core/deleter/service.go
Lists customer checkouts before cleanup, deletes each checkout, records audit attributes, and continues when audit logging fails.
Mock wiring and cleanup validation
core/deleter/mocks/checkout_service.go, core/deleter/service_test.go
Adds List mock configuration and tests successful cleanup, listing failures, and deletion failures.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: rohilsurana, amangit07

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rohilsurana rohilsurana left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shape is right: list before delete, log after the delete succeeds, and a retry lists zero checkouts so there are no duplicate records. Two notes inline. One minor thought: as more steps get audited, a small helper for this loop would keep DeleteCustomers readable.

Comment thread core/deleter/service.go
Comment thread core/deleter/service.go
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 30970637866

Coverage increased (+0.03%) to 47.527%

Details

  • Coverage increased (+0.03%) from the base build.
  • Patch coverage: 2 uncovered changes across 1 file (22 of 24 lines covered, 91.67%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
core/deleter/service.go 24 22 91.67%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 39359
Covered Lines: 18706
Line Coverage: 47.53%
Coverage Strength: 15.4 hits per line

💛 - Coveralls

Base automatically changed from fix/org-delete-cleanup to main August 5, 2026 03:36
whoAbhishekSah and others added 2 commits August 5, 2026 09:08
… org delete

Org delete now hard-deletes checkout rows, and with them the local
reference to the Stripe checkout sessions. Emit one audit record per
removed checkout carrying the provider session id, plan/product id,
state, and payment status. The audits table survives the org delete,
so the sessions can still be looked up on Stripe later.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Also note that the records depend on the audit service seeded in ctx;
outside the API path the logger falls back to a noop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
core/deleter/service_test.go (1)

143-144: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

Test the persisted audit contract.

These tests use context.Background(), so audit.NewLogger falls back to a no-op audit service. For DeleteOrganization, add a recording audit repository, set it with audit.SetContextWithService, and assert one persisted billing_checkout_deleted entry per checkout with the expected provider_id, customer_id, plan_id, product_id, state, and payment_status attributes, including omission of empty values. Also add a failing audit repository case that still deletes cred and customer records. For DeleteOrganization, assert that the recorded checkout audit entry remains after organization deletion.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ca7a7c3-3b5e-48aa-857d-312ac2523381

📥 Commits

Reviewing files that changed from the base of the PR and between 2930c71 and 21b3303.

📒 Files selected for processing (4)
  • core/audit/audit.go
  • core/deleter/mocks/checkout_service.go
  • core/deleter/service.go
  • core/deleter/service_test.go

@whoAbhishekSah
whoAbhishekSah merged commit 555c089 into main Aug 5, 2026
8 checks passed
@whoAbhishekSah
whoAbhishekSah deleted the fix/org-delete-checkout-audit branch August 5, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants