-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Partnerstack: Handle manual commissions #3231
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.
|
WalkthroughAdds upfront deduplication by invoiceId_programId, consolidates currency conversion for non-USD earnings, and introduces a manual commission path that finds partners by partnership.email to create "custom" commissions and update partner/program totals. Changes
Sequence DiagramsequenceDiagram
participant PS as PartnerStack
participant Import as ImportProcess
participant DB as Database
participant PartnerSvc as PartnerLookup
participant CommStore as CommissionStore
PS->>Import: Send commission record
alt Dedup check (invoiceId_programId)
Import->>DB: Query by invoiceId_programId
DB-->>Import: Found / Not Found
alt Found
Import-->>PS: Skip (duplicate)
end
end
Note over Import: Apply currency conversion if non-USD
alt Sale (has customer & transaction)
Import->>CommStore: Create sale commission (with customer, transaction)
CommStore->>DB: Persist commission
else Manual (no customer & no transaction)
Import->>PartnerSvc: Lookup partner by partnership.email
PartnerSvc-->>Import: Partner ID / NotFound
alt Partner found
Import->>CommStore: Create custom commission (partner, program, earnings)
CommStore->>DB: Persist commission
Import->>DB: Update partner+program totalCommissions
DB-->>Import: OK
else Partner not found
Import->>DB: Log PARTNER_NOT_FOUND
Import-->>PS: Abort / Error
end
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)
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: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/lib/partnerstack/import-commissions.ts(1 hunks)apps/web/lib/partnerstack/schemas.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: devkiran
Repo: dubinc/dub PR: 2635
File: packages/prisma/schema/payout.prisma:24-25
Timestamp: 2025-07-11T16:28:55.693Z
Learning: In the Dub codebase, multiple payout records can now share the same stripeTransferId because payouts are grouped by partner and processed as single Stripe transfers. This is why the unique constraint was removed from the stripeTransferId field in the Payout model - a single transfer can include multiple payouts for the same partner.
📚 Learning: 2025-08-16T11:14:00.667Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2754
File: apps/web/lib/partnerstack/schemas.ts:47-52
Timestamp: 2025-08-16T11:14:00.667Z
Learning: The PartnerStack API always includes the `group` field in partner responses, so the schema should use `.nullable()` rather than `.nullish()` since the field is never omitted/undefined.
Applied to files:
apps/web/lib/partnerstack/schemas.ts
📚 Learning: 2025-12-08T09:44:28.429Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3200
File: apps/web/lib/api/fraud/detect-duplicate-payout-method-fraud.ts:55-73
Timestamp: 2025-12-08T09:44:28.429Z
Learning: In apps/web/lib/api/fraud/detect-duplicate-payout-method-fraud.ts, the fraud event creation logic intentionally generates self-referential fraud events (where partnerId equals duplicatePartnerId) for partners with duplicate payout methods. This is by design to create raw events for all partners involved in a duplicate payout method scenario, regardless of whether they reference themselves.
Applied to files:
apps/web/lib/partnerstack/import-commissions.ts
⏰ 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 (4)
apps/web/lib/partnerstack/import-commissions.ts (3)
156-168: LGTM!Upfront deduplication using the
invoiceId_programIdunique constraint is a clean approach. The inline comment clarifies the repurposing of the commission key.
170-182: LGTM!Currency conversion for earnings is handled correctly with a case-insensitive check and null-safety for
fxRates.
220-220: This concern is not applicable. The PartnerStack API returnscreated_atas a number already in milliseconds, makingnew Date(commission.created_at)the correct approach. This is confirmed by the ±1 hour window queries elsewhere in the code that would be non-functional if the timestamp format were wrong.apps/web/lib/partnerstack/schemas.ts (1)
98-100: Verifypartnershipfield is always present in PartnerStack commission responses.The schema defines
partnershipas required (non-nullable), whilecustomerandtransactionuse.nullable(). If PartnerStack commission responses sometimes omit this field, parsing will fail. Cross-reference with PartnerStack API documentation or actual response logs to confirm the field is consistently included across all commission types.
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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/lib/partnerstack/import-commissions.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-08T09:44:28.429Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3200
File: apps/web/lib/api/fraud/detect-duplicate-payout-method-fraud.ts:55-73
Timestamp: 2025-12-08T09:44:28.429Z
Learning: In apps/web/lib/api/fraud/detect-duplicate-payout-method-fraud.ts, the fraud event creation logic intentionally generates self-referential fraud events (where partnerId equals duplicatePartnerId) for partners with duplicate payout methods. This is by design to create raw events for all partners involved in a duplicate payout method scenario, regardless of whether they reference themselves.
Applied to files:
apps/web/lib/partnerstack/import-commissions.ts
📚 Learning: 2025-11-12T22:23:10.414Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 3098
File: apps/web/lib/actions/partners/message-program.ts:49-58
Timestamp: 2025-11-12T22:23:10.414Z
Learning: In apps/web/lib/actions/partners/message-program.ts, when checking if a partner can continue messaging after messaging is disabled, the code intentionally requires `senderPartnerId: null` (program-initiated messages) to prevent partners from continuing to send junk messages. Only conversations started by the program should continue after messaging is disabled, as a spam prevention mechanism.
Applied to files:
apps/web/lib/partnerstack/import-commissions.ts
⏰ 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/lib/partnerstack/import-commissions.ts (3)
156-168: LGTM!Good upfront deduplication using the composite key
invoiceId_programId. This prevents duplicate commission imports efficiently at the start of processing.
184-231: LGTM - Manual commission handling with proper program scoping.The
programIdfilter is now correctly included in theprogramEnrollmentlookup (line 188), addressing the previous review concern. The custom commission creation withamount: 0and proper earnings is appropriate for manual commissions without transactions.
288-307: Verify amount comparison uses consistent currency basis.Line 298 uses
commission.transaction.amount(the original PartnerStack amount, possibly non-USD) for the deduplication lookup. If existing Dub commissions store converted USD amounts while this compares against the original currency amount, the deduplication check could fail to find matches.Please confirm whether the
amountfield in existing Dub commissions stores the original currency value or the USD-converted value. If stored as converted USD, consider using the convertedamountvariable instead:- amount: commission.transaction.amount, + amount,
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.