Skip to content

Lead and sales rewards metadata condition#4032

Open
pepeladeira wants to merge 15 commits into
mainfrom
lead-sales-rewards-metadata
Open

Lead and sales rewards metadata condition#4032
pepeladeira wants to merge 15 commits into
mainfrom
lead-sales-rewards-metadata

Conversation

@pepeladeira

@pepeladeira pepeladeira commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Release Notes

  • New Features

    • Added metadata-based reward conditions for lead and sale, including metadata field input and new operator options like contains / not_contains.
  • Bug Fixes

    • Improved reward-condition evaluation with stricter handling for empty/invalid values and better type-appropriate comparisons for metadata.
    • Updated partner commission queuing to include metadata only when present; tightened sale/lead metadata aggregation.
  • Tests

    • Expanded unit tests for metadata scenarios, operator edge cases, and schema validation.
  • Chores

    • Added QSTASH_URL to E2E workflows and the web environment example.

@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
dub Ready Ready Preview Jun 23, 2026 11:30pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

Walkthrough

This PR adds complete support for metadata-based reward conditions in the partner rewards system. It introduces a new lead entity type and metadata attribute, propagates metadata through Stripe webhook handlers and conversion tracking, implements condition evaluation with proper type coercion, and provides UI components and comprehensive test coverage for the new functionality.

Changes

Metadata-Based Reward Conditions Feature

Layer / File(s) Summary
Environment and Workflow Configuration
.github/workflows/e2e.yaml, .github/workflows/playwright.yaml, apps/web/.env.example
QSTASH_URL environment variable added to e2e workflows and example configuration for test infrastructure.
Reward Condition Schema and Type Definitions
apps/web/lib/zod/schemas/rewards.ts
Schema extended to support lead entity, metadata attribute type, and validation rules. New exports: condition attribute/ID collections, metadata operator groupings, and context schema with optional metadata for lead/sale.
Metadata Context Propagation to Commission Creation
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts, apps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.ts, apps/web/lib/api/conversions/track-lead.ts, apps/web/lib/api/conversions/track-sale.ts
Enriches partner commission creation payloads with metadata extracted from Stripe webhooks (charge metadata, merged invoice metadata) and conversion tracking (lead/sale metadata).
Metadata Condition Evaluation
apps/web/lib/partners/evaluate-reward-conditions.ts
Implements metadata field resolution, value type coercion based on operator requirements (numeric vs text), and tightened edge-case handling for empty strings, arrays, and missing values.
UI Components and Form Validation
apps/web/ui/partners/rewards/rewards-logic.tsx, apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx, apps/web/ui/partners/program-reward-modifiers-tooltip.tsx
Adds metadata field-name input, dedicated metadata operator menu, value input adaptation for numeric/text metadata, tooltip rendering of metadata field names, and base schema integration for partial form validation.
Test Coverage
apps/web/tests/rewards/reward-conditions.test.ts
Comprehensive tests for metadata condition evaluation with type coercion, schema validation of metadata attribute/entity rules, edge cases (empty values/fields), and operator behavior (contains/not\_contains/starts\_with/ends\_with/not\_in).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • dubinc/dub#3824: Both PRs modify operator evaluation logic in evaluateRewardConditions.ts, particularly not_in guard behavior and condition handling.
  • dubinc/dub#3968: Both PRs modify Stripe webhook handlers, specifically invoicePaid in invoice-paid.ts for constructing commission context payloads.

Suggested reviewers

  • steven-tey

Poem

🐰 A hop through metadata fields we go,
Lead and sale conditions now can flow,
With coerced types and operators keen,
The prettiest reward rules we've seen!
Tests and UI dance in sync so true,
Dub's partnerships just leveled up, wahoo!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main feature being added: support for metadata-based conditions in lead and sales rewards.
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.

✏️ 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 lead-sales-rewards-metadata

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
apps/web/ui/partners/program-reward-modifiers-tooltip.tsx (1)

179-220: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Render numeric 0 condition values in tooltip text.

At Line 182, condition.value && ... suppresses valid falsy operands like 0 (e.g., greater_than 0), so the tooltip can render an incomplete condition.

Suggested fix
-                  {condition.value &&
+                  {condition.value !== undefined &&
+                    condition.value !== null &&
+                    (typeof condition.value !== "string" ||
+                      condition.value.trim() !== "") &&
                     (condition.attribute === "country"
                       ? // Country names
                         Array.isArray(condition.value)
🤖 Prompt for 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.

In `@apps/web/ui/partners/program-reward-modifiers-tooltip.tsx` around lines 179 -
220, The tooltip logic is skipping falsy but valid values like 0 because it uses
"condition.value && ..."; update the check to explicitly allow 0 by replacing
that truthy check with an explicit null/undefined check (e.g., condition.value
!== undefined && condition.value !== null, or condition.value != null) before
the big rendering expression so all the downstream branches (country lookup
using COUNTRIES, subscription formatting via formatSubscriptionDuration, product
label handling, Array.isArray branches using attribute?.options,
currencyFormatter, formatDateTime, and options lookup on attribute) still run
for numeric 0 or other valid falsy values; keep the rest of the rendering logic
and symbols (CONDITION_OPERATOR_LABELS, COUNTRIES, formatSubscriptionDuration,
currencyFormatter, formatDateTime, attribute) unchanged.
🤖 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/web/.env.example`:
- Line 32: The QSTASH_URL variable is quoted and triggers dotenv-linter's
QuoteCharacter rule; update the QSTASH_URL entry (the QSTASH_URL key in the .env
example) to use an unquoted URL value (remove the surrounding double quotes) so
the line reads a bare URL and passes the linter.

---

Outside diff comments:
In `@apps/web/ui/partners/program-reward-modifiers-tooltip.tsx`:
- Around line 179-220: The tooltip logic is skipping falsy but valid values like
0 because it uses "condition.value && ..."; update the check to explicitly allow
0 by replacing that truthy check with an explicit null/undefined check (e.g.,
condition.value !== undefined && condition.value !== null, or condition.value !=
null) before the big rendering expression so all the downstream branches
(country lookup using COUNTRIES, subscription formatting via
formatSubscriptionDuration, product label handling, Array.isArray branches using
attribute?.options, currencyFormatter, formatDateTime, and options lookup on
attribute) still run for numeric 0 or other valid falsy values; keep the rest of
the rendering logic and symbols (CONDITION_OPERATOR_LABELS, COUNTRIES,
formatSubscriptionDuration, currencyFormatter, formatDateTime, attribute)
unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7834f79f-5668-4266-bea9-f64a458aa69d

📥 Commits

Reviewing files that changed from the base of the PR and between c15eae7 and 8bc444a.

📒 Files selected for processing (13)
  • .github/workflows/e2e.yaml
  • .github/workflows/playwright.yaml
  • apps/web/.env.example
  • apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts
  • apps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.ts
  • apps/web/lib/api/conversions/track-lead.ts
  • apps/web/lib/api/conversions/track-sale.ts
  • apps/web/lib/partners/evaluate-reward-conditions.ts
  • apps/web/lib/zod/schemas/rewards.ts
  • apps/web/tests/rewards/reward-conditions.test.ts
  • apps/web/ui/partners/program-reward-modifiers-tooltip.tsx
  • apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx
  • apps/web/ui/partners/rewards/rewards-logic.tsx

Comment thread apps/web/.env.example
devkiran added 2 commits June 17, 2026 12:08
Always include lead in commission context and simplify metadata spreading in track lead/sale.
Comment thread apps/web/lib/api/rewards/reward-condition-metadata.ts
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.

4 participants