-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Partner notification settings #2670
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 Git ↗︎
|
|
""" WalkthroughThis change introduces partner user notification preferences to the application. It adds new Prisma models for storing notification settings per partner user and partner invites. Server-side actions and API routes are added to fetch and update these preferences. Notification email logic is updated to send emails individually to users who opted in. New UI components and navigation for managing partner notification settings are included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI (Notifications Page)
participant API (GET/POST)
participant Server Action
participant DB
User->>UI (Notifications Page): Visit settings/notifications
UI (Notifications Page)->>API (GET): Fetch notification preferences
API (GET)->>DB: Query PartnerNotificationPreferences
DB-->>API (GET): Return preferences
API (GET)-->>UI (Notifications Page): Send preferences
User->>UI (Notifications Page): Toggle notification switch
UI (Notifications Page)->>Server Action: updatePartnerNotificationPreference({type, value})
Server Action->>DB: Update PartnerNotificationPreferences
DB-->>Server Action: Confirm update
Server Action-->>UI (Notifications Page): { ok: true }
sequenceDiagram
participant System
participant DB
participant EmailService
System->>DB: Fetch partner users with notificationPreference (sale/applicationApproved)
DB-->>System: Return users and emails
loop For each opted-in user
System->>EmailService: Send notification email (personalized)
end
Estimated code review effort4 (~90 minutes) Suggested reviewers
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
| notificationPreference: { | ||
| create: {}, | ||
| }, |
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.
A PartnerNotificationPreferences record will be created when the partner is created, but we'll have to backfill this for existing partners.
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: 3
🧹 Nitpick comments (1)
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (1)
17-30: Consider moving notification definitions to a shared constants file.The hardcoded
notificationsarray could benefit from being moved to a shared constants file for better maintainability and reusability across the codebase.Create a new constants file and move this definition:
// apps/web/lib/constants/partner-notifications.ts export const PARTNER_NOTIFICATIONS = [ { type: "sale" as const, icon: InvoiceDollar, title: "New sale", description: "Alert when a new sale is made.", }, { type: "applicationApproved" as const, icon: CircleCheck, title: "Application approval", description: "Alert when an application to a program is approved.", }, ] as const;Then import and use it in the component:
+ import { PARTNER_NOTIFICATIONS } from "@/lib/constants/partner-notifications"; - const notifications = [ - // ... array content - ]; export function PartnerSettingsNotificationsPageClient() { // ... rest of component return ( <div className="mt-2 grid grid-cols-1 gap-3"> - {notifications.map(({ type, icon: Icon, title, description }) => ( + {PARTNER_NOTIFICATIONS.map(({ type, icon: Icon, title, description }) => ( // ... rest of JSX ))} </div> ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts(1 hunks)apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx(1 hunks)apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page.tsx(1 hunks)apps/web/lib/actions/partners/bulk-approve-partners.ts(1 hunks)apps/web/lib/actions/partners/onboard-partner.ts(1 hunks)apps/web/lib/actions/partners/update-partner-notification-preference.ts(1 hunks)apps/web/lib/api/partners/notify-partner-sale.ts(2 hunks)apps/web/lib/partners/approve-partner-enrollment.ts(4 hunks)apps/web/lib/partners/bulk-approve-partners.ts(2 hunks)apps/web/lib/zod/schemas/partner-profile.ts(1 hunks)apps/web/ui/layout/page-content/index.tsx(1 hunks)apps/web/ui/layout/sidebar/partners-sidebar-nav.tsx(4 hunks)packages/email/src/templates/new-sale-alert-partner.tsx(1 hunks)packages/email/src/templates/partner-application-approved.tsx(1 hunks)packages/prisma/schema/partner.prisma(1 hunks)
🧠 Learnings (8)
packages/email/src/templates/partner-application-approved.tsx (1)
Learnt from: devkiran
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.
packages/email/src/templates/new-sale-alert-partner.tsx (1)
Learnt from: devkiran
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.
apps/web/lib/partners/approve-partner-enrollment.ts (1)
Learnt from: devkiran
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.
apps/web/lib/zod/schemas/partner-profile.ts (2)
Learnt from: devkiran
PR: #2433
File: apps/web/app/api/workspaces/[idOrSlug]/billing/payment-methods/route.ts:74-76
Timestamp: 2025-05-29T09:47:33.583Z
Learning: When Zod enum validation is used (e.g., z.enum(PAYMENT_METHOD_TYPES)), it ensures the validated value is one of the valid enum values, making subsequent type casts to the corresponding TypeScript types safe without additional validation.
Learnt from: devkiran
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.
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (1)
Learnt from: devkiran
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.
apps/web/lib/actions/partners/bulk-approve-partners.ts (1)
Learnt from: devkiran
PR: #2177
File: apps/web/lib/api/links/bulk-create-links.ts:66-84
Timestamp: 2025-06-06T07:59:03.120Z
Learning: In apps/web/lib/api/links/bulk-create-links.ts, the team accepts the risk of potential undefined results from links.find() operations when building invalidLinks arrays, because existing links are fetched from the database based on the input links, so matches are expected to always exist.
apps/web/lib/partners/bulk-approve-partners.ts (1)
Learnt from: TWilson023
PR: #2538
File: apps/web/ui/partners/overview/blocks/commissions-block.tsx:16-27
Timestamp: 2025-06-18T20:26:25.177Z
Learning: In the Dub codebase, components that use workspace data (workspaceId, defaultProgramId) are wrapped in WorkspaceAuth which ensures these values are always available, making non-null assertions safe. This is acknowledged as a common pattern in their codebase, though not ideal.
apps/web/ui/layout/sidebar/partners-sidebar-nav.tsx (1)
Learnt from: devkiran
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.
🧬 Code Graph Analysis (5)
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page.tsx (3)
apps/web/ui/layout/page-content/index.tsx (1)
PageContent(11-97)apps/web/ui/layout/page-width-wrapper.tsx (1)
PageWidthWrapper(4-21)apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (1)
PartnerSettingsNotificationsPageClient(32-116)
apps/web/lib/api/partners/notify-partner-sale.ts (1)
packages/email/src/templates/new-sale-alert-partner.tsx (1)
NewSaleAlertPartner(17-140)
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (3)
apps/web/lib/zod/schemas/partner-profile.ts (1)
partnerNotificationTypes(130-130)apps/web/lib/actions/partners/update-partner-notification-preference.ts (1)
updatePartnerNotificationPreference(14-37)packages/ui/src/icons/index.tsx (1)
Icon(77-77)
apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts (1)
apps/web/lib/auth/partner.ts (1)
withPartnerProfile(26-85)
apps/web/lib/actions/partners/update-partner-notification-preference.ts (2)
apps/web/lib/zod/schemas/partner-profile.ts (1)
partnerNotificationTypes(130-130)apps/web/lib/actions/safe-action.ts (1)
authPartnerActionClient(84-112)
🧰 Additional context used
🧠 Learnings (8)
packages/email/src/templates/partner-application-approved.tsx (1)
Learnt from: devkiran
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.
packages/email/src/templates/new-sale-alert-partner.tsx (1)
Learnt from: devkiran
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.
apps/web/lib/partners/approve-partner-enrollment.ts (1)
Learnt from: devkiran
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.
apps/web/lib/zod/schemas/partner-profile.ts (2)
Learnt from: devkiran
PR: #2433
File: apps/web/app/api/workspaces/[idOrSlug]/billing/payment-methods/route.ts:74-76
Timestamp: 2025-05-29T09:47:33.583Z
Learning: When Zod enum validation is used (e.g., z.enum(PAYMENT_METHOD_TYPES)), it ensures the validated value is one of the valid enum values, making subsequent type casts to the corresponding TypeScript types safe without additional validation.
Learnt from: devkiran
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.
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (1)
Learnt from: devkiran
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.
apps/web/lib/actions/partners/bulk-approve-partners.ts (1)
Learnt from: devkiran
PR: #2177
File: apps/web/lib/api/links/bulk-create-links.ts:66-84
Timestamp: 2025-06-06T07:59:03.120Z
Learning: In apps/web/lib/api/links/bulk-create-links.ts, the team accepts the risk of potential undefined results from links.find() operations when building invalidLinks arrays, because existing links are fetched from the database based on the input links, so matches are expected to always exist.
apps/web/lib/partners/bulk-approve-partners.ts (1)
Learnt from: TWilson023
PR: #2538
File: apps/web/ui/partners/overview/blocks/commissions-block.tsx:16-27
Timestamp: 2025-06-18T20:26:25.177Z
Learning: In the Dub codebase, components that use workspace data (workspaceId, defaultProgramId) are wrapped in WorkspaceAuth which ensures these values are always available, making non-null assertions safe. This is acknowledged as a common pattern in their codebase, though not ideal.
apps/web/ui/layout/sidebar/partners-sidebar-nav.tsx (1)
Learnt from: devkiran
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.
🧬 Code Graph Analysis (5)
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page.tsx (3)
apps/web/ui/layout/page-content/index.tsx (1)
PageContent(11-97)apps/web/ui/layout/page-width-wrapper.tsx (1)
PageWidthWrapper(4-21)apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (1)
PartnerSettingsNotificationsPageClient(32-116)
apps/web/lib/api/partners/notify-partner-sale.ts (1)
packages/email/src/templates/new-sale-alert-partner.tsx (1)
NewSaleAlertPartner(17-140)
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (3)
apps/web/lib/zod/schemas/partner-profile.ts (1)
partnerNotificationTypes(130-130)apps/web/lib/actions/partners/update-partner-notification-preference.ts (1)
updatePartnerNotificationPreference(14-37)packages/ui/src/icons/index.tsx (1)
Icon(77-77)
apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts (1)
apps/web/lib/auth/partner.ts (1)
withPartnerProfile(26-85)
apps/web/lib/actions/partners/update-partner-notification-preference.ts (2)
apps/web/lib/zod/schemas/partner-profile.ts (1)
partnerNotificationTypes(130-130)apps/web/lib/actions/safe-action.ts (1)
authPartnerActionClient(84-112)
⏰ 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 (22)
apps/web/lib/zod/schemas/partner-profile.ts (1)
129-130: LGTM! Well-structured notification type schema.The Zod enum definition for notification types is clean and follows established patterns in the codebase. The two notification types align perfectly with the partner notification features being implemented.
packages/email/src/templates/partner-application-approved.tsx (1)
172-175: LGTM! Consistent integration with notification settings.The addition of the
notificationSettingsUrlprop to the Footer component provides users with a direct link to manage their notification preferences, which enhances the user experience.packages/email/src/templates/new-sale-alert-partner.tsx (1)
131-134: LGTM! Consistent with other email templates.The notification settings URL addition matches the pattern established in the partner application approved template, ensuring a consistent user experience across all partner notification emails.
apps/web/lib/actions/partners/onboard-partner.ts (1)
63-65: LGTM! Proper initialization of notification preferences.The nested creation of notification preferences ensures new partner users have their settings initialized during onboarding. The empty object will correctly use schema defaults.
Note: As mentioned in previous comments, existing partners will need backfilling of notification preferences, but that's outside the scope of this change.
apps/web/lib/actions/partners/bulk-approve-partners.ts (1)
36-49: LGTM! Well-structured query for notification preferences.The nested Prisma query correctly filters partner users based on their notification preferences and includes the necessary user data for individualized email notifications. This approach ensures only users who opted in for application approval notifications receive emails.
apps/web/ui/layout/page-content/index.tsx (1)
21-21: LGTM! Good enhancement for component flexibility.Making the
hrefproperty optional in thetitleInfoobject type is a sensible change that allows for more flexible usage patterns while maintaining backward compatibility.Also applies to: 29-29
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page.tsx (1)
5-19: Well-structured notification settings page implementation.The component follows good patterns with clear separation of concerns. The descriptive subtitle effectively communicates the personal nature of these notification preferences.
apps/web/lib/partners/approve-partner-enrollment.ts (3)
83-96: Good implementation of notification preference filtering.The query correctly includes partner users who have opted in for application approval notifications.
140-142: Add null check for email filtering.Good use of filter to ensure only valid emails are included.
166-192: Batch email implementation looks correct.The transition from single email to batch emails for opted-in users is well implemented. The conditional check ensures no empty batch is sent when there are no opted-in users.
apps/web/lib/api/partners/notify-partner-sale.ts (3)
50-63: Proper implementation of user notification preferences.The query correctly fetches partner users who have opted in for sale notifications.
112-114: Clean email extraction with null filtering.Good defensive programming by filtering out null emails.
117-131: Well-implemented batch notification with rate limiting.Good use of the limiter for rate-controlled email sending. The conditional logic ensures no processing occurs when there are no opted-in users.
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx (1)
92-111: LGTM: Well-implemented optimistic updates with proper error handling.The Switch component implementation correctly:
- Uses optimistic updates for immediate UI feedback
- Properly handles loading states by disabling toggles
- Includes null checks for preferences data
- Maintains consistent state management
apps/web/lib/actions/partners/update-partner-notification-preference.ts (1)
8-11: LGTM: Proper schema validation.The Zod schema correctly validates the input with:
- Type restriction using
partnerNotificationTypesenum- Boolean value validation
packages/prisma/schema/partner.prisma (2)
71-71: LGTM: Proper optional relationship definition.The optional one-to-one relationship is correctly defined, allowing existing partner users to not have notification preferences initially.
77-85: LGTM: Well-designed notification preferences model.The model design is excellent:
- Proper unique constraint on
partnerUserIdensures one-to-one relationship- Cascade delete maintains referential integrity
- Sensible default values (opt-in by default) provide good user experience
- Boolean fields align with the Zod enum types defined in the codebase
apps/web/lib/partners/bulk-approve-partners.ts (2)
33-35: LGTM: Proper type definition for notification-aware partner data.The updated type correctly reflects that partner users are now filtered based on their notification preferences and includes the necessary email information.
90-116: LGTM: Correct implementation of per-user email notifications.The email sending logic properly:
- Handles multiple users per partner
- Filters out null email addresses
- Sends individual emails to each user who opted in
- Maintains the same email content structure
- Uses efficient batch sending
apps/web/ui/layout/sidebar/partners-sidebar-nav.tsx (3)
64-70: LGTM: Well-structured navigation group addition.The new "Settings" navigation group follows the established pattern with:
- Descriptive name and description
- Appropriate icon (Gear)
- Correct href pointing to the notifications page
- Proper active state logic
199-216: LGTM: Consistent navigation area structure.The new
partnerSettingsarea maintains consistency with existing areas:
- Proper title and direction
- Logical "Account" section grouping
- Appropriate icon for notifications
- Correct href and exact matching
264-272: LGTM: Proper path matching logic with correct precedence.The updated currentArea logic correctly:
- Places
/settingscheck before/profileto avoid conflicts- Maintains proper precedence order
- Uses consistent pattern matching approach
apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx
Outdated
Show resolved
Hide resolved
|
@CodeRabbit final review |
|
Tip For best results, initiate chat on the files or code changes. @steven-tey This PR looks excellent and ready for merge! 🎉 Final Review SummaryStrong Implementation ✅
Architecture Highlights 🏗️
Comprehensive Coverage 📋
Code Quality 💎
This is a well-executed feature that enhances the partner experience while maintaining code quality and security standards. Ready to ship! 🚀 ᕱ⑅ᕱ excited rabbit noises ✨ |
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: 1
🧹 Nitpick comments (1)
apps/web/lib/api/partners/notify-partner-application.ts (1)
61-63: Fix unnecessary ternary operator.The static analysis tool correctly identified this as a useless ternary operator. Since you're converting a truthy/falsy value to a boolean, you can simplify this expression.
- autoApprovePartners: program.autoApprovePartnersEnabledAt - ? true - : false, + autoApprovePartners: Boolean(program.autoApprovePartnersEnabledAt),Or alternatively:
- autoApprovePartners: program.autoApprovePartnersEnabledAt - ? true - : false, + autoApprovePartners: !!program.autoApprovePartnersEnabledAt,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts(1 hunks)apps/web/lib/api/partners/notify-partner-application.ts(2 hunks)apps/web/lib/api/partners/notify-partner-sale.ts(3 hunks)apps/web/lib/partners/bulk-approve-partners.ts(4 hunks)
🧬 Code Graph Analysis (1)
apps/web/lib/api/partners/notify-partner-application.ts (1)
packages/email/src/templates/partner-application-received.tsx (1)
PartnerApplicationReceived(17-178)
🪛 Biome (1.9.4)
apps/web/lib/api/partners/notify-partner-application.ts
[error] 61-63: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/lib/api/partners/notify-partner-sale.ts
- apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts
- apps/web/lib/partners/bulk-approve-partners.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/lib/api/partners/notify-partner-application.ts (1)
packages/email/src/templates/partner-application-received.tsx (1)
PartnerApplicationReceived(17-178)
🪛 Biome (1.9.4)
apps/web/lib/api/partners/notify-partner-application.ts
[error] 61-63: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
⏰ 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 (2)
apps/web/lib/api/partners/notify-partner-application.ts (2)
1-2: LGTM: Imports support the batch email functionality.The new imports for
VARIANT_TO_FROM_MAPandchunkutility are appropriate for the batch email sending refactor and improve consistency in email handling.Also applies to: 6-6
71-76: LGTM: Well-implemented batch email sending.The batch sending approach with 100 emails per chunk is efficient and appropriate for email service limits. Using
Promise.allfor concurrent batch processing will significantly improve performance compared to individual email sending.The optional chaining on
resend?.batch.send()properly handles potential undefined cases.
|
@CodeRabbit final review please |
|
Tip For best results, initiate chat on the files or code changes. @steven-tey This PR represents a well-executed and comprehensive implementation of partner notification settings! Here's my final review: 🎯 Implementation ExcellenceDatabase Design ✅
Security & Authentication 🔒
UI/UX Excellence 🎨
Email Logic Improvement 📧
🏗️ Architecture Strengths
🔍 Code Quality Assessment
✅ Ready for MergeThis is a production-ready feature that enhances the partner experience while maintaining high code quality standards. The implementation is thorough, secure, and follows best practices. Recommendation: APPROVE - Ready to ship! 🚀 Great work on this comprehensive feature addition! 🌟 |
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 (2)
apps/web/scripts/backfill-notification-preferences.ts (1)
12-12: Consider the batch size for larger datasets.The current batch size of 100 is reasonable, but for very large partner user bases, you might want to make this configurable or add progress logging to track multiple runs.
apps/web/lib/api/partners/notify-partner-sale.ts (1)
113-116: Add null check for partner users array.While the filter should handle null emails, consider adding a length check to avoid unnecessary processing when no partner users have opted in.
const partnerEmailsToNotify = partner.users .map(({ user }) => user.email) .filter(Boolean) as string[]; +if (partnerEmailsToNotify.length === 0 && workspaceUsers.length === 0) { + console.log("No recipients found for partner sale notification"); + return; +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts(1 hunks)apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx(1 hunks)apps/web/lib/api/partners/notify-partner-sale.ts(3 hunks)apps/web/scripts/backfill-notification-preferences.ts(1 hunks)packages/prisma/schema/partner.prisma(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts
- apps/web/app/(ee)/partners.dub.co/(dashboard)/settings/notifications/page-client.tsx
- packages/prisma/schema/partner.prisma
⏰ 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 (2)
apps/web/lib/api/partners/notify-partner-sale.ts (2)
51-65: Excellent refactor to use notification preferences.The query now properly filters partner users based on their commission notification preferences, which aligns perfectly with the new notification system.
118-143: Well-structured email batching implementation.The email construction logic is clean and properly separates partner and workspace user notifications. The use of chunking for batch sending is a good performance optimization.
Summary by CodeRabbit
New Features
Improvements
Bug Fixes