-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Record lead commissions/workflows in attributeViaPromoCode #3135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughMoved lead-related webhook dispatch and lead state updates out of the main checkout sale path into a dedicated lead side-effects block invoked during promo-code attribution; standardized workspace usage increment to 1 and added an internal helper to increment link leads. Changes
Sequence DiagramsequenceDiagram
participant Stripe
participant Webhook as Checkout Handler
participant PromoAttr as Promo Attribution
participant DB as Database
participant Webhooks as Webhook Dispatch
Stripe->>Webhook: Checkout Session Completed
Webhook->>DB: Record sale
Webhook->>DB: Increment workspace usage (1)
alt Promo code present
Webhook->>PromoAttr: attributeViaPromoCode()
PromoAttr->>DB: Create/update lead record
Note right of PromoAttr: Lead side-effects block
PromoAttr->>DB: incrementLinkLeads(linkId) // increments leads, updates lastLeadAt
PromoAttr->>DB: If partner -> trigger commissions & leadRecorded workflow
PromoAttr->>DB: Sync partner link stats
PromoAttr->>Webhooks: Send transformed lead.created webhook
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (3)📓 Common learnings📚 Learning: 2025-10-02T22:46:22.739ZApplied to files:
📚 Learning: 2025-08-25T17:33:45.072ZApplied to files:
🧬 Code graph analysis (1)apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts (6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (4)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts (1)
600-665: Consider error handling: Link update failure blocks downstream operations.The lead side-effects block uses a single async IIFE within
waitUntil. If the link update (lines 603-613) fails, the partner commissions, workflows, and webhooks won't be triggered. SincerecordLeadalready succeeded (line 598), this could lead to inconsistent state.Consider wrapping the link update in a try-catch or using
Promise.allSettledfor all operations to ensure partner-related side-effects run even if link updates fail.Example refactor:
waitUntil( (async () => { const [linkUpdateResult, ...partnerResults] = await Promise.allSettled([ prisma.link.update({ where: { id: link.id }, data: { leads: { increment: 1 }, lastLeadAt: new Date(), }, include: includeTags, }), // Partner operations link.programId && link.partnerId ? Promise.allSettled([ createPartnerCommission({ /* ... */ }), executeWorkflows({ /* ... */ }), syncPartnerLinksStats({ /* ... */ }), ]) : Promise.resolve([]), ]); const linkUpdated = linkUpdateResult.status === 'fulfilled' ? linkUpdateResult.value : link; // fallback to original link if update failed // Send webhook with best available data await sendWorkspaceWebhook({ /* ... */ }); })(), );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-02T22:46:22.739Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2924
File: apps/web/lib/api/conversions/track-lead.ts:7-7
Timestamp: 2025-10-02T22:46:22.739Z
Learning: In apps/web/lib/api/conversions/track-lead.ts, lead events are cached in Redis for 5 minutes (keys: `leadCache:${customer.id}` and `leadCache:${customer.id}:${stringifiedEventName}`) to provide immediate data availability while Tinybird ingestion happens asynchronously. This caching pattern allows for async-only recording without breaking "wait" mode semantics.
Applied to files:
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts
📚 Learning: 2025-08-25T17:33:45.072Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2736
File: apps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.ts:12-12
Timestamp: 2025-08-25T17:33:45.072Z
Learning: The WorkflowTrigger enum in packages/prisma/schema/workflow.prisma contains three values: leadRecorded, saleRecorded, and commissionEarned. All three are properly used throughout the codebase.
Applied to files:
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts
🧬 Code graph analysis (1)
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts (5)
apps/web/lib/types.ts (1)
WebhookPartner(410-410)apps/web/lib/partners/create-partner-commission.ts (1)
createPartnerCommission(59-379)apps/web/lib/api/workflows/execute-workflows.ts (1)
executeWorkflows(17-99)apps/web/lib/webhook/publish.ts (1)
sendWorkspaceWebhook(8-45)apps/web/lib/webhook/transform.ts (1)
transformLeadEventData(60-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (3)
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts (3)
377-387: LGTM: Workspace usage increment standardized.The fixed increment of 1 per sale is clearer than the previous conditional logic. Lead-related usage tracking is now handled separately in the attribution flow.
389-402: LGTM: Customer stats update simplified.The customer stats update now focuses solely on sale metrics, which is consistent with the refactoring to move lead-related side-effects to the dedicated attribution block.
514-514: LGTM: Required field for workspace webhook.The
webhookEnabledfield is needed for thesendWorkspaceWebhookcall in the lead side-effects block (line 652).
Summary by CodeRabbit