fix(backend): send plan and deletion emails only once - #40
Conversation
Skip the Apple-path deletion mail so Better Auth onDelete is the single sender, and claim the Pro upgrade mail when hasPro flips to true.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
adapter.deleteOne does not run Better Auth onDelete, so Apple-only deletes must send the confirmation themselves. Upgrade mail is claimed with planUpgradedEmailSent and released if the send fails.
There was a problem hiding this comment.
Verified the existing fix in f378e05 for the failed-upgrade-email retry issue. _upgradeToPro now claims the upgrade email with planUpgradedEmailSent, and _handlePlanUpgrade releases that claim if the send is skipped or throws so a later Autumn event can retry. No additional code changes were needed.
I attempted to run bun run test:integration integration-tests/email-webhooks.test.ts, but this environment does not have bun installed (bun: command not found).
Sent by Cursor Automation: Autofix PR review comments
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f378e05. Configure here.
Unset planUpgradedEmailSent now means a legacy Pro user, not a retry. Failed sends set the flag to false so only those can claim again.
There was a problem hiding this comment.
Verified the triggered Bugbot thread is addressed by PR head 73cb3e8: _upgradeToPro now treats legacy Pro rows (hasPro === true with no planUpgradedEmailSent) as already handled, while only planUpgradedEmailSent === false claims a retry after a failed send.
No additional code changes were needed in this run; the PR branch was already at the fixing commit. Verification passed:
bun run test:integration email-webhooks.test.ts(6 tests passed)- pre-push
lintandcheck-typeshooks passed; push reportedEverything up-to-date
Sent by Cursor Automation: Autofix PR review comments
Summary
onDeleteis the single sender.hasProfirst becomes true so duplicate Autumn events do not resend it.Needed to unblock
dev→main(#39), which requires conversation resolution.Test plan
_upgradeToProclaims the email only onceNote
Medium Risk
Touches billing webhook email paths and persistent
emailState; wrong claim logic could suppress or duplicate Pro upgrade emails, but behavior mirrors the existing grace-period pattern and is covered by new tests.Overview
Adds
planUpgradedEmailSentonemailStateand uses it so the Plan Upgraded email is sent at most once per real upgrade, even when Autumn/webhooks call upgrade repeatedly._upgradeToPronow returnsclaimedUpgradeEmail(same idea as downgrade’sclaimedGraceEmail). It claims on first transition to Pro, skips duplicate claims for users already Pro (including legacy rows with no flag), and can re-claim after_releaseUpgradeEmailsets the flag back tofalse. Downgrade clearsplanUpgradedEmailSentso a future upgrade can email again._handlePlanUpgradeonly callssendEmailwhen the claim succeeds; on send skip or failure it releases the claim so a retry can succeed. Integration tests cover repeat upgrades, release/re-claim, and legacy Pro rows.Reviewed by Cursor Bugbot for commit 73cb3e8. Bugbot is set up for automated code reviews on this repo. Configure here.