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

Skip to content

Conversation

@steven-tey
Copy link
Collaborator

@steven-tey steven-tey commented Aug 8, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a dedicated "Create Webhook" button that appears only for eligible workspace plans and user roles.
    • Added a reusable layout for webhooks settings pages, including informative headers and documentation links.
    • Added a new webhook creation page with plan-based access control and form for adding or editing webhooks.
  • Bug Fixes

    • Improved permission checks and plan-based access control for webhook creation, ensuring users on unsupported plans are redirected appropriately.
  • Refactor

    • Streamlined the webhooks settings page by moving creation controls and headers into modular components.
    • Updated internal capability checks to include webhook creation eligibility.
    • Simplified the webhooks list page by removing creation controls and permission logic.
  • Chores

    • Updated function signatures for consistency and maintainability.

@vercel
Copy link
Contributor

vercel bot commented Aug 8, 2025

The latest updates on your projects. Learn more about Vercel for Git β†—οΈŽ

Name Status Preview Updated (UTC)
dub βœ… Ready (Inspect) Visit Preview Aug 8, 2025 4:09am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 8, 2025

Walkthrough

This set of changes restructures the webhooks settings pages. It introduces new components for layout and button control, centralizes plan-based permission logic for webhook creation, and removes duplicated UI and permission checks from the main webhooks page. The ability to create webhooks is now consistently gated by workspace plan capabilities.

Changes

Cohort / File(s) Change Summary
New Webhook Page Client Refactor
.../webhooks/new/page-client.tsx
Old client component removed and replaced with a new version. The new component checks the workspace plan and redirects if not eligible, rendering the webhook form only for higher-tier plans.
Create Webhook Button Introduction
.../webhooks/create-webhook-button.tsx
New client component added to render a "Create Webhook" button, conditionally displayed based on pathname, plan, and permission checks.
Webhooks Layout Component
.../webhooks/layout.tsx
New layout component introduced for webhooks settings pages, including title, description, and the create button.
Webhooks Page Client Simplification
.../webhooks/page-client.tsx
Permission logic, header, tooltip, and "Create Webhook" button removed. Component now only displays the webhook list or placeholder.
Webhooks Page Export Update
.../webhooks/page.tsx
Export changed from async to sync function; no other logic changes.
Plan Capabilities Extension
.../lib/plan-capabilities.ts
getPlanCapabilities now includes a canCreateWebhooks flag, true only for plans above "free" and "pro".

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebhooksPage
    participant CreateWebhookButton
    participant getPlanCapabilities
    participant NewWebhookPageClient

    User->>WebhooksPage: Navigates to /settings/webhooks
    WebhooksPage->>CreateWebhookButton: Render control
    CreateWebhookButton->>getPlanCapabilities: Check canCreateWebhooks
    getPlanCapabilities-->>CreateWebhookButton: Returns capabilities
    alt Eligible plan and correct path
        CreateWebhookButton-->>User: Show "Create Webhook" button
        User->>CreateWebhookButton: Clicks button
        CreateWebhookButton->>NewWebhookPageClient: Navigate to /webhooks/new
        NewWebhookPageClient->>getPlanCapabilities: Check plan
        alt Plan not eligible
            NewWebhookPageClient-->>User: Redirect to /settings/webhooks
        else
            NewWebhookPageClient-->>User: Show Add/Edit Webhook Form
        end
    else
        CreateWebhookButton-->>User: Button not shown
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Poem

A bunny hopped through webhooks’ land,
Tidied buttons with a gentle hand.
Plans checked high, and plans checked low,
Only the worthy see β€œCreate” aglow.
With layouts new and logic neat,
Every carrotβ€”er, featureβ€”now feels complete!
πŸ₯•βœ¨

✨ Finishing Touches
  • πŸ“ Generate Docstrings
πŸ§ͺ Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch webhooks-page

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
πŸͺ§ Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@steven-tey
Copy link
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 8, 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: 0

🧹 Nitpick comments (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/new/page-client.tsx (1)

14-18: Consider using centralized plan capabilities and improve redirect timing.

The plan check logic duplicates what's already available in getPlanCapabilities. Consider using the centralized capability:

+import { getPlanCapabilities } from "@/lib/plan-capabilities";

export default function NewWebhookPageClient({
  newSecret,
}: {
  newSecret: string;
}) {
  const { slug, plan } = useWorkspace();
+  const { canCreateWebhooks } = getPlanCapabilities(plan);

-  const needsHigherPlan = plan === "free" || plan === "pro";
-
-  if (needsHigherPlan) {
+  if (!canCreateWebhooks) {
    redirect(`/${slug}/settings/webhooks`);
  }

Also, the client-side redirect may cause a brief flash of content before redirecting. Consider if server-side redirect would be more appropriate.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/page-client.tsx (2)

15-30: Consider using centralized plan capabilities for consistency.

The plan check logic is duplicated and inconsistent with the new canCreateWebhooks capability. Consider using the centralized approach:

+import { getPlanCapabilities } from "@/lib/plan-capabilities";

export default function WebhooksPageClient() {
  const { slug, plan } = useWorkspace();
+  const { canCreateWebhooks } = getPlanCapabilities(plan);

  const { webhooks, isLoading } = useWebhooks();

-  const needsHigherPlan = plan === "free" || plan === "pro";
-
-  if (needsHigherPlan) {
+  if (!canCreateWebhooks) {

This ensures consistency across all webhook-related components and makes future plan changes easier to manage.


17-30: Consider moving upgrade empty state to layout level.

Since the layout component now handles the overall webhook page structure, the upgrade empty state might be better placed there to avoid duplicating the plan check logic across multiple components.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/create-webhook-button.tsx (1)

27-35: Consider disabling the button when there are permission errors.

The button shows a tooltip for permission errors but remains clickable, which could lead to a confusing user experience where users can navigate to a page they can't use.

Consider disabling the button when there are permission errors:

  return (
    <Link href={`/${slug}/settings/webhooks/new`}>
      <Button
        className="flex h-10 items-center justify-center whitespace-nowrap rounded-lg border px-4 text-sm"
        text="Create Webhook"
        disabledTooltip={permissionsError}
+       disabled={!!permissionsError}
      />
    </Link>
  );
πŸ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between d8ea025 and 7b73eb6.

πŸ“’ Files selected for processing (7)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/webhooks/new/page-client.tsx (0 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/create-webhook-button.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/layout.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/new/page-client.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/page-client.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/page.tsx (1 hunks)
  • apps/web/lib/plan-capabilities.ts (1 hunks)
πŸ’€ Files with no reviewable changes (1)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/(basic-layout)/webhooks/new/page-client.tsx
🧰 Additional context used
🧠 Learnings (2)
πŸ“š Learning: 2025-06-19T01:46:45.723Z
Learnt from: steven-tey
PR: dubinc/dub#0
File: :0-0
Timestamp: 2025-06-19T01:46:45.723Z
Learning: PayPal webhook verification in the Dub codebase is handled at the route level in `apps/web/app/(ee)/api/paypal/webhook/route.ts` using the `verifySignature` function. Individual webhook handlers like `payoutsItemFailed` don't need to re-verify signatures since they're only called after successful verification.

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/page.tsx
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/page-client.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]/settings/webhooks/page.tsx
πŸ”‡ Additional comments (6)
apps/web/lib/plan-capabilities.ts (1)

11-11: LGTM! Consistent capability addition.

The new canCreateWebhooks capability follows the established pattern and correctly restricts webhook creation to higher-tier plans.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/page.tsx (1)

3-5: LGTM! Clean simplification.

Converting to a synchronous function is appropriate since no server-side logic is required. This aligns well with the overall restructuring to delegate functionality to dedicated components.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/layout.tsx (1)

6-20: LGTM! Well-structured layout component.

The layout component provides excellent separation of concerns by centralizing the page structure, title, documentation link, and controls. The integration with CreateWebhookButton maintains consistency across webhook-related pages.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/webhooks/create-webhook-button.tsx (3)

1-8: LGTM!

The imports are well-organized and all necessary for the component's functionality. The "use client" directive is correctly placed for a component using client-side hooks.


22-25: LGTM!

The conditional logic correctly prevents the button from showing when:

  1. The workspace plan doesn't support webhook creation
  2. The user is not on the main webhooks settings page

The pathname.endsWith("/settings/webhooks") check is appropriate for the URL structure.


13-20: Add defensive checks for loading states.

The component doesn't handle potential undefined values during initial loading. The useWorkspace hook might return undefined values before the workspace data is loaded, which could cause issues.

Consider adding loading state checks:

  const { slug, plan, role } = useWorkspace();

+ // Don't render during initial load
+ if (!slug || !plan || role === undefined) {
+   return null;
+ }

  const { canCreateWebhooks } = getPlanCapabilities(plan);
β›” Skipped due to learnings
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.
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.

@steven-tey steven-tey merged commit 5d14cc0 into main Aug 8, 2025
9 of 10 checks passed
@steven-tey steven-tey deleted the webhooks-page branch August 8, 2025 05:14
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