Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steven-tey
Copy link
Collaborator

@steven-tey steven-tey commented Dec 21, 2025

CleanShot 2025-12-21 at 12 01 51@2x

Summary by CodeRabbit

  • New Features
    • Enhanced partner approval emails to display rewards and bounties as organized lists for improved clarity and structure.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Contributor

vercel bot commented Dec 21, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
dub Ready Ready Preview Dec 21, 2025 7:21pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

Walkthrough

This PR refactors the partner-approved email flow to replace a single rewardDescription prop with structured rewards and bounties arrays. The API route now fetches these arrays using getPartnerInviteRewardsAndBounties and spreads the data into the email template, which conditionally renders reward and bounty lists.

Changes

Cohort / File(s) Summary
Partner-approved API route
apps/web/app/(ee)/api/workflows/partner-approved/route.ts
Added import and invocation of getPartnerInviteRewardsAndBounties to fetch rewards and bounties data; replaced rewardDescription payload with spread rewardsAndBounties data in email sending step.
Email template
packages/email/src/templates/partner-application-approved.tsx
Replaced rewardDescription prop with rewards and bounties optional arrays; added conditional rendering to display reward/bounty lists with icon and label; added Column and Row imports for layout structure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Verify that the data structure returned by getPartnerInviteRewardsAndBounties (with icon and label fields) matches the email template's expectations
  • Check the groupId fallback logic (groupId ?? program.defaultGroupId) is correct in all cases
  • Review conditional rendering logic in the email template to ensure proper spacing and layout when both rewards and bounties are present

Possibly related PRs

Suggested reviewers

  • TWilson023

Poem

🐰 A reward once singular, now splits in two,
Rewards and bounties, fresh and new!
Structured arrays dance in the light,
Partner approvals dressed just right,
Icons and labels, a cleaner view—
Hopping forward, refactored through! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Update PartnerApplicationApproved email to show rewards and bounties' directly and specifically describes the main changes in the pull request, which involve updating the partner-approved email template to display rewards and bounties data.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update-application-approved

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 getPartnerInviteRewardsAndBounties at line 218, the group fetching and rewards array computation (lines 200-216) are no longer referenced. The rewards variable is never used after line 241 switched to spreading rewardsAndBounties.

🔎 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 groupId is destructured from programEnrollment at line 68 and validated to be truthy at line 163, using programEnrollment.groupId || program.defaultGroupId is redundant. The fallback will never execute. You could simplify this to just groupId.

🔎 Optional simplification
       const rewardsAndBounties = await getPartnerInviteRewardsAndBounties({
         programId,
-        groupId: programEnrollment.groupId || program.defaultGroupId,
+        groupId,
       });
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3015b03 and 5d19dba.

📒 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.tsx
  • apps/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 Column and Row components from @react-email/components are 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 rewardDescription with structured rewards and bounties arrays 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 getPartnerInviteRewardsAndBounties import 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 getPartnerInviteRewardsAndBounties properly fetches structured rewards/bounties data, and spreading the result into the email template aligns with the updated PartnerApplicationApproved component props.

Also applies to: 241-241

@steven-tey
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@steven-tey steven-tey merged commit 854a16e into main Dec 21, 2025
8 of 9 checks passed
@steven-tey steven-tey deleted the update-application-approved branch December 21, 2025 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants