dub icon indicating copy to clipboard operation
dub copied to clipboard

Geo-specific CPC rewards

Open devkiran opened this issue 2 months ago • 2 comments

devkiran avatar Dec 17 '25 16:12 devkiran

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

Project Deployment Review Updated (UTC)
dub Ready Ready Preview Jan 2, 2026 6:02am

vercel[bot] avatar Dec 17 '25 16:12 vercel[bot]

📝 Walkthrough

Walkthrough

Implements per-country click aggregation: fetches TinyBird analytics grouped by link and country, resolves country-specific click rewards, computes per-link earnings/commissions, updates cron batching, and adds supporting TinyBird pipe, reward resolver, API changes, UI tweaks, and tests.

Changes

Cohort / File(s) Summary
Click aggregation & earnings
apps/web/app/(ee)/api/cron/aggregate-clicks/route.ts
Replaces per-link analytics calls with per-link-per-country aggregation, builds a link→country earnings map, computes earnings using country-specific rewards, creates commissions, logs per-country earnings, and enqueues next batch via qstash when needed.
Reward amount resolution
apps/web/app/(ee)/api/cron/aggregate-clicks/resolve-click-reward-amount.ts
New utility resolveClickRewardAmount(reward, country) that parses modifiers, evaluates conditions with country context, applies conditional overrides, and returns final amount in cents.
TinyBird analytics pipe & client
packages/tinybird/pipes/v3_group_by_link_country.pipe, apps/web/lib/tinybird/get-top-links-by-countries.ts
Adds new TinyBird pipe (group by link+country) and TB client wrapper getTopLinksByCountries with input/output schemas and UTC date formatting.
Reward validation & UI logic
apps/web/lib/api/rewards/validate-reward.ts, apps/web/ui/partners/rewards/rewards-logic.tsx
Allows modifiers for "click" rewards (removes previous prohibition) and adds "customer" as a valid related entity for click event.
Reward API endpoints
apps/web/app/(ee)/api/rewards/[rewardId]/route.ts, apps/web/app/(ee)/api/rewards/route.ts
Adds GET /api/rewards/[rewardId] workspace-scoped handler; updates route comment for /api/rewards.
Frontend data fetching
apps/web/lib/swr/use-rewards.ts
SWR key changed to query /api/rewards?workspaceId=... instead of /api/programs/{programId}/rewards.
Tests
apps/web/tests/rewards/click-reward.test.ts
New end-to-end tests verifying resolveClickRewardAmount returns country-specific amounts (modifier countries vs fallback) across sample countries.
UI behavior
apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx
Close button now clears tooltipDescription; RewardsLogic always rendered inside RewardSheetCard (removed conditional render).

Sequence Diagram(s)

sequenceDiagram
    participant Cron as Aggregate Clicks Cron
    participant TB as TinyBird
    participant DB as Database
    participant Resolver as Reward Resolver
    participant Sync as Commission Sync

    Cron->>TB: getTopLinksByCountries({linkIds, start, end})
    TB-->>Cron: rows: {link_id, country, clicks}
    Cron->>Cron: group rows by link_id -> country buckets
    Cron->>DB: fetch rewards for link_ids
    DB-->>Cron: reward objects

    loop per link_id, country
        Cron->>Resolver: resolveClickRewardAmount(reward, country)
        Resolver->>Resolver: parse modifiers & evaluate conditions (country context)
        Resolver-->>Cron: reward cents
        Cron->>Cron: earnings = clicks * reward cents
    end

    Cron->>DB: create commissions (per-link totals + reward details)
    DB-->>Cron: commissions created
    Cron->>Sync: sync total commissions
    Sync-->>Cron: sync complete

    alt more links remain
        Cron->>Cron: enqueue next batch via qstash
    end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • dubinc/dub#2730: Modifies the same aggregate-clicks cron route and earlier per-link aggregation/commission logic that this change extends to per-country aggregation.
  • dubinc/dub#2725: Introduced batch analytics and commission creation patterns in the aggregate-clicks cron that this PR builds upon.
  • dubinc/dub#2987: Related to reward condition evaluation/context (country) changes used by resolveClickRewardAmount and modifier handling.

Poem

🐰 I count clicks across each land and sea,
Per-country carrots fall just right for me,
Modifiers hop in, rewards now align,
Cron tallies, queues, and commissions shine,
A joyful hop — rewards by country, whee! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Geo-specific CPC rewards' directly and specifically describes the main change: introducing country-based CPC (cost-per-click) reward amounts across the codebase.
✨ Finishing touches
  • [ ] 📝 Generate docstrings

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.

coderabbitai[bot] avatar Dec 17 '25 16:12 coderabbitai[bot]

@coderabbitai full review

devkiran avatar Dec 30 '25 16:12 devkiran

✅ Actions performed

Full review triggered.

coderabbitai[bot] avatar Dec 30 '25 16:12 coderabbitai[bot]