feat(email): add org top-up confirmations#3084
Open
evanjacobson wants to merge 10 commits intomainfrom
Open
Conversation
Contributor
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (11 files)
Fix these issues in Kilo Cloud Reviewed by gpt-5.5-20260423 · 1,827,933 tokens |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Organization credit top-ups now send the transactional confirmation billing owners expect after team funds are added, closing the gap where successful org top-ups were only reflected in-app.
This extends the existing credit top-up email flow to organization purchases, including distinct manual and auto top-up copy, organization payment-detail links, Stripe receipt links when available, and durable send markers so webhook retries can recover missed sends without double-emailing recipients. The implementation follows the existing server-rendered email template conventions and reuses the transactional email log idempotency pattern already used for purchase confirmations.
Implementation notes
transactional_email_log.organization_idso retry paths can remain idempotent.invoice.paidorg auto top-ups.Verification
Visual Changes
N/A
Reviewer Notes
Suggested review focus
transactional_email_log.organization_idschema/index addition and GDPR retention note.A few more details
We are not falling into the unrelated post-commit failure pitfall from Jean’s first comment. In this PR, processTopupForOrganization runs the test-only promo grant before scheduling the email, but that branch is gated to NODE_ENV === 'test' at apps/web/src/lib/organizations/organization-billing.ts:345. In production there is no unrelated bonus/promo step ahead of scheduleOrganizationTopUpConfirmationEmail at apps/web/src/lib/organizations/organization-billing.ts:355.
We are not falling into the retry-date pitfall from Jean’s second comment. Duplicate payment recovery loads the existing credit_transactions.created_at in getExistingOrganizationTopUpCreditTransaction and passes it as purchaseDate at apps/web/src/lib/organizations/organization-billing.ts:334-340. The email sender uses purchaseDate ?? new Date() at apps/web/src/lib/organizations/organization-billing.ts:165, so recovery uses the original transaction timestamp.
We do share the known insert-before-send marker limitations described in PR feat(emails): add top-up purchase confirmations #3050. This PR inserts a marker before sending at apps/web/src/lib/organizations/organization-billing.ts:141-149. That means a crash after marker insert but before provider acceptance can suppress a future retry. The code does mitigate multi-recipient failures by clearing the marker if all sends fail retryably at apps/web/src/lib/organizations/organization-billing.ts:220-222, but it is still not a durable outbox. That appears consistent with the explicit PR feat(emails): add top-up purchase confirmations #3050 decision to keep this pattern uniform rather than solve it locally.