Skip to content

fix(affiliate): conflict in prod & staging dashboards#7188

Open
kernelwhisperer wants to merge 10 commits intodevelopfrom
fix/affiliate-dashboards
Open

fix(affiliate): conflict in prod & staging dashboards#7188
kernelwhisperer wants to merge 10 commits intodevelopfrom
fix/affiliate-dashboards

Conversation

@kernelwhisperer
Copy link
Copy Markdown
Contributor

@kernelwhisperer kernelwhisperer commented Mar 19, 2026

Summary

Fixes:

  1. fix a loophole allowing you to create a code that was used on staging and get those rewards
  2. fix handle fee bps being null in SQL queries
  3. fix active traders being computed wrongly
  4. feat allow to deny addresses in payouts
  5. feat new dashboard to check for missing fee & missing env
  6. chore new query to analyze ETH-flow orders are not included into referral volume

Context:

  1. If you review commit by commit you will see that I tried to fix the prod & staging conflict using a start_date param, cutting of trades done before the prod lauch date. This was naive and cause the check for "traders to not have previous cowswap trades" to fail. The proper fix was to check the environment in the app data.
  2. I already updated the dashboards in prod & staging.
  3. I added fac_trades.sql for reference, and imported traders activity from feat(affiliate): trader activity table #7164 as it can be used for debugging

Summary by CodeRabbit

  • New Features

    • Added enhanced affiliate program eligibility tracking with volume-based capping and detailed reason codes.
    • Introduced new data analysis tools for debugging trades and identifying missing data issues.
    • Added support for excluding specific addresses from payouts.
  • Bug Fixes

    • Fixed fee calculation logic for trades with missing fee-volume data.
    • Improved environment-based filtering for staging and production environments.
  • Chores

    • Refined affiliate query optimization and removed outdated time constraints.
    • Enhanced trade fee breakdowns with daily USD and ETH conversions.

@kernelwhisperer kernelwhisperer requested a review from a team March 19, 2026 10:33
@kernelwhisperer kernelwhisperer self-assigned this Mar 19, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cowfi Ready Ready Preview Apr 9, 2026 8:35am
explorer-dev Ready Ready Preview Apr 9, 2026 8:35am
swap-dev Ready Ready Preview Apr 9, 2026 8:35am
widget-configurator Ready Ready Preview Apr 9, 2026 8:35am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
cosmos Ignored Ignored Apr 9, 2026 8:35am
sdk-tools Ignored Ignored Preview Apr 9, 2026 8:35am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds and updates multiple affiliate SQL queries: joins app metadata (environment) for staging/production gating, treats missing protocol fee volume as 0 for low-fee checks, removes protocol_fee_bps from outputs, adds denied-address filtering for payouts, and introduces new diagnostics and trade-fee breakdown queries including daily USD/ETH conversions and per-trade eligibility logic.

Changes

Cohort / File(s) Summary
App metadata & environment gating
apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql, apps/cowswap-frontend/src/modules/affiliate/misc/ethflow_debug.sql, apps/cowswap-frontend/src/modules/affiliate/misc/affiliate_data_issues.sql
Introduce app_data CTE (join query_5172256) to surface environment (with widget_environment fallback) and add staging vs production filtering of trades based on params.is_staging_env.
Low-fee & integrator exclusions
apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql, apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql
Change low-fee predicate to coalesce(protocol_fee_volume_bps, 0) < min_fee_bps (missing treated as 0). Ensure first-trade logic excludes integrator-sourced trades (not is_excluded_integrators_source).
Removed / added selected columns
apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
Remove selection of protocol_fee_bps from several outputs; add order_uid to debug/trades output where noted.
Payouts: denied addresses parsing & filter
apps/cowswap-frontend/src/modules/affiliate/misc/payouts.sql
Add denied_addresses template param parsing into varchar[] (empty for blank/default; trimmed & lowercased entries) and exclude rows whose receiver is in that list from final results.
Payouts: time bound removal
apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
Removed hard-coded lower time bound (evt_block_time >= date '2026-01-01') from payouts CTEs.
New diagnostics & analytics queries
apps/cowswap-frontend/src/modules/affiliate/misc/affiliate_data_issues.sql, apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql, apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql
Add affiliate_data_issues.sql (missing env/fee/referrer diagnostics), fac_trades.sql (per-trade fee/native-token breakdown with daily USD/ETH conversions and USD-fee upper bound), and traders_activity.sql (per-trade eligibility, capped cumulative USD volume, and eligibility reasons).
Aggregation explicit-null tweak
apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql
Tighten affiliate_rewards.active_traders aggregation by adding explicit else null in the count(distinct case ...) expression.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped the joins and fetched the env by name,
Turned missing fees to zero, and tidy’d the claim,
Denied some receivers, split fees by day,
First-trade rules tightened, caps kept in play,
A rabbit’s small debug — SQL neat as a game 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'fix(affiliate): conflict in prod & staging dashboards' clearly identifies the main issue being addressed—resolving environment-specific conflicts between production and staging affiliate dashboards.
Description check ✅ Passed The PR description includes a structured summary of fixes and features, context explaining the approach, and references to updated dashboards, but lacks the 'To Test' and 'Background' sections specified in the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/affiliate-dashboards

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 and usage tips.

@kernelwhisperer
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql (1)

32-35: ⚠️ Potential issue | 🟡 Minor

Exclude integrator-origin swaps from debug first_trade.

This CTE still includes integration traffic, so is_trader_eligible and eligibility_reason can disagree with the payout queries for wallets whose earliest swap came from an integrator.

🛠️ Suggested change
 first_trade as (
   select trader, min(block_time) as first_trade_time
   from trades
+  where not is_excluded_integrators_source
   group by 1
 ),
Based on learnings: In `apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql`, ensure the `first_trade` CTE excludes integrator-origin swaps by adding `WHERE NOT is_excluded_integrators_source` to prevent traders whose earliest swap came via an integrator from being incorrectly marked as ineligible at the eligibility gate.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql` around
lines 32 - 35, The first_trade CTE currently includes swaps originating from
integrators which causes mismatches with eligibility and payout logic; update
the first_trade CTE (named first_trade) to exclude integrator-origin swaps by
adding a WHERE clause filtering out rows where is_excluded_integrators_source is
true (e.g., add "WHERE NOT is_excluded_integrators_source" or equivalent) so the
computed first_trade_time only considers non-integrator-origin trades and aligns
with is_trader_eligible / eligibility_reason logic.
apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql (1)

46-68: ⚠️ Potential issue | 🟠 Major

Don't reset the new-trader gate at start_date.

Line 67 applies the cutoff before first_trade is computed, so existing wallets can look new again after the cutoff. A trader with a pre-cutoff unreferred swap and a post-cutoff referred swap will now count toward referral_volume, active_traders, and payout totals.

🛠️ Suggested change
-trades_with_referrer as (
+all_trades_with_referrer as (
   select
     dune.cowprotocol.result_fac_trades.blockchain,
     dune.cowprotocol.result_fac_trades.block_time,
     dune.cowprotocol.result_fac_trades.tx_hash,
     dune.cowprotocol.result_fac_trades.trader as trader,
     dune.cowprotocol.result_fac_trades.usd_value as usd_value,
     dune.cowprotocol.result_fac_trades.referrer_code as referrer_code,
     dune.cowprotocol.result_fac_trades.swap_source as swap_source,
     dune.cowprotocol.result_fac_trades.protocol_fee_volume_bps,
     (
       coalesce(dune.cowprotocol.result_fac_trades.protocol_fee_volume_bps, 0) < constants.min_fee_bps
     ) as is_excluded_low_fee,
     (
       lower(coalesce(dune.cowprotocol.result_fac_trades.swap_source, '')) = 'integrations'
     ) as is_excluded_integrators_source
   from dune.cowprotocol.result_fac_trades
   cross join params
   cross join constants
   where
     if(array_position(params.blockchains, '-=All=-') > 0, true, array_position(params.blockchains, dune.cowprotocol.result_fac_trades.blockchain) > 0)
-    and dune.cowprotocol.result_fac_trades.block_time >= cast(params.start_date as timestamp)
 ),
+trades_with_referrer as (
+  select *
+  from all_trades_with_referrer
+  where block_time >= cast((select start_date from params) as timestamp)
+),
 first_trade as (
   select trader, min(block_time) as first_trade_time
-  from trades_with_referrer
+  from all_trades_with_referrer
   where not is_excluded_integrators_source
   group by 1
 ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql` around lines
46 - 68, The CTE trades_with_referrer currently filters rows by
params.start_date before computing first_trade, which can reset the "new-trader"
gate; remove or postpone the block_time >= cast(params.start_date as timestamp)
filter from trades_with_referrer (i.e., stop trimming
dune.cowprotocol.result_fac_trades by params.start_date in that CTE) so that
first_trade is computed from full history, and instead apply params.start_date
only when calculating referral_volume/active_traders/payouts or when filtering
the final metric joins; refer to trades_with_referrer,
dune.cowprotocol.result_fac_trades.block_time, params.start_date and the
first_trade logic to locate where to move the cutoff.
apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql (1)

46-68: ⚠️ Potential issue | 🟠 Major

Keep first_trade on full history.

Line 67 filters trades_with_referrer before first_trade is derived, so the gate becomes “first non-integrator trade since start_date”. A wallet with an unreferred pre-cutoff trade and a referred post-cutoff trade will now pass first_trade.first_trade_time = first_ref_trade.first_ref_trade_time, which changes payout eligibility rather than only the reporting window.

🛠️ Suggested change
-trades_with_referrer as (
+all_trades_with_referrer as (
   select
     dune.cowprotocol.result_fac_trades.blockchain,
     dune.cowprotocol.result_fac_trades.block_time,
     dune.cowprotocol.result_fac_trades.tx_hash,
     dune.cowprotocol.result_fac_trades.trader as trader,
     dune.cowprotocol.result_fac_trades.usd_value as usd_value,
     dune.cowprotocol.result_fac_trades.referrer_code as referrer_code,
     dune.cowprotocol.result_fac_trades.swap_source as swap_source,
     dune.cowprotocol.result_fac_trades.protocol_fee_volume_bps,
     (
       coalesce(dune.cowprotocol.result_fac_trades.protocol_fee_volume_bps, 0) < constants.min_fee_bps
     ) as is_excluded_low_fee,
     (
       lower(coalesce(dune.cowprotocol.result_fac_trades.swap_source, '')) = 'integrations'
     ) as is_excluded_integrators_source
   from dune.cowprotocol.result_fac_trades
   cross join params
   cross join constants
   where
     if(array_position(params.blockchains, '-=All=-') > 0, true, array_position(params.blockchains, dune.cowprotocol.result_fac_trades.blockchain) > 0)
-    and dune.cowprotocol.result_fac_trades.block_time >= cast(params.start_date as timestamp)
 ),
+trades_with_referrer as (
+  select *
+  from all_trades_with_referrer
+  where block_time >= cast((select start_date from params) as timestamp)
+),
 first_trade as (
   select trader, min(block_time) as first_trade_time
-  from trades_with_referrer
+  from all_trades_with_referrer
   where not is_excluded_integrators_source
   group by 1
 ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql` around lines 46
- 68, The current CTE pipeline filters trades_with_referrer by params.start_date
and exclusion flags before deriving first_trade, causing first_trade to be
computed only over the reporting window; instead compute first_trade over the
wallet's full history. Fix by creating or using an unfiltered source CTE (e.g.,
a new trades_full or reuse dune.cowprotocol.result_fac_trades) to derive
first_trade (do not apply the start_date filter or is_excluded_* logic there),
then apply the params.start_date and exclusion filters downstream when computing
first_ref_trade and payout-eligibility; update references to
trades_with_referrer/first_trade so first_trade.first_trade_time compares
against first_ref_trade.first_ref_trade_time using the full-history first_trade.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql`:
- Around line 46-68: The CTE trades_with_referrer currently filters rows by
params.start_date before computing first_trade, which can reset the "new-trader"
gate; remove or postpone the block_time >= cast(params.start_date as timestamp)
filter from trades_with_referrer (i.e., stop trimming
dune.cowprotocol.result_fac_trades by params.start_date in that CTE) so that
first_trade is computed from full history, and instead apply params.start_date
only when calculating referral_volume/active_traders/payouts or when filtering
the final metric joins; refer to trades_with_referrer,
dune.cowprotocol.result_fac_trades.block_time, params.start_date and the
first_trade logic to locate where to move the cutoff.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql`:
- Around line 32-35: The first_trade CTE currently includes swaps originating
from integrators which causes mismatches with eligibility and payout logic;
update the first_trade CTE (named first_trade) to exclude integrator-origin
swaps by adding a WHERE clause filtering out rows where
is_excluded_integrators_source is true (e.g., add "WHERE NOT
is_excluded_integrators_source" or equivalent) so the computed first_trade_time
only considers non-integrator-origin trades and aligns with is_trader_eligible /
eligibility_reason logic.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql`:
- Around line 46-68: The current CTE pipeline filters trades_with_referrer by
params.start_date and exclusion flags before deriving first_trade, causing
first_trade to be computed only over the reporting window; instead compute
first_trade over the wallet's full history. Fix by creating or using an
unfiltered source CTE (e.g., a new trades_full or reuse
dune.cowprotocol.result_fac_trades) to derive first_trade (do not apply the
start_date filter or is_excluded_* logic there), then apply the
params.start_date and exclusion filters downstream when computing
first_ref_trade and payout-eligibility; update references to
trades_with_referrer/first_trade so first_trade.first_trade_time compares
against first_ref_trade.first_ref_trade_time using the full-history first_trade.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2065ad57-ca8a-4a62-b43f-1dd781566bad

📥 Commits

Reviewing files that changed from the base of the PR and between 83385cf and 5eb626c.

📒 Files selected for processing (4)
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql
💤 Files with no reviewable changes (1)
  • apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql`:
- Around line 6-9: The current inline start_date CASE is truncating source rows
and thus resetting affiliate state used for first_trade, paid_out and
next_payout; instead compute lifetime eligibility and paid_out from the full
history (do not apply the '{{start_date}}' cast/filter when building those
aggregates/windows—look for the expressions named start_date, paid_out,
first_trade and next_payout) and only apply the '{{start_date}}' cutoff as a
post-aggregation display filter (e.g. in a final WHERE or in the outer SELECT
that restricts displayed earning rows). Update the logic at the start_date
occurrences (and the other occurrences noted) so that calculations of lifetime
metrics use the unfiltered source, then apply the date filter purely for output.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql`:
- Around line 6-9: The current CASE for start_date is mutating lifetime state
used by computed fields (first_trade, first_ref_trade, paid_out) instead of just
filtering the reporting window; change the query so start_date is not injected
into derived-state calculations—compute first_trade, first_ref_trade and
paid_out over the full history, then apply the start_date cutoff only when
filtering rows for the reporting/earnings window (e.g., move the CASE-based
start_date usage out of aggregations/CTEs that produce
first_trade/first_ref_trade/paid_out and use it only in the final WHERE or
window that defines the reporting period), and make the same change for the
other occurrences of start_date referenced in this file.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5aaecdf8-3725-4ac2-88a4-2b770e912453

📥 Commits

Reviewing files that changed from the base of the PR and between 5eb626c and 65861cb.

📒 Files selected for processing (5)
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/payouts.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql
💤 Files with no reviewable changes (1)
  • apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql

Comment thread apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql Outdated
Comment thread apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (2)
apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql (1)

62-70: Consider extracting blockchain list to params CTE for consistency.

Other affiliate SQL files (traders.sql, affiliates.sql) store split('{{blockchain}}', ',') in the params CTE as blockchains. This file inlines it in the WHERE clause, which works but is slightly inconsistent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql` around
lines 62 - 70, The WHERE clause currently inlines split('{{blockchain}}', ',') —
extract that expression into the params CTE as blockchains (matching the pattern
used in traders.sql and affiliates.sql) and then replace the inline uses in the
WHERE with references to params.blockchains (e.g., use
array_position(params.blockchains,
dune.cowprotocol.result_fac_trades.blockchain) and the '-=All=-' check against
params.blockchains) so the CTE holds the parsed blockchain list consistently
across files.
apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql (1)

163-165: Consider documenting the fee sanity-check threshold.

The magic number 500000 in the final filter and the truncated comment ("to eliminate big price errors from be") would benefit from clarification. Is this $500,000 USD? Why this specific threshold?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql` around lines
163 - 165, The WHERE clause in the query on fees_with_conversions uses a magic
number 500000 with an incomplete comment; replace this with a documented
constant or parameter and expand the comment to explain it's a USD threshold to
filter out implausible total-fee vs trade-value mismatches (e.g., sums of
protocol_fee_usd + partner_fee_cow_cut_usd + partner_fee_partner_cut_usd
compared to usd_value), state why 500000 was chosen (source, trade-size
percentile, or heuristic) and, if possible, move the threshold into a named
CTE/variable (e.g., fee_sanity_threshold) so future readers can find and adjust
it easily.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/cowswap-frontend/src/modules/affiliate/misc/affiliate_data_issues.sql`:
- Around line 12-20: The SELECT currently lists specific columns
(base.block_time, base.environment, base.protocol_fee_volume_bps,
base.referrer_code, base.blockchain, base.order_uid, base.trader_address) and
then also includes base.*, causing duplicate columns in the result; fix this by
removing base.* from the select list (or alternatively remove the explicit
columns and keep base.*) so each column appears once—update the SELECT that
references base.* accordingly (look for the SELECT block with the explicit
base.* and the listed base.<column> names).

In `@apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql`:
- Around line 67-69: The BPS expressions (protocol_fee_bps, protocol_fee_pi_bps,
protocol_fee_volume_bps) can divide by zero because the denominator uses
if(rod.protocol_fee_token = t.buy_token_address,
t.atoms_bought+rod.protocol_fee, t.atoms_sold+rod.protocol_fee); fix by wrapping
that denominator with NULLIF(...) to convert 0 to NULL and avoid the division
error, and ensure you coalesce null operands to 0 (e.g., use
coalesce(t.atoms_bought,0), coalesce(rod.protocol_fee,0),
coalesce(t.atoms_sold,0), coalesce(rod.protocol_volume_fee,0)) so the calculated
numerator/denominator remain numeric; update each expression (protocol_fee_bps,
protocol_fee_pi_bps, protocol_fee_volume_bps) to use the NULLIF-wrapped
denominator.
- Around line 142-151: The ETH conversion expressions (e.g., the conversions of
protocol_fee_native, volume_fee_native, limit_pi_fee_native,
market_pi_fee_native, ui_fee_native, partner_fee_cow_cut_native,
partner_fee_partner_cut_native) currently divide by p_eth.price which can be
NULL or zero; update each occurrence of "p_native.price / p_eth.price" (and
similar native/ETH divisions) to use a safe denominator such as "p_native.price
/ nullif(p_eth.price, 0)" (or nullif on p_eth.price where used) so the division
won't error on zero and will yield NULL when ETH price is missing; apply this
pattern to all conversion expressions in the block (including
partner_fee_*_native conversions).

---

Nitpick comments:
In `@apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql`:
- Around line 163-165: The WHERE clause in the query on fees_with_conversions
uses a magic number 500000 with an incomplete comment; replace this with a
documented constant or parameter and expand the comment to explain it's a USD
threshold to filter out implausible total-fee vs trade-value mismatches (e.g.,
sums of protocol_fee_usd + partner_fee_cow_cut_usd + partner_fee_partner_cut_usd
compared to usd_value), state why 500000 was chosen (source, trade-size
percentile, or heuristic) and, if possible, move the threshold into a named
CTE/variable (e.g., fee_sanity_threshold) so future readers can find and adjust
it easily.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql`:
- Around line 62-70: The WHERE clause currently inlines split('{{blockchain}}',
',') — extract that expression into the params CTE as blockchains (matching the
pattern used in traders.sql and affiliates.sql) and then replace the inline uses
in the WHERE with references to params.blockchains (e.g., use
array_position(params.blockchains,
dune.cowprotocol.result_fac_trades.blockchain) and the '-=All=-' check against
params.blockchains) so the CTE holds the parsed blockchain list consistently
across files.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4278cc4b-c9ba-44ef-9b40-270ad360e6f0

📥 Commits

Reviewing files that changed from the base of the PR and between 65861cb and f0bbad7.

📒 Files selected for processing (6)
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliate_data_issues.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql

Comment thread apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql
Comment thread apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql
@kernelwhisperer kernelwhisperer requested a review from a team April 9, 2026 06:54
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (1)
apps/cowswap-frontend/src/modules/affiliate/misc/ethflow_debug.sql (1)

1-50: Consider adding optional environment filtering for consistency.

Unlike affiliates.sql and traders_activity.sql, this debug query has no environment filtering. If this is intentional (to see all environments for debugging the staging/prod conflict), consider adding a comment explaining this design choice. Otherwise, adding the standard params CTE with is_staging_env would maintain consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/cowswap-frontend/src/modules/affiliate/misc/ethflow_debug.sql` around
lines 1 - 50, This query lacks the standard environment filtering; add the usual
params CTE (including is_staging_env and environment param) and either filter
the app_data/trades CTEs by coalesced environment (e.g., join or where using
params.environment / params.is_staging_env) to match the pattern in
affiliates.sql and traders_activity.sql, or if the omission is intentional, add
a clear comment above the app_data/trades CTEs stating that the query
intentionally spans all environments for debugging staging/prod conflicts;
reference the app_data, trades and native_sell_symbols CTEs when applying the
filter or placing the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql`:
- Around line 175-183: The CASE for eligibility_reason is missing a branch for
trades excluded by the time cap applied earlier in the eligible_trades CTE;
update the eligibility_reason CASE (used when computing eligibility_reason) to
include a WHEN that detects trades where block_time > bound_time + time_cap_days
(the same condition used in eligible_trades) and return 'time_cap_exceeded' so
those rows are labeled correctly instead of falling through to 'eligible';
reference the eligible_trades CTE, the bound_time and time_cap_days fields, and
the eligibility_reason CASE/column when making the change.

---

Nitpick comments:
In `@apps/cowswap-frontend/src/modules/affiliate/misc/ethflow_debug.sql`:
- Around line 1-50: This query lacks the standard environment filtering; add the
usual params CTE (including is_staging_env and environment param) and either
filter the app_data/trades CTEs by coalesced environment (e.g., join or where
using params.environment / params.is_staging_env) to match the pattern in
affiliates.sql and traders_activity.sql, or if the omission is intentional, add
a clear comment above the app_data/trades CTEs stating that the query
intentionally spans all environments for debugging staging/prod conflicts;
reference the app_data, trades and native_sell_symbols CTEs when applying the
filter or placing the comment.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 33ab54d7-8d7f-44cd-8b74-2c0f3f4d6b7c

📥 Commits

Reviewing files that changed from the base of the PR and between f0bbad7 and fe4fccd.

📒 Files selected for processing (9)
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliate_data_issues.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliates.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/ethflow_debug.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/payouts.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_activity.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql
💤 Files with no reviewable changes (1)
  • apps/cowswap-frontend/src/modules/affiliate/misc/trader_debug.sql
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/traders_debug.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/affiliate_data_issues.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/payouts.sql
  • apps/cowswap-frontend/src/modules/affiliate/misc/fac_trades.sql

@elena-zh
Copy link
Copy Markdown
Contributor

elena-zh commented Apr 9, 2026

Hey @kernelwhisperer , could you please provide a bit more clear test steps? What in particular I should test?
Thank you!

@kernelwhisperer
Copy link
Copy Markdown
Contributor Author

kernelwhisperer commented Apr 9, 2026

Hey @kernelwhisperer , could you please provide a bit more clear test steps? What in particular I should test? Thank you!

Mainly this one ETH-flow orders are not included into referral volume

(I tested it myself with 2 trades on gnosis, looks like Nitish fixed it)

Copy link
Copy Markdown
Contributor

@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Collaborator

@shoom3301 shoom3301 left a comment

Choose a reason for hiding this comment

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

I don't really have expertise here and it will take too much to obtain it. So I just blindly approve

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.

3 participants