-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add more calculated stats #3088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughUpdates partner metric pipeline and UI: new enrollment analytics fields and Prisma indexes, cron stream dedupes program:partner events then fetches/merges link & commission stats to compute derived metrics and batch-update ProgramEnrollment; ranking and table schemas/columns updated to surface the new metrics and header tooltips added. Changes
Sequence Diagram(s)sequenceDiagram
participant Redis as Redis stream
participant Cron as Cron handler
participant Fetch as Link & Commission fetchers
participant Agg as Merger / Metrics calculator
participant DB as Prisma (ProgramEnrollment)
participant UI as Dashboard
Note over Redis,Cron: batch of partner events arrives
Redis->>Cron: deliver events
Cron->>Cron: dedupe programId:partnerId keys
Cron->>Fetch: parallel fetch(linkStats) and fetch(commissionStats)
Fetch-->>Cron: linkStats, commissionStats
Cron->>Agg: merge stats per programId:partnerId
Agg->>Agg: compute derived metrics (EPC, AvgLTV, rates, ROAS, consistency)
Agg->>DB: update ProgramEnrollment (sub-batches, conditional fields)
DB-->>Agg: update acknowledgements
UI->>DB: query enrollments (sortable by new metrics)
DB-->>UI: return enriched rows
UI->>UI: render columns and header tooltips
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts(7 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx(3 hunks)apps/web/lib/api/network/calculate-partner-ranking.ts(5 hunks)apps/web/lib/zod/schemas/partners.ts(2 hunks)packages/prisma/schema/program.prisma(5 hunks)packages/ui/src/table/table.tsx(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-09-24T15:47:40.293Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/about-you-form.tsx:152-157
Timestamp: 2025-09-24T15:47:40.293Z
Learning: The Button component from dub/ui automatically adds type="button" when an onClick prop is passed, preventing accidental form submissions without requiring explicit type specification. The implementation uses: type={onClick ? "button" : type}
Applied to files:
packages/ui/src/table/table.tsx
📚 Learning: 2025-09-17T17:44:03.965Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2857
File: apps/web/lib/actions/partners/update-program.ts:96-0
Timestamp: 2025-09-17T17:44:03.965Z
Learning: In apps/web/lib/actions/partners/update-program.ts, the team prefers to keep the messagingEnabledAt update logic simple by allowing client-provided timestamps rather than implementing server-controlled timestamp logic to avoid added complexity.
Applied to files:
apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.tsapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
🧬 Code graph analysis (2)
packages/ui/src/table/table.tsx (1)
packages/ui/src/tooltip.tsx (1)
Tooltip(64-115)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (2)
apps/web/lib/types.ts (1)
EnrolledPartnerProps(450-450)packages/utils/src/functions/currency-formatter.ts (1)
currencyFormatter(7-22)
🔇 Additional comments (6)
packages/ui/src/table/table.tsx (2)
474-488: LGTM! Clean tooltip integration.The IIFE pattern cleanly extracts the header content and tooltip metadata, then delegates to the HeaderWithTooltip wrapper. This preserves sortable header behavior while adding optional tooltip support.
700-719: LGTM! Simple and effective tooltip wrapper.The component provides a clear visual affordance with the dotted underline and cursor-help styling, making it obvious to users that additional information is available on hover.
apps/web/lib/api/network/calculate-partner-ranking.ts (1)
61-61: LGTM! Consistent migration to clickToConversionRate.All references to the legacy
conversionRatefield have been properly updated to useclickToConversionRatethroughout the ranking logic, aggregations, and display mappings. The changes are consistent with the schema updates across the PR.Also applies to: 146-146, 170-172, 227-227
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (1)
300-357: LGTM! Well-structured metric columns with helpful tooltips.The new metric columns (EPC, Avg LTV, and rate metrics) are properly implemented with:
- Appropriate formatting (currency for EPC/LTV, percentages for rates)
- Null/undefined handling with fallback to "-"
- Clear tooltips explaining each calculation
- Proper typing with EnrolledPartnerProps
- Inclusion in sortableColumns array
The tooltip descriptions effectively communicate how each metric is derived.
Also applies to: 421-427
packages/prisma/schema/program.prisma (2)
150-156: LGTM! Indexes will optimize sorting queries.The new composite indexes on
[programId, status, <metric>]for all the new calculated metrics will efficiently support the sorting functionality added to the partners table. This follows the existing pattern for other sortable metrics.
205-212: LGTM! Clean category model with proper constraints.The new
ProgramCategorymodel is well-structured with:
- Proper foreign key relationship with cascade delete
- Unique constraint on
[programId, category]to prevent duplicates- Simple, normalized design
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
🧬 Code graph analysis (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (2)
apps/web/lib/types.ts (1)
EnrolledPartnerProps(450-450)packages/utils/src/functions/currency-formatter.ts (1)
currencyFormatter(7-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
Show resolved
Hide resolved
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/lib/api/network/calculate-partner-ranking.ts(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
apps/web/lib/api/network/calculate-partner-ranking.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (5)
apps/web/lib/api/network/calculate-partner-ranking.ts (5)
42-42: LGTM! Documentation accurately reflects the metric change.The documentation correctly describes that
clickToConversionRateis the average click-to-conversion rate across all programs.
61-61: LGTM! Filter logic correctly updated.The condition properly filters out partners with suspiciously high (≥100%) click-to-conversion rates.
138-138: LGTM! Aggregation correctly computes average click-to-conversion rate.The aggregation properly computes the average across all program enrollments with appropriate NULL handling.
162-164: LGTM! Similarity scoring correctly updated.The conversion rate component of the similarity score properly uses
clickToConversionRatewith appropriate logarithmic scaling for rates between 0-10%.
61-61: Schema verification passed — no action required.The
clickToConversionRatefield exists in the ProgramEnrollment model and is properly indexed. The code correctly usesCOALESCEto handle the nullable field type.
There was a problem hiding this 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
♻️ Duplicate comments (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (1)
332-391: Zero values display as "-" instead of formatted zeros.All new ratio columns use truthiness checks, so legitimate zero values (e.g., 0% conversion rate or 0.00x ROAS) render as "-" instead of "0.00%"/"0.00x". Partners who generate traffic but no conversions will see blanks rather than accurate zero stats, which is misleading for performance analysis.
Apply this diff to treat only
null/undefinedas "no data":accessorFn: (d: EnrolledPartnerProps) => - d.averageLifetimeValue + d.averageLifetimeValue != null ? currencyFormatter(d.averageLifetimeValue) : "-",accessorFn: (d: EnrolledPartnerProps) => - d.clickToLeadRate - ? `${parseFloat((d.clickToLeadRate * 100).toFixed(2))}%` + d.clickToLeadRate != null + ? `${(d.clickToLeadRate * 100).toFixed(2)}%` : "-",accessorFn: (d: EnrolledPartnerProps) => - d.clickToConversionRate - ? `${parseFloat((d.clickToConversionRate * 100).toFixed(2))}%` + d.clickToConversionRate != null + ? `${(d.clickToConversionRate * 100).toFixed(2)}%` : "-",accessorFn: (d: EnrolledPartnerProps) => - d.leadToConversionRate - ? `${parseFloat((d.leadToConversionRate * 100).toFixed(2))}%` + d.leadToConversionRate != null + ? `${(d.leadToConversionRate * 100).toFixed(2)}%` : "-",accessorFn: (d: EnrolledPartnerProps) => - d.returnOnAdSpend - ? `${parseFloat((d.returnOnAdSpend * 100).toFixed(2))}%` + d.returnOnAdSpend != null + ? `${d.returnOnAdSpend.toFixed(2)}x` : "-",Note: The diff above also removes the unnecessary
parseFloatwrapper aroundtoFixedresults and fixes the ROAS format (see next comment).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts(5 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
📚 Learning: 2025-07-30T15:29:54.131Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/rewards-logic.tsx:268-275
Timestamp: 2025-07-30T15:29:54.131Z
Learning: In apps/web/ui/partners/rewards/rewards-logic.tsx, when setting the entity field in a reward condition, dependent fields (attribute, operator, value) should be reset rather than preserved because different entities (customer vs sale) have different available attributes. Maintaining existing fields when the entity changes would create invalid state combinations and confusing UX.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
📚 Learning: 2025-09-17T17:44:03.965Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2857
File: apps/web/lib/actions/partners/update-program.ts:96-0
Timestamp: 2025-09-17T17:44:03.965Z
Learning: In apps/web/lib/actions/partners/update-program.ts, the team prefers to keep the messagingEnabledAt update logic simple by allowing client-provided timestamps rather than implementing server-controlled timestamp logic to avoid added complexity.
Applied to files:
apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts
🧬 Code graph analysis (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (2)
apps/web/lib/types.ts (1)
EnrolledPartnerProps(450-450)packages/utils/src/functions/currency-formatter.ts (1)
currencyFormatter(7-22)
apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts (1)
packages/prisma/index.ts (1)
prisma(3-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (4)
260-310: LGTM! Helpful tooltips for existing metrics.The headerTooltip additions provide clear explanations for each metric, improving the user experience without altering functionality.
313-321: LGTM! Net Revenue column is well-defined.The column definition includes a clear tooltip explaining the calculation formula, and the accessor function correctly formats the currency value.
322-331: LGTM! EPC column definition is clear.The Earnings Per Click column includes an appropriate tooltip with the calculation formula and correctly formats the value as currency.
436-450: LGTM! New metrics properly added to sortable columns.All new calculated metrics are correctly included in the sortableColumns array, enabling users to sort by these performance indicators.
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/lib/zod/schemas/partners.ts (1)
27-65: Consider adding new calculated metrics to export columns.The
netRevenuefield is included in the export columns (line 58), but the other new calculated metrics (earningsPerClick, averageLifetimeValue, clickToLeadRate, clickToConversionRate, leadToConversionRate, returnOnAdSpend) are not.If these metrics are valuable for partner performance analysis, consider adding them to the export columns array to allow users to export this data.
Example additions:
{ id: "earningsPerClick", label: "EPC", default: false, numeric: true }, { id: "averageLifetimeValue", label: "Avg LTV", default: false, numeric: true }, { id: "clickToLeadRate", label: "Click-to-Lead Rate", default: false, numeric: true }, { id: "clickToConversionRate", label: "Click-to-Conversion Rate", default: false, numeric: true }, { id: "leadToConversionRate", label: "Lead-to-Conversion Rate", default: false, numeric: true }, { id: "returnOnAdSpend", label: "ROAS", default: false, numeric: true },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/lib/zod/schemas/partners.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-16T11:14:00.667Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2754
File: apps/web/lib/partnerstack/schemas.ts:47-52
Timestamp: 2025-08-16T11:14:00.667Z
Learning: The PartnerStack API always includes the `group` field in partner responses, so the schema should use `.nullable()` rather than `.nullish()` since the field is never omitted/undefined.
Applied to files:
apps/web/lib/zod/schemas/partners.ts
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
apps/web/lib/zod/schemas/partners.ts
📚 Learning: 2025-07-30T15:29:54.131Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/rewards-logic.tsx:268-275
Timestamp: 2025-07-30T15:29:54.131Z
Learning: In apps/web/ui/partners/rewards/rewards-logic.tsx, when setting the entity field in a reward condition, dependent fields (attribute, operator, value) should be reset rather than preserved because different entities (customer vs sale) have different available attributes. Maintaining existing fields when the entity changes would create invalid state combinations and confusing UX.
Applied to files:
apps/web/lib/zod/schemas/partners.ts
🔇 Additional comments (3)
apps/web/lib/zod/schemas/partners.ts (3)
126-132: LGTM! New sort options align with calculated metrics.The seven new sorting options for calculated metrics (netRevenue, earningsPerClick, averageLifetimeValue, clickToLeadRate, clickToConversionRate, leadToConversionRate, returnOnAdSpend) are well-integrated and follow the existing pattern.
387-387: Excellent clarity improvements to field descriptions.The updated descriptions for
totalSaleAmountandnetRevenueare clearer and more informative. Including the calculation formula fornetRevenueenhances API documentation quality.Also applies to: 397-399
400-433: Well-designed calculated metrics with consistent schema patterns.All six new calculated metrics follow a consistent pattern:
- Use
.nullish()to properly handle cases where calculations are impossible (e.g., division by zero)- Include clear descriptions with formulas in a standardized format
- Use appropriate numeric types
The previous concern about
earningsPerClickusing.default(0)has been addressed—it now correctly uses.nullish()like the other calculated metrics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (1)
322-391: Truthiness checks still treating zero as no-data.This issue was flagged in a previous review comment and remains unresolved. All six new calculated columns use truthiness checks (
d.field ? ... : "-"), so legitimate zero values render as "-" instead of formatted zeros. Partners with clicks but zero conversions will see blanks for rates/ROAS rather than "0.00%"/"0.00x", which misrepresents their performance.The fix from the previous review should be applied across all new columns:
- d.earningsPerClick ? currencyFormatter(d.earningsPerClick) : "-", + d.earningsPerClick != null + ? currencyFormatter(d.earningsPerClick) + : "-", - d.averageLifetimeValue - ? currencyFormatter(d.averageLifetimeValue) + d.averageLifetimeValue != null + ? currencyFormatter(d.averageLifetimeValue) : "-", - d.clickToLeadRate - ? `${parseFloat((d.clickToLeadRate * 100).toFixed(2))}%` + d.clickToLeadRate != null + ? `${parseFloat((d.clickToLeadRate * 100).toFixed(2))}%` : "-", - d.clickToConversionRate - ? `${parseFloat((d.clickToConversionRate * 100).toFixed(2))}%` + d.clickToConversionRate != null + ? `${parseFloat((d.clickToConversionRate * 100).toFixed(2))}%` : "-", - d.leadToConversionRate - ? `${parseFloat((d.leadToConversionRate * 100).toFixed(2))}%` + d.leadToConversionRate != null + ? `${parseFloat((d.leadToConversionRate * 100).toFixed(2))}%` : "-", - d.returnOnAdSpend - ? `${parseFloat(d.returnOnAdSpend.toFixed(2))}x` + d.returnOnAdSpend != null + ? `${parseFloat(d.returnOnAdSpend.toFixed(2))}x` : "-",
🧹 Nitpick comments (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (1)
353-353: Consider consistent decimal precision across metrics.Wrapping
toFixed(2)inparseFloat()strips trailing zeros ("3.00" → "3"), which differs from currency formatting that preserves cents. This creates mixed precision displays:
- EPC: "$3.00" (always 2 decimals)
- ROAS: "3x" (trailing zeros stripped)
- Rates: "0%" vs "1.5%" (variable decimals)
If consistent precision is preferred, remove
parseFloat()to preserve two decimals:- `${parseFloat((d.clickToLeadRate * 100).toFixed(2))}%` + `${(d.clickToLeadRate * 100).toFixed(2)}%` - `${parseFloat((d.clickToConversionRate * 100).toFixed(2))}%` + `${(d.clickToConversionRate * 100).toFixed(2)}%` - `${parseFloat((d.leadToConversionRate * 100).toFixed(2))}%` + `${(d.leadToConversionRate * 100).toFixed(2)}%` - `${parseFloat(d.returnOnAdSpend.toFixed(2))}x` + `${d.returnOnAdSpend.toFixed(2)}x`This would ensure "0.00%", "3.00x", etc., matching the currency formatter's behavior. If variable precision is intentional for cleaner display, this can be ignored.
Also applies to: 365-365, 377-377, 389-389
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
📚 Learning: 2025-07-30T15:29:54.131Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2673
File: apps/web/ui/partners/rewards/rewards-logic.tsx:268-275
Timestamp: 2025-07-30T15:29:54.131Z
Learning: In apps/web/ui/partners/rewards/rewards-logic.tsx, when setting the entity field in a reward condition, dependent fields (attribute, operator, value) should be reset rather than preserved because different entities (customer vs sale) have different available attributes. Maintaining existing fields when the entity changes would create invalid state combinations and confusing UX.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
🧬 Code graph analysis (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (2)
apps/web/lib/types.ts (1)
EnrolledPartnerProps(450-450)packages/utils/src/functions/currency-formatter.ts (1)
currencyFormatter(7-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
Summary by CodeRabbit
New Features
Refactor
Chores