-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Remove partnersEnabled flag 🚀
#2740
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 Git ↗︎
|
WalkthroughThis change removes the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI
participant Server
participant DB
User->>UI: Trigger action (create webhook / set token / view UI)
UI->>Server: Send request (no partnersEnabled check)
Server->>DB: Query / update (no partnersEnabled filter)
DB-->>Server: Return result
Server-->>UI: Respond
UI-->>User: Render result (partner-related items no longer gated)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 3
🔭 Outside diff range comments (2)
apps/web/lib/webhook/create-webhook.ts (1)
72-102: Fix: handle optional linkIds and clean up Promise aggregation
findManyusesid: { in: linkIds }without guarding; whenlinkIdsis undefined, Prisma will error. Also,Promise.all([... , []])mixes an array value into promises list.Suggested diff:
- waitUntil( - (async () => { - const links = await prisma.link.findMany({ - where: { - id: { in: linkIds }, - projectId: workspace.id, - }, - include: { - webhooks: { - select: { - webhookId: true, - }, - }, - }, - }); - - const formatedLinks = links.map((link) => { - return { - ...link, - webhookIds: link.webhooks.map((webhook) => webhook.webhookId), - }; - }); - - Promise.all([ - ...(links && links.length > 0 - ? [linkCache.mset(formatedLinks), []] - : []), - - ...(isLinkLevelWebhook(webhook) ? [webhookCache.set(webhook)] : []), - ]); - })(), - ); + waitUntil( + (async () => { + const tasks: Promise<unknown>[] = []; + + if (linkIds && linkIds.length > 0) { + const links = await prisma.link.findMany({ + where: { + id: { in: linkIds }, + projectId: workspace.id, + }, + include: { + webhooks: { + select: { webhookId: true }, + }, + }, + }); + + const formattedLinks = links.map((link) => ({ + ...link, + webhookIds: link.webhooks.map((w) => w.webhookId), + })); + + if (links.length > 0) { + tasks.push(linkCache.mset(formattedLinks)); + } + } + + if (isLinkLevelWebhook(webhook)) { + tasks.push(webhookCache.set(webhook)); + } + + if (tasks.length > 0) { + await Promise.all(tasks); + } + })(), + );apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsx (1)
30-41: Harden managePaymentMethods: handle errors, set headers, and reset loading stateCurrently, failures (non-2xx or network errors) can leave isLoading stuck true and may throw on missing url. Recommend try/catch/finally, response.ok check, and Content-Type header.
Apply this diff:
- const managePaymentMethods = async () => { - setIsLoading(true); - const { url } = await fetch( - `/api/workspaces/${slug}/billing/payment-methods`, - { - method: "POST", - body: JSON.stringify({}), - }, - ).then((res) => res.json()); - - router.push(url); - }; + const managePaymentMethods = async () => { + setIsLoading(true); + try { + const res = await fetch(`/api/workspaces/${slug}/billing/payment-methods`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({}), + }); + const json = await res.json().catch(() => ({})); + if (!res.ok || !json?.url) { + // Optionally surface a toast here for better UX + console.error("Failed to open billing portal:", json); + return; + } + router.push(json.url); + } finally { + setIsLoading(false); + } + };
🧹 Nitpick comments (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/notifications/page-client.tsx (1)
19-46: LGTM: partner notifications are now always availableStatic list reflects removal of partner gating. Optional: hoist
notificationsto a module-level constant to avoid re-allocation per render.Example:
-export default function NotificationsSettingsPageClient() { - const { id: workspaceId } = useWorkspace(); - const { executeAsync } = useAction(updateNotificationPreference); - - const notifications = [ +const NOTIFICATIONS = [ // ... ]; + +export default function NotificationsSettingsPageClient() { + const { id: workspaceId } = useWorkspace(); + const { executeAsync } = useAction(updateNotificationPreference);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (20)
apps/web/app/(ee)/api/programs/rewardful/campaigns/route.ts(0 hunks)apps/web/app/(ee)/app.dub.co/(new-program)/sidebar-context.tsx(0 hunks)apps/web/app/api/slack/callback/route.ts(1 hunks)apps/web/app/api/webhooks/[webhookId]/route.ts(0 hunks)apps/web/app/api/webhooks/route.ts(0 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/auth.tsx(1 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx(2 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsx(2 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx(1 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/notifications/page-client.tsx(1 hunks)apps/web/lib/actions/partners/onboard-program.ts(0 hunks)apps/web/lib/actions/partners/set-partnerstack-token.ts(0 hunks)apps/web/lib/actions/partners/set-rewardful-token.ts(0 hunks)apps/web/lib/actions/partners/set-tolt-token.ts(0 hunks)apps/web/lib/webhook/create-webhook.ts(2 hunks)apps/web/lib/zod/schemas/workspaces.ts(0 hunks)apps/web/scripts/backfill-invoice-numbers.ts(0 hunks)apps/web/ui/layout/sidebar/dub-partners-popup.tsx(0 hunks)apps/web/ui/webhooks/add-edit-webhook-form.tsx(2 hunks)packages/prisma/schema/workspace.prisma(0 hunks)
💤 Files with no reviewable changes (12)
- packages/prisma/schema/workspace.prisma
- apps/web/lib/zod/schemas/workspaces.ts
- apps/web/ui/layout/sidebar/dub-partners-popup.tsx
- apps/web/lib/actions/partners/set-tolt-token.ts
- apps/web/lib/actions/partners/onboard-program.ts
- apps/web/app/api/webhooks/route.ts
- apps/web/lib/actions/partners/set-rewardful-token.ts
- apps/web/app/(ee)/app.dub.co/(new-program)/sidebar-context.tsx
- apps/web/lib/actions/partners/set-partnerstack-token.ts
- apps/web/app/api/webhooks/[webhookId]/route.ts
- apps/web/app/(ee)/api/programs/rewardful/campaigns/route.ts
- apps/web/scripts/backfill-invoice-numbers.ts
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: TWilson023
PR: dubinc/dub#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.
📚 Learning: 2025-07-30T15:29:54.131Z
Learnt from: TWilson023
PR: dubinc/dub#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)/settings/billing/plan-usage.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/auth.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/notifications/page-client.tsxapps/web/ui/webhooks/add-edit-webhook-form.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
PR: dubinc/dub#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)/settings/billing/plan-usage.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/notifications/page-client.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
📚 Learning: 2025-06-18T20:26:25.177Z
Learnt from: TWilson023
PR: dubinc/dub#2538
File: apps/web/ui/partners/overview/blocks/commissions-block.tsx:16-27
Timestamp: 2025-06-18T20:26:25.177Z
Learning: In the Dub codebase, components that use workspace data (workspaceId, defaultProgramId) are wrapped in `WorkspaceAuth` which ensures these values are always available, making non-null assertions safe. This is acknowledged as a common pattern in their codebase, though not ideal.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/auth.tsxapps/web/ui/webhooks/add-edit-webhook-form.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
📚 Learning: 2025-05-29T09:49:19.604Z
Learnt from: devkiran
PR: dubinc/dub#2433
File: apps/web/ui/modals/add-payment-method-modal.tsx:60-62
Timestamp: 2025-05-29T09:49:19.604Z
Learning: The `/api/workspaces/${slug}/billing/payment-methods` POST endpoint in the billing API returns either an error (handled by response.ok check) or a response object containing a `url` property for successful requests.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsx
📚 Learning: 2025-07-30T15:25:13.936Z
Learnt from: TWilson023
PR: dubinc/dub#2673
File: apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx:56-66
Timestamp: 2025-07-30T15:25:13.936Z
Learning: In apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx, the form schema uses partial condition objects to allow users to add empty/unconfigured condition fields without type errors, while submission validation uses strict schemas to ensure data integrity. This two-stage validation pattern improves UX by allowing progressive completion of complex forms.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsxapps/web/ui/webhooks/add-edit-webhook-form.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
📚 Learning: 2025-06-16T19:21:23.506Z
Learnt from: TWilson023
PR: dubinc/dub#2519
File: apps/web/ui/analytics/utils.ts:35-37
Timestamp: 2025-06-16T19:21:23.506Z
Learning: In the `useAnalyticsFilterOption` function in `apps/web/ui/analytics/utils.ts`, the pattern `options?.context ?? useContext(AnalyticsContext)` is intentionally designed as a complete replacement strategy, not a merge. When `options.context` is provided, it should contain all required fields (`baseApiPath`, `queryString`, `selectedTab`, `requiresUpgrade`) and completely replace the React context, not be merged with it. This is used for dependency injection or testing scenarios.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/notifications/page-client.tsx
📚 Learning: 2025-06-06T07:59:03.120Z
Learnt from: devkiran
PR: dubinc/dub#2177
File: apps/web/lib/api/links/bulk-create-links.ts:66-84
Timestamp: 2025-06-06T07:59:03.120Z
Learning: In apps/web/lib/api/links/bulk-create-links.ts, the team accepts the risk of potential undefined results from links.find() operations when building invalidLinks arrays, because existing links are fetched from the database based on the input links, so matches are expected to always exist.
Applied to files:
apps/web/lib/webhook/create-webhook.ts
📚 Learning: 2025-07-09T20:52:56.592Z
Learnt from: TWilson023
PR: dubinc/dub#2614
File: apps/web/ui/partners/design/previews/lander-preview.tsx:181-181
Timestamp: 2025-07-09T20:52:56.592Z
Learning: In apps/web/ui/partners/design/previews/lander-preview.tsx, the ellipsis wave animation delay calculation `3 - i * -0.15` is intentionally designed to create negative delays that offset each dot's animation cycle. This pattern works correctly for the intended ellipsis effect and should not be changed to positive incremental delays.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
📚 Learning: 2025-06-25T18:08:53.931Z
Learnt from: TWilson023
PR: dubinc/dub#2484
File: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/usage/get-recommended-plan.ts:11-12
Timestamp: 2025-06-25T18:08:53.931Z
Learning: In the Dub codebase, prefer keeping semantically different functions separate even if they currently have identical implementations. This maintains readability and allows for easy future divergence when business logic changes. For example, `hasConversions` and `hasPartners` functions should remain separate despite having the same current logic, as they serve different conceptual purposes and may need different feature checks in the future.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
📚 Learning: 2025-07-17T06:41:45.620Z
Learnt from: devkiran
PR: dubinc/dub#2637
File: apps/web/app/(ee)/api/singular/webhook/route.ts:0-0
Timestamp: 2025-07-17T06:41:45.620Z
Learning: In the Singular integration (apps/web/app/(ee)/api/singular/webhook/route.ts), the event names in the singularToDubEvent object have intentionally different casing: "Copy GAID" and "copy IDFA". This casing difference is valid and should not be changed, as these are the correct event names expected from Singular.
Applied to files:
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx
⏰ 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 (12)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx (1)
202-226: LGTM: correct removal of partnersEnabled gatingCondition now depends only on
defaultProgramId, matching the flag removal.usePartnersCountis already guarded bydefaultProgramIdand the UI gracefully handles loading viaUsageCategory.apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/auth.tsx (1)
31-31: LGTM: simplified auth gating aligns with flag removalShowing the upgrade CTA when plan lacks capability or there’s no
defaultProgramIdis consistent and removes obsolete flag checks.apps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/notifications/page-client.tsx (2)
16-16: LGTM: narrowed workspace destructureOnly
idis used here; dropping other fields is correct.
19-46: Partner notification types already included in schemaConfirmed that
notificationTypesin apps/web/lib/zod/schemas/workspaces.ts (lines 152–156) lists both"newPartnerSale"and"newPartnerApplication". No further changes required.apps/web/lib/webhook/create-webhook.ts (2)
4-4: LGTM: removed partner-specific import
PARTNERS_WEBHOOK_TRIGGERSremoval is consistent with deleting the flag and associated gating.
23-23: LGTM: workspace type now excludes partnersEnabledMatches schema/type removals. Structural typing still allows callers to pass extra fields (e.g., slug).
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsx (2)
20-20: Removal of partnersEnabled from workspace destructure — LGTMMatches PR objective; no downstream usage in this component.
93-108: Partner payment methods unguarded by feature flag — LGTMRendering now depends solely on partnerPaymentMethods presence/length. This aligns with removing the flag.
apps/web/ui/webhooks/add-edit-webhook-form.tsx (2)
36-36: Removal of partnersEnabled from workspace destructure — LGTMConsistent with feature flag deletion.
194-217: Show all workspace-level triggers without partner filtering — LGTMDirectly mapping WORKSPACE_LEVEL_WEBHOOK_TRIGGERS is correct after removing partner gating.
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.tsx (2)
5-5: Import change to buttonVariants — LGTMNo issues.
17-17: Removal of partnersEnabled from workspace destructure — LGTMMatches PR objective and simplifies state.
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-ugrade-cta.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/tests/utils/resource.ts (1)
69-69: Make the discount ID configurable to avoid future brittle updatesHard-coding a changing external ID causes recurring churn. Consider making it configurable via env with a safe fallback.
Apply this diff:
- id: "disc_1K2E253814K7TA6YRKA86XMX5", + id: process.env.E2E_DISCOUNT_ID ?? "disc_1K2E253814K7TA6YRKA86XMX5",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/tests/utils/resource.ts(1 hunks)
⏰ 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 (1)
apps/web/tests/utils/resource.ts (1)
69-77: All discount references updated—please confirm E2E seedingEverything in the codebase has been updated to use the new ID and there are no leftover references to the old one. Before merging, please ensure that your E2E environment is seeded with a discount record matching the new ID (
disc_1K2E253814K7TA6YRKA86XMX5), or update your seed/fixture scripts accordingly.Key findings:
- No occurrences of the old ID (
disc_1JY5V6W88X71C7T5DMXPNWTCD) remain.- The new ID appears only in
apps/web/tests/utils/resource.ts(exported asE2E_DISCOUNT) and is imported across your discount tests.- No other tests or fixtures contain hardcoded discount IDs.
- No seed/fixture files include either the old or new ID—verify that your test setup creates this discount before running E2E tests.
Summary by CodeRabbit
Refactor
Chores