Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steven-tey
Copy link
Collaborator

@steven-tey steven-tey commented Nov 20, 2025

Summary by CodeRabbit

  • New Features

    • Added an option to hide the "Powered by" badge in referral program embeds.
  • Improvements

    • Simplified the referral embed placeholder UI for a cleaner loading state.
    • Streamlined sale conversion tracking lookup to reduce redundant cache checks and improve performance.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Contributor

vercel bot commented Nov 20, 2025

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

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Nov 20, 2025 4:16pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Walkthrough

Added a new hidePoweredByBadge flag to the program embed schema; referral embed UIs now conditionally render the "Powered by" badge and adjusted placeholder UI; simplified track-sale cache logic by changing a dual-key Redis lookup to a single-key retrieval.

Changes

Cohort / File(s) Summary
Referral Embed UI
apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx, apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx
"Powered by" badge rendering now guarded by programEmbedData?.hidePoweredByBadge; removed Wordmark from loading placeholder, replaced Rewards skeletons with a single bordered placeholder, and increased referral placeholder width from xs:w-60 to xs:w-72.
Schema Updates
apps/web/lib/zod/schemas/program-embed.ts
Added hidePoweredByBadge: z.boolean().default(false) to programEmbedSchema.
Cache Logic Simplification
apps/web/lib/api/conversions/track-sale.ts
Replaced dual-key Redis idempotency lookup (new+old keys) with a single-key retrieval; removed old-key fallback and related branching/comments.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant TrackSale
  participant Redis

  rect rgb(220,240,255)
    Note over TrackSale: New flow (single-key)
    Client->>TrackSale: POST /track-sale
    TrackSale->>Redis: GET idempotencyKey
    alt cached
      Redis-->>TrackSale: cachedResponse
      TrackSale-->>Client: return cachedResponse
    else not cached
      TrackSale->>TrackSale: process sale
      TrackSale->>Redis: SET idempotencyKey -> response
      TrackSale-->>Client: return new response
    end
  end

  rect rgb(255,245,220)
    Note over TrackSale: Old flow (dual-key, removed)
    Client->>TrackSale: POST /track-sale
    TrackSale->>Redis: MGET idempotencyKey_new, idempotencyKey_old
    alt newKey found
      Redis-->>TrackSale: cachedResponseNew
      TrackSale-->>Client: return cachedResponseNew
    else oldKey found
      Redis-->>TrackSale: cachedResponseOld
      TrackSale-->>Client: return cachedResponseOld
    else not cached
      TrackSale->>TrackSale: process sale
      TrackSale->>Redis: SET idempotencyKey_new -> response
      TrackSale-->>Client: return new response
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to:
    • apps/web/lib/api/conversions/track-sale.ts: idempotency behavior and backward compatibility with previously cached old-key responses.
    • apps/web/app/(ee)/app.dub.co/embed/referrals/*: verify conditional rendering and responsive CSS changes (placeholder widths and removed Wordmark).
    • apps/web/lib/zod/schemas/program-embed.ts: ensure schema default integrates with consumers that may omit the field.

Possibly related PRs

  • Improve /track/ endpointsΒ #2828 β€” Introduced dual-key mget and workspace-scoped caching in track-sale.ts; directly related to the cache lookup changes in this PR.

Suggested reviewers

  • TWilson023
  • devkiran

Poem

🐰 A tiny flag hops into view,
Badge hides when the setting says it's due.
Wordmarks tucked away, placeholders neat,
Redis keys trimmed β€” the cache feels light on its feet. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 directly and clearly summarizes the two main changes: conditionally hiding a badge and fixing a loading state in the referral embed UI.
✨ Finishing touches
  • πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-badge-loading

πŸ“œ Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between fd6d0ea and f054c80.

πŸ“’ Files selected for processing (4)
  • apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx (1 hunks)
  • apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx (3 hunks)
  • apps/web/lib/api/conversions/track-sale.ts (1 hunks)
  • apps/web/lib/zod/schemas/program-embed.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
πŸ“š Learning: 2025-10-15T01:05:43.266Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2958
File: apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx:432-457
Timestamp: 2025-10-15T01:05:43.266Z
Learning: In apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx, defer refactoring the custom MenuItem component (lines 432-457) to use the shared dub/ui MenuItem component to a future PR, as requested by steven-tey.

Applied to files:

  • apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx
  • apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx
πŸ“š Learning: 2025-09-24T16:10:37.349Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/ui/partners/partner-about.tsx:11-11
Timestamp: 2025-09-24T16:10:37.349Z
Learning: In the Dub codebase, the team prefers to import Icon as a runtime value from "dub/ui" and uses Icon as both a type and variable name in component props, even when this creates shadowing. This is their established pattern and should not be suggested for refactoring.

Applied to files:

  • apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx
πŸ“š Learning: 2025-06-18T20:23:38.835Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2538
File: apps/web/ui/partners/overview/blocks/traffic-sources-block.tsx:50-82
Timestamp: 2025-06-18T20:23:38.835Z
Learning: Internal links within the same application that use target="_blank" may not require rel="noopener noreferrer" according to the team's security standards, even though it's generally considered a best practice for any target="_blank" link.

Applied to files:

  • apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx
πŸ“š Learning: 2025-10-02T22:46:22.739Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2924
File: apps/web/lib/api/conversions/track-lead.ts:7-7
Timestamp: 2025-10-02T22:46:22.739Z
Learning: In apps/web/lib/api/conversions/track-lead.ts, lead events are cached in Redis for 5 minutes (keys: `leadCache:${customer.id}` and `leadCache:${customer.id}:${stringifiedEventName}`) to provide immediate data availability while Tinybird ingestion happens asynchronously. This caching pattern allows for async-only recording without breaking "wait" mode semantics.

Applied to files:

  • apps/web/lib/api/conversions/track-sale.ts
πŸͺ› Biome (2.1.2)
apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx

[error] 208-209: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".

Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.

(lint/security/noBlankTarget)

πŸ”‡ Additional comments (4)
apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx (2)

2-2: LGTM! Import cleanup aligns with usage.

Removing the Wordmark import is correct since the "Powered by" badge is now conditionally rendered in page-client.tsx, and the loading state has been simplified.


73-84: LGTM! Loading state simplification.

The placeholder adjustments improve the loading UI:

  • Wider input placeholder (xs:w-72) provides better visual balance
  • Single consolidated placeholder div is cleaner than the previous multiple skeleton blocks

These changes align well with the conditional badge rendering implemented in page-client.tsx.

apps/web/lib/zod/schemas/program-embed.ts (1)

12-12: LGTM! Schema addition is well-designed.

The hidePoweredByBadge field is properly typed with a sensible default (false = show badge by default). The naming is clear and the positioning alongside the leaderboard configuration is logical.

apps/web/lib/api/conversions/track-sale.ts (1)

61-66: Cache lookup simplification is correct and consistent.

The read operation (line 62) and write operation (line 603) both use the same key format. No references to old or alternative cache key patterns were found in the codebase.


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.

@steven-tey
Copy link
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

βœ… Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between fd6d0ea and f054c80.

πŸ“’ Files selected for processing (4)
  • apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx (1 hunks)
  • apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx (3 hunks)
  • apps/web/lib/api/conversions/track-sale.ts (1 hunks)
  • apps/web/lib/zod/schemas/program-embed.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
πŸ“š Learning: 2025-10-15T01:05:43.266Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2958
File: apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx:432-457
Timestamp: 2025-10-15T01:05:43.266Z
Learning: In apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx, defer refactoring the custom MenuItem component (lines 432-457) to use the shared dub/ui MenuItem component to a future PR, as requested by steven-tey.

Applied to files:

  • apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx
  • apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx
πŸ“š Learning: 2025-09-24T16:10:37.349Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/ui/partners/partner-about.tsx:11-11
Timestamp: 2025-09-24T16:10:37.349Z
Learning: In the Dub codebase, the team prefers to import Icon as a runtime value from "dub/ui" and uses Icon as both a type and variable name in component props, even when this creates shadowing. This is their established pattern and should not be suggested for refactoring.

Applied to files:

  • apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx
πŸ“š Learning: 2025-10-02T22:46:22.739Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2924
File: apps/web/lib/api/conversions/track-lead.ts:7-7
Timestamp: 2025-10-02T22:46:22.739Z
Learning: In apps/web/lib/api/conversions/track-lead.ts, lead events are cached in Redis for 5 minutes (keys: `leadCache:${customer.id}` and `leadCache:${customer.id}:${stringifiedEventName}`) to provide immediate data availability while Tinybird ingestion happens asynchronously. This caching pattern allows for async-only recording without breaking "wait" mode semantics.

Applied to files:

  • apps/web/lib/api/conversions/track-sale.ts
πŸͺ› Biome (2.1.2)
apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx

[error] 208-209: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".

Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the rel="noopener" attribute.

(lint/security/noBlankTarget)

⏰ 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/lib/api/conversions/track-sale.ts (1)

61-66: LGTM! Clean simplification of cache retrieval.

The change from dual-key to single-key Redis cache lookup simplifies the idempotency logic while maintaining the same functionality. The code is now more straightforward and easier to maintain.

apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx (2)

2-2: LGTM! Correctly removed unused import.

The Wordmark import is no longer needed since the loading placeholder no longer displays the powered-by badge unconditionally.


73-84: LGTM! Simplified loading placeholder UI.

The changes appropriately update the loading state to reflect the conditional badge behavior. The placeholder width adjustment and simplified rewards section align with the new conditional rendering approach.

apps/web/lib/zod/schemas/program-embed.ts (1)

12-12: LGTM! Well-defined schema addition.

The new hidePoweredByBadge field follows Zod conventions correctly with an appropriate default value of false, ensuring backward compatibility (badge shows by default unless explicitly hidden).

@steven-tey steven-tey merged commit 57fb244 into main Nov 20, 2025
8 of 9 checks passed
@steven-tey steven-tey deleted the fix-badge-loading branch November 20, 2025 16:20
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.

2 participants