-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Update PartnerApplicationApproved email to show rewards and bounties #3262
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.
|
WalkthroughThis PR refactors the partner-approved email flow to replace a single Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 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)
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: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/app/(ee)/api/workflows/partner-approved/route.ts (1)
200-216: Remove dead code: group fetching and rewards computation are no longer used.After introducing
getPartnerInviteRewardsAndBountiesat line 218, the group fetching and rewards array computation (lines 200-216) are no longer referenced. Therewardsvariable is never used after line 241 switched to spreadingrewardsAndBounties.🔎 Proposed removal of dead code
- // Find the group to get the rewards - const group = await getGroupOrThrow({ - programId, - groupId, - includeExpandedFields: true, - }); - - const rewards = [ - group.clickReward, - group.leadReward, - group.saleReward, - ].filter(Boolean) as RewardProps[]; - - logger.info({ - message: `Sending email notification to ${partnerUsers.length} partner users.`, - data: partnerUsers, - }); - const rewardsAndBounties = await getPartnerInviteRewardsAndBounties({ programId, groupId: programEnrollment.groupId || program.defaultGroupId, }); + + logger.info({ + message: `Sending email notification to ${partnerUsers.length} partner users.`, + data: partnerUsers, + });
🧹 Nitpick comments (1)
apps/web/app/(ee)/api/workflows/partner-approved/route.ts (1)
220-220: Consider simplifying the groupId parameter.Since
groupIdis destructured fromprogramEnrollmentat line 68 and validated to be truthy at line 163, usingprogramEnrollment.groupId || program.defaultGroupIdis redundant. The fallback will never execute. You could simplify this to justgroupId.🔎 Optional simplification
const rewardsAndBounties = await getPartnerInviteRewardsAndBounties({ programId, - groupId: programEnrollment.groupId || program.defaultGroupId, + groupId, });
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/app/(ee)/api/workflows/partner-approved/route.ts(3 hunks)packages/email/src/templates/partner-application-approved.tsx(5 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: devkiran
Repo: dubinc/dub PR: 3244
File: apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts:148-174
Timestamp: 2025-12-18T16:55:47.136Z
Learning: In the bounty system (e.g., apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts), bounties cannot be created with workflow attributes `partnerEnrolledDays` and `partnerJoined`. Bounty workflows only support attributes available from partner link stats (clicks, sales, leads, conversions, saleAmount) and totalCommissions, which is a subset of the general WORKFLOW_ATTRIBUTES schema.
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/rewards-logic.tsx:268-275
Timestamp: 2025-07-30T15:29:54.131Z
Learning: In apps/web/ui/partners/rewards/rewards-logic.tsx, when setting the entity field in a reward condition, dependent fields (attribute, operator, value) should be reset rather than preserved because different entities (customer vs sale) have different available attributes. Maintaining existing fields when the entity changes would create invalid state combinations and confusing UX.
📚 Learning: 2025-07-30T15:29:54.131Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/rewards-logic.tsx:268-275
Timestamp: 2025-07-30T15:29:54.131Z
Learning: In apps/web/ui/partners/rewards/rewards-logic.tsx, when setting the entity field in a reward condition, dependent fields (attribute, operator, value) should be reset rather than preserved because different entities (customer vs sale) have different available attributes. Maintaining existing fields when the entity changes would create invalid state combinations and confusing UX.
Applied to files:
packages/email/src/templates/partner-application-approved.tsx
📚 Learning: 2025-09-12T17:31:10.548Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2833
File: apps/web/lib/actions/partners/approve-bounty-submission.ts:53-61
Timestamp: 2025-09-12T17:31:10.548Z
Learning: In approve-bounty-submission.ts, the logic `bounty.rewardAmount ?? rewardAmount` is intentional. Bounties with preset reward amounts should use those fixed amounts, and the rewardAmount override parameter is only used when bounty.rewardAmount is null/undefined (for custom reward bounties). This follows the design pattern where bounties are either "flat rate" (fixed amount) or "custom" (variable amount set during approval).
Applied to files:
packages/email/src/templates/partner-application-approved.tsxapps/web/app/(ee)/api/workflows/partner-approved/route.ts
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
packages/email/src/templates/partner-application-approved.tsx
📚 Learning: 2025-07-30T15:25:13.936Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx:56-66
Timestamp: 2025-07-30T15:25:13.936Z
Learning: In apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx, the form schema uses partial condition objects to allow users to add empty/unconfigured condition fields without type errors, while submission validation uses strict schemas to ensure data integrity. This two-stage validation pattern improves UX by allowing progressive completion of complex forms.
Applied to files:
packages/email/src/templates/partner-application-approved.tsx
📚 Learning: 2025-12-18T16:55:47.136Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3244
File: apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts:148-174
Timestamp: 2025-12-18T16:55:47.136Z
Learning: In the bounty system (e.g., apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts), bounties cannot be created with workflow attributes `partnerEnrolledDays` and `partnerJoined`. Bounty workflows only support attributes available from partner link stats (clicks, sales, leads, conversions, saleAmount) and totalCommissions, which is a subset of the general WORKFLOW_ATTRIBUTES schema.
Applied to files:
apps/web/app/(ee)/api/workflows/partner-approved/route.ts
🧬 Code graph analysis (2)
packages/email/src/templates/partner-application-approved.tsx (1)
packages/email/src/react-email.d.ts (5)
Text(15-15)Section(8-8)Row(9-9)Column(10-12)Img(13-13)
apps/web/app/(ee)/api/workflows/partner-approved/route.ts (1)
apps/web/lib/api/partners/get-partner-invite-rewards-and-bounties.ts (1)
getPartnerInviteRewardsAndBounties(19-97)
⏰ 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 (5)
packages/email/src/templates/partner-application-approved.tsx (3)
4-4: LGTM! Imports are correct.The
ColumnandRowcomponents from@react-email/componentsare properly imported and align with the email layout primitives needed for the rewards/bounties lists.Also applies to: 13-13
31-32: LGTM! Props refactoring aligns with the new data structure.The replacement of
rewardDescriptionwith structuredrewardsandbountiesarrays provides better separation of concerns and enables conditional rendering of each section independently.Also applies to: 44-45
75-123: LGTM! Conditional rendering logic is well-structured.The implementation correctly:
- Uses optional chaining for null-safe length checks
- Conditionally renders rewards and bounties sections only when data exists
- Applies appropriate spacing between sections with dynamic className
- Maps over arrays with proper keys and icon/label rendering
apps/web/app/(ee)/api/workflows/partner-approved/route.ts (2)
4-4: LGTM! Import added correctly.The
getPartnerInviteRewardsAndBountiesimport aligns with the refactored email flow that now uses structured rewards/bounties data.
218-221: LGTM! Rewards and bounties data integration looks correct.The call to
getPartnerInviteRewardsAndBountiesproperly fetches structured rewards/bounties data, and spreading the result into the email template aligns with the updatedPartnerApplicationApprovedcomponent props.Also applies to: 241-241
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.