Skip to content

feat(affiliate): partner revenue breakout — registry listing + fee-split swap rows#50

Merged
kaladinlight merged 7 commits into
developfrom
feat/partner-revenue-breakout
Jul 2, 2026
Merged

feat(affiliate): partner revenue breakout — registry listing + fee-split swap rows#50
kaladinlight merged 7 commits into
developfrom
feat/partner-revenue-breakout

Conversation

@kaladinlight

@kaladinlight kaladinlight commented Jul 2, 2026

Copy link
Copy Markdown
Member

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/swapspartnerCode now optional. When omitted, returns swaps across all partners (partnerCode is not null); when supplied, unchanged single-partner behavior. The DTO field is now @IsOptional().
  • Per-row fee split. Each returned swap is enriched with affiliateBps, feeUsd, volumeUsd, and partnerFeeUsd — derived from the injected calculateFeeForSwap / getPartnerFeeRate fee math (partnerFeeUsd = feeUsd × partnerFeeRate), so callers get the revenue breakout without re-deriving it.

Testing

  • yarn build — all 6 packages build
  • swap-service — 60/60 tests pass, including the new affiliate-swaps.test.ts (optional partnerCode + fee-split enrichment) and updated list-affiliates.test.ts

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new affiliate list endpoint.
    • Added a referral-fees lookup route with optional date filtering.
  • Bug Fixes

    • Improved affiliate swap results to show derived fee and volume amounts when available.
    • Kept stored affiliate split values intact while handling unpriceable swaps gracefully.
    • Made affiliate swap filtering work when no partner code is provided.

kaladinlight and others added 4 commits July 2, 2026 12:03
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>
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a new endpoint and service method to list all affiliates, enriches getAffiliateSwaps to compute per-swap feeUsd, volumeUsd, and partnerFeeUsd while making partnerCode optional, and replaces the affiliate-fees route/method with a new referral-fees equivalent.

Changes

Affiliate service and swaps fee changes

Layer / File(s) Summary
Get all affiliates endpoint
apps/swap-service/src/affiliate/affiliate.controller.ts, apps/swap-service/src/affiliate/affiliate.service.ts
New unparameterized GET route returns getAffiliates(), implemented via prisma.affiliate.findMany().
getAffiliateSwaps fee-split enrichment and optional partnerCode
apps/swap-service/src/affiliate/affiliate.service.ts, apps/swap-service/src/affiliate/types.ts, apps/swap-service/src/affiliate/__tests__/affiliate.service.test.ts
partnerCode becomes optional in the DTO and service signature with adjusted Prisma filtering; PaginatedSwaps import removed; swap results now include computed feeUsd, volumeUsd, partnerFeeUsd derived via calculateFeeForSwap/getPartnerFeeRate, preserving stored affiliateBps; new tests cover verified and unpriceable swap scenarios.
Replace affiliate-fees route/method with referral-fees
apps/swap-service/src/swaps/swaps.controller.ts, apps/swap-service/src/swaps/swaps.service.ts
Removes affiliate-fees/:partnerCode route and calculateAffiliateFees service method; adds referral-fees/:referralCode route calling calculateReferralFees; drops now-unused getPartnerFeeRate import.

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
Loading

Possibly related PRs

Poem

A rabbit hops through fields of code,
Affiliate fees now find their road,
Referral paths replace the old,
While swaps reveal their fees in gold. 🐇💰
Hop, compute, and ship anew!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: an affiliate registry listing and fee-split swap row enrichment.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/partner-revenue-breakout

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.

kaladinlight and others added 3 commits July 2, 2026 15:47
- 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>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7ce8c3f and 0cfddb9.

📒 Files selected for processing (6)
  • apps/swap-service/src/affiliate/__tests__/affiliate.service.test.ts
  • apps/swap-service/src/affiliate/affiliate.controller.ts
  • apps/swap-service/src/affiliate/affiliate.service.ts
  • apps/swap-service/src/affiliate/types.ts
  • apps/swap-service/src/swaps/swaps.controller.ts
  • apps/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

Comment thread apps/swap-service/src/affiliate/affiliate.service.ts
Comment thread apps/swap-service/src/affiliate/affiliate.service.ts
@kaladinlight
kaladinlight force-pushed the feat/partner-revenue-breakout branch from 25a03b0 to 0cfddb9 Compare July 2, 2026 23:31
@kaladinlight
kaladinlight enabled auto-merge (squash) July 2, 2026 23:33
@kaladinlight
kaladinlight merged commit f252430 into develop Jul 2, 2026
3 checks passed
@kaladinlight
kaladinlight deleted the feat/partner-revenue-breakout branch July 2, 2026 23:33
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.

1 participant