feat(affiliate): use verified actuals for swap fee amounts and expose partnerBps#12311
Conversation
Reshape the affiliate swaps endpoint around verified on-chain values: fee USD is derived from the actual paid amount when recorded, falling back to volume × bps (buy-side when feeAssetId matches buyAsset, else sell-side). Sell/buy amounts now prefer verified/actual over expected. Drops the verbose `affiliateVerificationDetails`, `affiliateFeeAsset`, and `affiliateFeeAmountCryptoPrecision` from the response — the dashboard only needs the resolved USD value and bps. Bumps dashboard fee precision to 4 decimals so small actual fees aren't rounded to zero. Calculation extracted to `calculateAffiliateFeeAmountUsd` with unit tests covering each priority tier. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Compute partnerBps server-side as max(0, affiliateBps - shapeshiftBps) so consumers don't have to derive it. affiliateBps defaults to 0 when no source value exists, making both bps fields non-nullable. The inferred fee USD calc now scales by partnerBps so the value reflects the partner's share. Tightens swaps table column layout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ 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. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAffiliate swap data handling is refactored with field restructuring (expectedBuyAmountCryptoPrecision/actualBuyAmountCryptoPrecision → buyAmountCryptoPrecision/buyAmountUsd, affiliateBps → partnerBps), a new partner fee USD calculation function, stricter schema validation (removed passthrough), and timezone handling shifted from UTC to local time. Changes
Poem
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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. Review rate limit: 0/1 reviews remaining, refill in 52 minutes and 3 seconds.Comment |
…liateBps Renames the helper to calculatePartnerFeeAmountUsd and scales the on-chain captured fee by partnerBps / affiliateBps so path 1 (verified actuals) and path 2 (volume × bps) both report the partner's share rather than the total captured. Drops affiliateBps from the response — it's redundant once shapeshiftBps and partnerBps are exposed. Makes partnerBps nullable end-to-end so "no fee data" is distinguishable from "0 bps", and the dashboard renders nullable bps and fee values as an em dash. Replaces .toString() with .toFixed() on USD amounts to avoid scientific-notation strings, and broadens test coverage to cover priority ordering, partner-share scaling, and direct sell/buy-side selection. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The dropdown was showing UTC months, so users in negative-UTC zones saw next month appear (and the current month disappear) hours before their local calendar rolled over. Compute month boundaries from local time and rely on .toISOString() for the UTC conversion when querying — the API still receives absolute timestamps, but they line up with the user's calendar month. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/affiliate-dashboard/src/lib/periods.ts`:
- Around line 34-37: Update the AffiliateConfigResponseSchema and the hook
schema to enforce ISO datetime strings: change
AffiliateConfigResponseSchema.createdAt to use z.string().datetime() (and add
the openapi example '2024-01-01T00:00:00.000Z' as suggested) so the API boundary
validates datetime format before it reaches generatePeriods, and update the
schema used in useAffiliateConfig (createdAt in that hook) to
z.string().datetime() as well so both the API response type and the client-side
hook match the upstream SwapServiceAffiliateSwapSchema and avoid Date parsing
timezone misalignment in generatePeriods.
🪄 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: 8d8a246f-ec7a-4701-a26d-796872935158
📒 Files selected for processing (8)
packages/affiliate-dashboard/src/components/swaps/SwapsTable.tsxpackages/affiliate-dashboard/src/hooks/useAffiliateSwaps.tspackages/affiliate-dashboard/src/lib/format.tspackages/affiliate-dashboard/src/lib/periods.tspackages/public-api/src/routes/affiliate/calculatePartnerFeeAmountUsd.test.tspackages/public-api/src/routes/affiliate/calculatePartnerFeeAmountUsd.tspackages/public-api/src/routes/affiliate/getAffiliateSwaps.tspackages/public-api/src/routes/affiliate/types.ts
A bare date string like "2024-01-01" parses as UTC midnight, which when truncated via local-time getMonth() in negative-UTC offsets shifts the oldestMonth back a month and pads the dropdown with an empty trailing entry. Validating at the API boundary (and matching the dashboard schema) ensures generatePeriods only sees full ISO timestamps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Description
Reworks the affiliate swaps endpoint to derive USD fee amounts using a tiered priority — actual on-chain amounts first, then inferred from volume × bps — and exposes
partnerBpsdirectly in the public API so clients no longer compute it.calculateAffiliateFeeAmountUsdhelper with three-tier priority: (1) actual fee amount × affiliate asset USD, (2) volume × bps inferred from buy/sell side based onaffiliateFeeAssetId, (3) null. Prefers verified amounts fromaffiliateVerificationDetailswhen present.getAffiliateSwapsnow derivesaffiliateBpsandpartnerBpsserver-side, returnsbuyAmountCryptoPrecision/buyAmountUsd, and renamesaffiliateFeeUsd→affiliateFeeAmountUsd.SwapServiceAffiliateSwapSchemaextended withsellAssetUsd,actualAffiliateFeeAmountCryptoBaseUnit,affiliateAssetUsd,affiliateFeeAssetId, andaffiliateVerificationDetails.AffiliateSwapItemSchema→AffiliateSwapSchemaand exportedSwapServiceAffiliateSwaptype.affiliate-dashboardupdated to consume new fields directly; removed localpartnerBpscomputation. USD format now allows up to 4 fractional digits to surface sub-cent fee amounts.calculateAffiliateFeeAmountUsdacross all priority tiers and edge cases.Issue (if applicable)
closes #
Risk
Low — read-only API change scoped to the affiliate swaps endpoint and its dashboard consumer. No on-chain transactions affected. The response shape changes (renamed/added fields), but the only consumer in this repo is the affiliate-dashboard, which is updated in lockstep.
None.
Testing
Engineering
pnpm --filter @shapeshiftoss/public-api test— newcalculateAffiliateFeeAmountUsd.test.tscovers all three priority paths plus fallbacks./v1/affiliate/swapsagainst a swap-service that returns the new upstream fields and confirmaffiliateFeeAmountUsd,partnerBps,buyAmountCryptoPrecision, andbuyAmountUsdare populated.Operations
Screenshots (if applicable)
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes