Repository navigation
feat(devpass): notify Discord on Reset Pass buys - #3106
Conversation
WalkthroughReset-pass purchase fulfilment now sends billing email, user name, tier, and paid amount to an internal Discord notification through a new reusable webhook helper. ChangesReset pass notifications
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant fulfillResetPassPurchase
participant UserDatabase
participant notifyResetPassPurchased
participant DiscordWebhook
fulfillResetPassPurchase->>UserDatabase: Look up billing-email user name
fulfillResetPassPurchase->>notifyResetPassPurchased: Pass email, name, tier, and amount
notifyResetPassPurchased->>DiscordWebhook: Send purchase embed
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/src/stripe.ts`:
- Around line 2596-2606: Wrap the billingEmail notification block in the
surrounding purchase fulfillment flow, including db.query.user.findFirst and
notifyResetPassPurchased, with a try-catch. Log or otherwise handle the
notification error without rethrowing, so execution always continues to the
subsequent posthog.capture telemetry step while preserving best-effort
notification behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: f9bc9018-490c-4aee-a586-3eb31c24bcf1
📒 Files selected for processing (2)
apps/api/src/stripe.tsapps/api/src/utils/discord.ts
| if (organization.billingEmail) { | ||
| const purchaseUser = await db.query.user.findFirst({ | ||
| where: { email: { eq: organization.billingEmail } }, | ||
| }); | ||
| await notifyResetPassPurchased( | ||
| organization.billingEmail, | ||
| purchaseUser?.name, | ||
| tier, | ||
| amountPaid, | ||
| ); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Wrap the notification block in a try-catch to protect subsequent telemetry.
If the database query db.query.user.findFirst fails (e.g., due to a transient database issue), it will throw an exception that permanently skips the posthog.capture step below. Because the purchase transaction has already been committed, subsequent Stripe webhook retries will exit early at the deduplication check and never reach the telemetry step.
Wrapping this block in a try-catch ensures that the notification remains truly "best-effort" without interrupting the remaining post-fulfillment pipeline.
🛡️ Proposed fix to isolate failures
if (organization.billingEmail) {
- const purchaseUser = await db.query.user.findFirst({
- where: { email: { eq: organization.billingEmail } },
- });
- await notifyResetPassPurchased(
- organization.billingEmail,
- purchaseUser?.name,
- tier,
- amountPaid,
- );
+ try {
+ const purchaseUser = await db.query.user.findFirst({
+ where: { email: { eq: organization.billingEmail } },
+ });
+ await notifyResetPassPurchased(
+ organization.billingEmail,
+ purchaseUser?.name,
+ tier,
+ amountPaid,
+ );
+ } catch (e) {
+ logger.error(
+ "Reset Pass Discord notification failed; suppressing failure",
+ e as Error,
+ );
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (organization.billingEmail) { | |
| const purchaseUser = await db.query.user.findFirst({ | |
| where: { email: { eq: organization.billingEmail } }, | |
| }); | |
| await notifyResetPassPurchased( | |
| organization.billingEmail, | |
| purchaseUser?.name, | |
| tier, | |
| amountPaid, | |
| ); | |
| } | |
| if (organization.billingEmail) { | |
| try { | |
| const purchaseUser = await db.query.user.findFirst({ | |
| where: { email: { eq: organization.billingEmail } }, | |
| }); | |
| await notifyResetPassPurchased( | |
| organization.billingEmail, | |
| purchaseUser?.name, | |
| tier, | |
| amountPaid, | |
| ); | |
| } catch (e) { | |
| logger.error( | |
| "Reset Pass Discord notification failed; suppressing failure", | |
| e as Error, | |
| ); | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/src/stripe.ts` around lines 2596 - 2606, Wrap the billingEmail
notification block in the surrounding purchase fulfillment flow, including
db.query.user.findFirst and notifyResetPassPurchased, with a try-catch. Log or
otherwise handle the notification error without rethrowing, so execution always
continues to the subsequent posthog.capture telemetry step while preserving
best-effort notification behavior.
Summary
Reset Pass purchases (#3093) were the only paid flow with no internal Discord notification — credits, DevPass/chat plan subscribe/renew/cancel, and refunds all post to the billing channel, and a refunded Reset Pass already notified via the generic refund handler. This closes that gap.
notifyResetPassPurchasedtoapps/api/src/utils/discord.ts(email, name, tier, amount — same embed pattern as the other purchase notifiers, posts toDISCORD_NOTIFICATION_URL)fulfillResetPassPurchaseafter the payment-intent dedupe guard, so the synchronous purchase route and thepayment_intent.succeededrecovery webhook can't double-notifyorganization.billingEmail+ user lookup, mirroring the refund notification pathTest plan
pnpm exec turbo run build --filter=apipassessendDiscordNotificationalready swallows webhook failures and skips whenDISCORD_NOTIFICATION_URLis unset, so fulfilment is unaffected either waySummary by CodeRabbit