-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Small partners fixes #2881
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
Small partners fixes #2881
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds link conversions to partner APIs and validation, surfaces conversions and a Copy button in the partners links UI, changes link cache invalidation from deleteMany to expireMany across partner account flows, and removes border/background styling from a bounty action bar. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UI as Partners Links Page
participant API as get-partner-for-program
participant DB as Database
UI->>API: GET partner links (workspaceId, includeExpandedFields)
API->>DB: SELECT ... url, clicks, leads, sales, saleAmount, conversions
DB-->>API: Rows with conversions
API-->>UI: JSON links array (includes conversions)
UI->>UI: Render table (Conversions column)
UI->>UI: CopyButton copies short link to clipboard
sequenceDiagram
autonumber
participant Admin as Admin Action
participant Service as Partner Actions Service
participant Cache as linkCache
rect rgba(230,250,230,0.4)
note over Admin,Service: Ban / Bulk-ban / Revoke Invite / Unban flows
Admin->>Service: Trigger partner state change
Service->>Cache: expireMany(links)
note right of Cache: Entries marked expired (not deleted)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ 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. 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: 0
🧹 Nitpick comments (2)
apps/web/lib/api/partners/get-partner-for-program.ts (1)
41-44: Per-link conversions added — LGTMAligns with UI and schema. If
Link.conversionscan be NULL in DB, consider COALESCE for robustness (optional).- 'conversions', CAST(l.conversions AS SIGNED), + 'conversions', COALESCE(CAST(l.conversions AS SIGNED), 0),apps/web/lib/actions/partners/revoke-program-invite.ts (1)
71-73: Pass only domain/key to linkCache.expireManyexpireMany signature is async expireMany(links: Pick<LinkProps, "domain" | "key">[]); partnerLinks are full Link records — map to { domain, key } for clarity/consistency.
File: apps/web/lib/actions/partners/revoke-program-invite.ts (lines ~71-73)
- // Expire the links from Redis - linkCache.expireMany(partnerLinks), + // Expire the links from Redis + linkCache.expireMany( + partnerLinks.map(({ domain, key }) => ({ domain, key })), + ),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-submission-details-sheet.tsx(1 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page-client.tsx(4 hunks)apps/web/lib/actions/partners/ban-partner.ts(2 hunks)apps/web/lib/actions/partners/bulk-ban-partners.ts(1 hunks)apps/web/lib/actions/partners/revoke-program-invite.ts(1 hunks)apps/web/lib/actions/partners/unban-partner.ts(1 hunks)apps/web/lib/api/partners/get-partner-for-program.ts(1 hunks)apps/web/lib/zod/schemas/programs.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: devkiran
PR: dubinc/dub#2448
File: packages/email/src/templates/partner-program-summary.tsx:254-254
Timestamp: 2025-05-29T04:49:42.842Z
Learning: In the Dub codebase, it's acceptable to keep `partners.dub.co` hardcoded rather than making it configurable for different environments.
📚 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/actions/partners/ban-partner.tsapps/web/lib/actions/partners/revoke-program-invite.tsapps/web/lib/actions/partners/bulk-ban-partners.ts
📚 Learning: 2025-09-17T17:44:03.965Z
Learnt from: TWilson023
PR: dubinc/dub#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/lib/actions/partners/revoke-program-invite.ts
🧬 Code graph analysis (5)
apps/web/lib/actions/partners/unban-partner.ts (1)
apps/web/lib/api/links/cache.ts (1)
linkCache(113-113)
apps/web/lib/actions/partners/ban-partner.ts (1)
apps/web/lib/api/links/cache.ts (1)
linkCache(113-113)
apps/web/lib/actions/partners/revoke-program-invite.ts (1)
apps/web/lib/api/links/cache.ts (1)
linkCache(113-113)
apps/web/lib/actions/partners/bulk-ban-partners.ts (1)
apps/web/lib/api/links/cache.ts (1)
linkCache(113-113)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page-client.tsx (1)
packages/utils/src/functions/urls.ts (1)
getPrettyUrl(130-138)
⏰ 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 (8)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-submission-details-sheet.tsx (1)
296-298: Border/background cleanup on sticky footer — LGTMParent already sets border/background; removing on the inner div prevents double borders.
apps/web/lib/actions/partners/bulk-ban-partners.ts (1)
126-128: Expiring cached links after bulk ban — LGTMConsistent with other actions and uses
{ domain, key }shape.apps/web/lib/actions/partners/unban-partner.ts (1)
111-114: Expire cache on unban — LGTMStale cache busting after re-enabling links is correct.
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page-client.tsx (3)
7-7: CopyButton import — LGTMConsistent with usage elsewhere.
46-55: Link cell with CopyButton — LGTMNice UX improvement; concise and accessible.
87-97: Keep event=sales for the Conversions column — 'conversions' maps to sale eventsThe codebase uses "sales" as the events-page param and tracks/increments "conversions" from sale events, so the current href (event=sales) is correct (see apps/web/ui/analytics/events/events-tabs.tsx and apps/web/lib/api/conversions/track-sale.ts).
apps/web/lib/zod/schemas/programs.ts (1)
82-85: Conversions added to ProgramPartnerLinkSchema — LGTMLinkSchema (apps/web/lib/zod/schemas/links.ts) defines conversions: z.number().default(0).
apps/web/lib/actions/partners/ban-partner.ts (1)
99-109: Switch to cache expiration is sensible — expireMany signature verifiedExpiring cached links after DB updates avoids stale reads. apps/web/lib/api/links/cache.ts defines LinkCache.expireMany(links: Pick<LinkProps, "domain" | "key">[]) — matches { domain, key }[].
|
/bug0 run |
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/api/partners/get-partners.ts (1)
140-151: Make link search truly case-insensitive and add an exact ID fast-path
- Apply LOWER() to the column side for link search to avoid case mismatches.
- Add an exact
p.id = ${search}branch to leverage the index when users paste a full ID; retain the LIKE for partials.${ search ? Prisma.sql`AND ( - LOWER(p.id) LIKE LOWER(${`%${search}%`}) + LOWER(p.id) LIKE LOWER(${`%${search}%`}) + OR p.id = ${search} OR LOWER(p.name) LIKE LOWER(${`%${search}%`}) OR LOWER(p.email) LIKE LOWER(${`%${search}%`}) OR EXISTS ( SELECT 1 FROM Link searchLink WHERE searchLink.programId = ${programId} AND searchLink.partnerId = p.id - AND searchLink.shortLink LIKE LOWER(${`%${search}%`}) + AND LOWER(searchLink.shortLink) LIKE LOWER(${`%${search}%`}) ) )` : Prisma.sql`` }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx(2 hunks)apps/web/lib/api/partners/get-partners.ts(1 hunks)apps/web/lib/zod/schemas/partners.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/lib/zod/schemas/partners.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 (3)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx (2)
394-396: Placeholder/UI copy aligns with backend search capabilitiesMatches the new ID-aware and link search server-side behavior. LGTM.
122-125: Verify API support for workspaceId/includeExpandedFields in /api/partnersThe fetch now sends
workspaceIdandincludeExpandedFields: true. Ensure the API route mapsworkspaceId-> tenant/program correctly and respectsincludeExpandedFields; otherwise counts/sorting may desync or the request could be rejected if the endpoint still expectsprogramIdortenantId.apps/web/lib/api/partners/get-partners.ts (1)
158-159: sortBy/sortOrder validated — ORDER BY usage OKgetPartnersQuerySchema (apps/web/lib/zod/schemas/partners.ts) defines sortBy as a z.enum([...]) and sortOrder as z.enum(["asc","desc"]), so Prisma.raw(sortColumnsMap[sortBy]) and Prisma.raw(sortOrder) are protected.
Summary by CodeRabbit
New Features
Style