-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add support for manual commissions #2513
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 ↗︎
|
|
Warning Rate limit exceeded@devkiran has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 3 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThis change refactors commission and reward type handling across the codebase, introducing new enums ( Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI
participant Backend
participant DB
User->>UI: Selects commission type (e.g., "custom")
UI->>Backend: Submits commission action (e.g., mark as duplicate)
Backend->>DB: Fetch commission details
DB-->>Backend: Return commission (with type)
alt If commission type is "custom"
Backend-->>UI: Throw error ("You cannot mark a custom commission as ...")
else
Backend->>DB: Proceed with action (update status)
DB-->>Backend: Confirm update
Backend-->>UI: Action successful
end
Possibly related PRs
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 (
|
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
…o manual-commission
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: 5
🔭 Outside diff range comments (1)
packages/prisma/client.ts (1)
1-20: 💡 Verification agent❓ Verification inconclusive
CommissionTypeis still implicitly re-exported viaexport *Although
CommissionTypewas removed from the explicit list (👍), the wildcard export on line 1 still exposes every enum from@prisma/client, so downstream code can continue to importCommissionTypeand bypass the refactor.-export * from "@prisma/client"; +// Re-export selected members to avoid leaking deprecated enums. +export { + CommissionStatus, + EventType, + FolderType, + FolderUserRole, + InvoiceStatus, + LinkStructure, + PartnerBannedReason, + PartnerProfileType, + PartnerRole, + PartnerStatus, + PayoutStatus, + Prisma, + ProgramEnrollmentStatus, + RewardStructure, + Role, + WebhookReceiver, +} from "@prisma/client";Alternatively, keep the wildcard and add an explicit
export type CommissionType = neverto cause compile-time failures wherever the old enum is referenced.
Avoid wildcard re-export to prevent leaking deprecated enums
The top-level
export * from "@prisma/client"still exposes every enum—including the deprecatedCommissionType—so downstream code can continue to import it. To fully removeCommissionType, either:
- Replace the wildcard export with an explicit list of allowed exports:
- export * from "@prisma/client"; + // Re-export only supported members to avoid leaking deprecated enums + export { + CommissionStatus, + EventType, + FolderType, + FolderUserRole, + InvoiceStatus, + LinkStructure, + PartnerBannedReason, + PartnerProfileType, + PartnerRole, + PartnerStatus, + PayoutStatus, + Prisma, + ProgramEnrollmentStatus, + RewardStructure, + Role, + WebhookReceiver, + } from "@prisma/client";- Or keep the wildcard but explicitly block
CommissionType:export * from "@prisma/client"; export type CommissionType = never;File: packages/prisma/client.ts
Lines: 1–20
🧹 Nitpick comments (8)
apps/web/scripts/tella/update-commissions.ts (1)
20-38: Concurrent DB calls: throttle to avoid connection exhaustion
Promise.allfires 50commission.updatequeries in parallel.
If this script is ever pointed at a larger batch (or the default take is removed), it can easily exceed the pool size. Considerp-mapwith a concurrency limit or a simplefor … ofloop withawait.apps/web/lib/rewardful/import-campaign.ts (1)
36-40: Handle unexpectedreward_typevalues explicitly
reward_type === "amount" ? … : …silently treats every non-amountvalue aspercentage.
A defensive switch improves clarity and surfaces API drifts:-let newType = - reward_type === "amount" - ? RewardStructure.flat - : RewardStructure.percentage; +let newType: RewardStructure; +switch (reward_type) { + case "amount": + newType = RewardStructure.flat; + break; + case "percentage": + newType = RewardStructure.percentage; + break; + default: + throw new Error(`Unsupported reward_type: ${reward_type}`); +}apps/web/ui/partners/commission-row-menu.tsx (1)
48-50: Good guard, but rely on enum constant not magic stringPrefer the generated enum to avoid typos and refactor churn:
-import { CommissionType } from "@dub/prisma/client"; -… -if (row.original.type === "custom") { +if (row.original.type === CommissionType.custom) { return null; }apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/use-commission-filters.tsx (1)
79-83: Hard-coded filter list duplicated across filesThe literal array
["click", "lead", "sale", "custom"]is now the third place this list appears. Consider extracting to a shared constant (e.g.COMMISSION_EVENT_TYPES) to avoid drift when another type is added.- options: ["click", "lead", "sale", "custom"].map((slug) => ({ + import { COMMISSION_EVENT_TYPES } from "@/lib/constants"; + options: COMMISSION_EVENT_TYPES.map((slug) => ({apps/web/lib/api/sales/construct-reward-amount.ts (1)
1-12: Compare against the enum value instead of string literal
RewardStructureis emitted by Prisma as both a value object and a type union.
Using the value object prevents silent breakage if the enum member is renamed:-return type === "percentage" +return type === RewardStructure.percentageThis keeps the comparison type-safe and discoverable by IDE refactors.
packages/prisma/schema/commission.prisma (1)
11-16: Consider documenting / constraining the newcustomtype
customcommissions don’t clearly map to eitheramount(sale) orquantity(click/lead).
Without nullable fields or a check constraint, consumers may have to populate both columns with sentinel values to satisfyNOT NULL.Options:
- Make
amount&quantitynullable and add a@@checkensuring exactly one is non-null pertype.- Keep them required but add a migration script & code-level guard that enforces one or the other.
This avoids bad data and simplifies downstream logic.
apps/web/ui/partners/comission-type-icon.tsx (2)
11-16: Mark the icon map as immutable for safer typingsAdd
as constto preserve literal types and prevent accidental mutation:-const ICONS_MAP = { +const ICONS_MAP = { click: { icon: CursorRays, className: "text-blue-500" }, lead: { icon: UserCheck, className: "text-purple-500" }, sale: { icon: InvoiceDollar, className: "text-teal-500" }, custom: { icon: MoneyBills2, className: "text-gray-500" }, -}; +} as const;
25-27: Graceful fallback for unexpected types
ICONS_MAP[type]will throw if an unknowntypeis passed.
Provide a default icon to avoid runtime errors:-const { icon: Icon, className: iconClassName } = ICONS_MAP[type]; +const { icon: Icon, className: iconClassName } = + ICONS_MAP[type] ?? ICONS_MAP.sale; // fallback
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/overview/page-client.tsx(2 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/use-commission-filters.tsx(1 hunks)apps/web/lib/actions/partners/mark-commission-duplicate.ts(1 hunks)apps/web/lib/actions/partners/mark-commission-fraud-or-canceled.ts(1 hunks)apps/web/lib/api/sales/construct-reward-amount.ts(1 hunks)apps/web/lib/rewardful/import-campaign.ts(2 hunks)apps/web/lib/zod/schemas/commissions.ts(2 hunks)apps/web/lib/zod/schemas/discount.ts(2 hunks)apps/web/lib/zod/schemas/program-onboarding.ts(2 hunks)apps/web/lib/zod/schemas/rewards.ts(3 hunks)apps/web/scripts/tella/update-commissions.ts(2 hunks)apps/web/ui/partners/add-edit-reward-sheet.tsx(3 hunks)apps/web/ui/partners/comission-type-icon.tsx(2 hunks)apps/web/ui/partners/commission-row-menu.tsx(1 hunks)packages/prisma/client.ts(1 hunks)packages/prisma/schema/commission.prisma(2 hunks)packages/prisma/schema/discount.prisma(1 hunks)packages/prisma/schema/program.prisma(0 hunks)packages/prisma/schema/reward.prisma(1 hunks)
💤 Files with no reviewable changes (1)
- packages/prisma/schema/program.prisma
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (14)
packages/prisma/schema/discount.prisma (1)
4-6: Migration reminder: existing rows need enum translationChanging
typefromCommissionType→RewardStructurewill leave existing rows with the old enum value.
Ensure the migration script updates stored values (flat/percentage) before applying the new enum, otherwise deploys will fail.apps/web/lib/rewardful/import-campaign.ts (1)
32-48:findFirstequality check ignoresundefinedbut notnull
maxDurationis included in thewhereclause even when it isnull, restricting the lookup to rewards whosemaxDuration IS NULL.
If the intention is to ignore the field when the API omits it, passundefinedinstead ofnull(or remove the property when falsy).apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/overview/page-client.tsx (2)
8-8: Switched toRewardStructureenum – looks goodImport correctly aligns with the schema refactor.
76-76:Details
❓ Verification inconclusive
Verify
RewardStructurestill contains the"flat"literal
(data.type ?? "flat") as RewardStructureassumes"flat"exists in the new enum. If the enum was also renamed or its members were changed (e.g.FIXEDinstead offlat), this will compile-error or, worse, cast an invalid value at runtime in JS.
🏁 Script executed:
#!/bin/bash # Confirm that "flat" is still a member of RewardStructure in the Prisma schema rg -n '"flat"' packages/prisma | headLength of output: 39
Verify
RewardStructurestill includes the"flat"literalPlease confirm that the Prisma schema’s
RewardStructureenum (in packages/prisma/schema.prisma) and the generated client still define a member namedflat. The expressiontype: (data.type ?? "flat") as RewardStructure,will either fail to compile or cast an invalid value at runtime if
flatwas renamed, removed, or changed (e.g. toFIXED).• Location: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/overview/page-client.tsx line 76
• Snippet:type: (data.type ?? "flat") as RewardStructure,apps/web/lib/actions/partners/mark-commission-fraud-or-canceled.ts (1)
35-39: Good guard against invalid state transitionsEarly-out prevents
"custom"commissions from being marked fraud/canceled, matching new business rules.apps/web/lib/zod/schemas/program-onboarding.ts (2)
1-1: Enum import updated correctly
RewardStructurereplacesCommissionTypewithout changing external API.
36-36: Schema now tied toRewardStructure– ensure default value handledBecause
typeis nownullish, callers relying on a default"flat"need to set it explicitly (as done inpage-client.tsx). Just double-check tests cover thenullcase.apps/web/ui/partners/add-edit-reward-sheet.tsx (1)
602-636: Copy changes only – UI strings consistent with new terminologyRenaming to “Reward …” keeps the UI aligned with backend enums. No functional impact detected.
packages/prisma/schema/commission.prisma (1)
28-31: Default value missing for the renamed enum
type CommissionTypelost its@defaultafter the refactor.
If legacy inserts relied on the previous default, they will now fail.
Add an explicit default (e.g.,@default(sale)) or migrate application code to always supplytype.apps/web/lib/zod/schemas/discount.ts (2)
1-2: Good move toRewardStructureImporting the new enum keeps schemas consistent with the DB layer.
24-30: Verify default value alignment
createDiscountSchemadefaultstypeto"flat"while the Prisma model’s default (per migration summary) is"percentage".
Confirm this intentional divergence; otherwise, choose one authoritative default to avoid confusion.apps/web/lib/zod/schemas/rewards.ts (2)
1-1: Import looks good – verify dead-code
EventTypeis still imported but no longer changed in this diff. If it’s unused after the wider refactor, drop the import to keep tree-shaking tight.
23-24: Schema now enforcesRewardStructure– ✅Switching to the dedicated enum tightens validation and matches the Prisma schema.
packages/prisma/schema/reward.prisma (1)
1-10: Enums introduced cleanlyIntroducing
EventTypeandRewardStructuredirectly in the schema makes downstream typing clearer. Values follow Prisma’s convention and the defaults line up with existing data, so no concerns here.
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please 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: 3
🔭 Outside diff range comments (1)
apps/web/scripts/convert-manual-commissions.ts (1)
74-75: 🛠️ Refactor suggestionExit with proper error code on failure
Unhandled promise rejections will be swallowed under some Node versions. Attach a catcher so CI/cron jobs fail loudly.
-main(); +main().catch((err) => { + console.error(err); + process.exit(1); +});
🧹 Nitpick comments (1)
apps/web/scripts/convert-manual-commissions.ts (1)
9-19: Limit the SELECT list for better IO and privacy
include: { partner: true }fetches the entirepartnerrecord, but the script only needspartner.name. Useselectto reduce payload and avoid unintentionally loading PII.- include: { - partner: true, - }, + select: { + id: true, + amount: true, + partnerId: true, + programId: true, + partner: { select: { name: true } }, + },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/scripts/convert-manual-commissions.ts(1 hunks)packages/prisma/schema/commission.prisma(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/prisma/schema/commission.prisma
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (2)
apps/web/scripts/convert-manual-commissions.ts (2)
52-65: Consider settingamountinstead ofearningsonlyDown-stream code often expects
amountto reflect the original transaction value. Storing it as zero while duplicating it inearningsmay break metrics or validations.Confirm the domain rules; if zero is intentional, leave a comment explaining why to avoid future confusion.
1-5: Imports & env bootstrapping look good
dotenv-flow/configearly-loads env vars before Prisma is touched – nice touch, keeps local execution friction-free.
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
🧹 Nitpick comments (2)
apps/web/app/(ee)/api/partner-profile/programs/[programId]/earnings/count/route.ts (2)
69-71: Deduplicate IDs before querying PrismaFiltering out
nullIDs is a solid fix.
However, the resulting array can still include duplicates, creating unnecessary work for the database and transferring redundant data over the wire. De-dupe cheaply withSet:- in: counts - .map(({ linkId }) => linkId) - .filter((id): id is string => id !== null), + in: Array.from( + new Set( + counts + .map(({ linkId }) => linkId) + .filter((id): id is string => id !== null) + ) + ),This keeps the query lean without changing behaviour.
75-85: Drop theanyescape hatch and keep type safety
as any[]sacrifices compile-time guarantees and can hide future regressions.
Define an explicit result shape and rely on inference:interface LinkCount { id: string | null; domain?: string | null; key?: string | null; url?: string | null; _count: number; } counts = counts.map(({ linkId, _count }): LinkCount => { const link = links.find((l) => l.id === linkId); return { id: linkId, domain: link?.domain, key: link?.key, url: link?.url, _count, }; });You retain type safety with minimal extra code.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/app/(ee)/api/partner-profile/programs/[programId]/earnings/count/route.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2513:
To re-run the tests, please comment |
Summary by CodeRabbit
New Features
Bug Fixes
Style
Refactor
Chores