Skip to content

feat(deleter): email the org owners when a delete forfeits tokens - #1880

Draft
whoAbhishekSah wants to merge 1 commit into
org-delete-preflight-blockersfrom
org-delete-forfeit-email
Draft

feat(deleter): email the org owners when a delete forfeits tokens#1880
whoAbhishekSah wants to merge 1 commit into
org-delete-preflight-blockersfrom
org-delete-forfeit-email

Conversation

@whoAbhishekSah

@whoAbhishekSah whoAbhishekSah commented Aug 13, 2026

Copy link
Copy Markdown
Member

Part of #1837. Top of the stack, based on #1857.

Deleting an organization forfeits any unused tokens (the client confirms that with the user before calling). This PR adds the second half of that flow: the org owners get an email saying how many tokens were left and that support can transfer the amount to their bank account.

How it works:

  • The email subject and body come from new config keys billing.token_forfeit_notice.subject and billing.token_forfeit_notice.body. Both are Go templates with .Amount (tokens forfeited), .Org (the deleted organization), and .User (the owner receiving the mail). Empty config falls back to plain built-in text. This is the same pattern the PAT expiry alert emails use.
  • The mail goes through the shared app.mailer dialer to every user holding the org owner role.
  • The owners and the token amount are read before teardown starts (both are gone after), but the mail is only sent after the delete fully succeeded. A failed delete never emails anyone, and repeated calls on a deleted org return not_found before any of this runs, so nobody gets the mail twice.
  • A send failure is logged and never fails the API call — the org is already gone at that point.

Side change: the org lookup at the start of the delete switched from Get to GetRaw, so a disabled org keeps its title for the email and stays deletable without the ErrDisabled special case.

🤖 Generated with Claude Code

Deleting an organization forfeits any unused tokens. The owners now get
an email saying how many tokens were left and that support can transfer
the amount. The subject and body come from the billing config
(billing.token_forfeit_notice.subject/body) as Go templates with
.Amount, .Org, and .User, falling back to plain built-in text — the
same pattern the PAT expiry alerts use. The mail goes through the
shared mailer dialer, only after the delete fully succeeded, and a send
failure is logged, never returned.

The owners and the amount are read before teardown (they are gone
after). The org lookup at the start switched from Get to GetRaw so a
disabled org keeps its title in the email and stays deletable without
a special case.
@vercel

vercel Bot commented Aug 13, 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 13, 2026 11:21am

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 59d0a661-5641-4849-9827-b3d7a7b9ee74

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 31695140194

Coverage increased (+0.07%) to 48.428%

Details

  • Coverage increased (+0.07%) from the base build.
  • Patch coverage: 32 uncovered changes across 3 files (102 of 134 lines covered, 76.12%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
core/deleter/forfeit_notice.go 101 72 71.29%
core/deleter/service.go 32 30 93.75%
cmd/serve.go 1 0 0.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 40008
Covered Lines: 19375
Line Coverage: 48.43%
Coverage Strength: 15.39 hits per line

💛 - Coveralls

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.

2 participants