feat(affiliate): partner revenue breakout — registry listing + fee-split swap rows#50
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ows with fee split Omitting partnerCode now returns all partner swaps (partnerCode not null) so revenue-api can fetch and settle across partners in one call. Each returned row is enriched with affiliateBps/feeUsd/partnerFeeUsd/volumeUsd computed via the existing calculateFeeForSwap/getPartnerFeeRate helpers. Single-partner behavior is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds a new endpoint and service method to list all affiliates, enriches ChangesAffiliate service and swaps fee changes
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant AffiliateController
participant AffiliateService
participant Prisma
Client->>AffiliateController: GET /v1/affiliate/swaps?partnerCode
AffiliateController->>AffiliateService: getAffiliateSwaps(partnerCode, options)
AffiliateService->>Prisma: findMany(where: partnerCode or not null)
Prisma-->>AffiliateService: items
AffiliateService->>AffiliateService: calculateFeeForSwap + getPartnerFeeRate per item
AffiliateService-->>AffiliateController: swaps with feeUsd/volumeUsd/partnerFeeUsd
AffiliateController-->>Client: paginated swaps response
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
- getAffiliates: rename from listAffiliates and return full Affiliate[] with an honest return type (endpoint is behind the shared service api key; callers may want wallet/receive addresses) - fold the one useful affiliate-swaps test (fee-split enrichment: happy path + unpriceable/no-verified-fee edge) into affiliate.service.test.ts as its own section; drop the standalone file and the redundant/tautological cases Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ll-precision strings - getAffiliateSwaps no longer overwrites the stored affiliateBps with verifiedBps - feeUsd/volumeUsd/partnerFeeUsd are full-precision USD strings (no server-side rounding — clients format as needed), null when the swap isn't priceable - test asserts the stored affiliateBps passes through untouched Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GET /swaps/affiliate-fees/:partnerCode and calculateAffiliateFees had no consumers (superseded by AffiliateService.getAffiliateStats and the affiliate-payouts script). Drops the now-unused getPartnerFeeRate import; aggregateFees/Fees remain in use by the live calculateReferralFees. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/swap-service/src/affiliate/affiliate.service.ts`:
- Around line 16-19: The public affiliate list in getAffiliates currently
returns prisma.affiliate.findMany() directly, which exposes sensitive Affiliate
fields. Update the AffiliateService.getAffiliates method to select only the safe
public fields partnerCode, bps, and isActive before returning results, and keep
the response shape limited to those fields.
- Around line 131-141: The USD string formatting in affiliate.service.ts is
still using native number multiplication in the swaps mapping, which can
introduce floating-point rounding artifacts. Update the logic in the swaps
construction to keep the final fee calculation in BigNumber form instead of
multiplying fee.feeUsd as a JS number, and stringify only after the precise
value is computed; use the existing symbols calculateFeeForSwap,
getPartnerFeeRate, and the feeUsd/partnerFeeUsd fields to locate the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8ee39d1b-013e-4a5a-92d0-d815a536d903
📒 Files selected for processing (6)
apps/swap-service/src/affiliate/__tests__/affiliate.service.test.tsapps/swap-service/src/affiliate/affiliate.controller.tsapps/swap-service/src/affiliate/affiliate.service.tsapps/swap-service/src/affiliate/types.tsapps/swap-service/src/swaps/swaps.controller.tsapps/swap-service/src/swaps/swaps.service.ts
💤 Files with no reviewable changes (2)
- apps/swap-service/src/swaps/swaps.controller.ts
- apps/swap-service/src/swaps/swaps.service.ts
25a03b0 to
0cfddb9
Compare
Description
Adds partner-revenue reporting surface to the affiliate API.
GET /v1/affiliate— new registry listing endpoint returning every affiliate as{ partnerCode, bps, isActive }.GET /v1/affiliate/swaps—partnerCodenow optional. When omitted, returns swaps across all partners (partnerCodeis not null); when supplied, unchanged single-partner behavior. The DTO field is now@IsOptional().affiliateBps,feeUsd,volumeUsd, andpartnerFeeUsd— derived from the injectedcalculateFeeForSwap/getPartnerFeeRatefee math (partnerFeeUsd = feeUsd × partnerFeeRate), so callers get the revenue breakout without re-deriving it.Testing
yarn build— all 6 packages buildaffiliate-swaps.test.ts(optional partnerCode + fee-split enrichment) and updatedlist-affiliates.test.ts🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes