Full Code of dubinc/dub for AI

main 055ca7e99042 cached
3991 files
12.1 MB
3.4M tokens
5941 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (13,548K chars total). Download the full file to get everything.
Repository: dubinc/dub
Branch: main
Commit: 055ca7e99042
Files: 3991
Total size: 12.1 MB

Directory structure:
gitextract_j4v7jeo4/

├── .github/
│   └── workflows/
│       ├── apply-issue-labels-to-pr.yml
│       ├── deploy-embed-script.yml
│       ├── e2e.yaml
│       ├── playwright.yaml
│       └── prettier.yaml
├── .gitignore
├── .prettierignore
├── LICENSE.md
├── README.md
├── SECURITY.md
├── apps/
│   └── web/
│       ├── app/
│       │   ├── (ee)/
│       │   │   ├── LICENSE.md
│       │   │   ├── README.md
│       │   │   ├── admin.dub.co/
│       │   │   │   ├── (auth)/
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   └── login/
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── (dashboard)/
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── commissions/
│       │   │   │   │   │   ├── client.tsx
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── components/
│       │   │   │   │   │   ├── ban-link.tsx
│       │   │   │   │   │   ├── delete-partner-account.tsx
│       │   │   │   │   │   ├── impersonate-user.tsx
│       │   │   │   │   │   ├── impersonate-workspace.tsx
│       │   │   │   │   │   ├── refresh-domain.tsx
│       │   │   │   │   │   ├── reset-login-attempts.tsx
│       │   │   │   │   │   └── user-info.tsx
│       │   │   │   │   ├── events/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── layout-nav-client.tsx
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   ├── links/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── page.tsx
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── client.tsx
│       │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   └── paypal/
│       │   │   │   │   │       ├── client.tsx
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   └── revenue/
│       │   │   │   │       ├── client.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   └── layout.tsx
│       │   │   ├── api/
│       │   │   │   ├── admin/
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── ban/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── commissions/
│       │   │   │   │   │   ├── get-commissions-timeseries.ts
│       │   │   │   │   │   ├── get-top-program-by-commissions.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── delete-partner-account/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── events/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── impersonate/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── links/
│       │   │   │   │   │   ├── [linkId]/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── ban/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── paypal/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── refresh-domain/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── reset-login-attempts/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── revenue/
│       │   │   │   │       ├── get-top-programs-by-sales.ts
│       │   │   │   │       └── route.ts
│       │   │   │   ├── audit-logs/
│       │   │   │   │   └── export/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── auth/
│       │   │   │   │   └── saml/
│       │   │   │   │       ├── authorize/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── callback/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── token/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── userinfo/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── verify/
│       │   │   │   │           └── route.tsx
│       │   │   │   ├── bounties/
│       │   │   │   │   ├── [bountyId]/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   ├── submissions/
│       │   │   │   │   │   │   ├── [submissionId]/
│       │   │   │   │   │   │   │   ├── approve/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── reject/
│       │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── sync-social-metrics/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── submissions/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── campaigns/
│       │   │   │   │   ├── [campaignId]/
│       │   │   │   │   │   ├── duplicate/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── preview/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── summary/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── commissions/
│       │   │   │   │   ├── [commissionId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── timeseries/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── cron/
│       │   │   │   │   ├── aggregate-clicks/
│       │   │   │   │   │   ├── resolve-click-reward-amount.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── bounties/
│       │   │   │   │   │   ├── create-draft-submissions/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── notify-partners/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── queue-sync-social-metrics/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── sync-social-metrics/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── campaigns/
│       │   │   │   │   │   └── broadcast/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── cleanup/
│       │   │   │   │   │   ├── demo-embed-partners/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── e2e-tests/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── expired-tokens/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── link-retention/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── rejected-applications/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── unenrolled-partners/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── discount-codes/
│       │   │   │   │   │   ├── create/
│       │   │   │   │   │   │   ├── queue-batches/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── delete/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── disposable-emails/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── domains/
│       │   │   │   │   │   ├── delete/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── renewal-payments/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── renewal-reminders/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── transfer/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── update/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── verify/
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       └── utils.ts
│       │   │   │   │   ├── email-domains/
│       │   │   │   │   │   ├── update/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── verify/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   ├── commissions/
│       │   │   │   │   │   │   ├── fetch-commissions-batch.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   ├── fetch-events-batch.ts
│       │   │   │   │   │   │   ├── partner/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── workspace/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   ├── fetch-links-batch.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── partners/
│       │   │   │   │   │       ├── fetch-partners-batch.ts
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── folders/
│       │   │   │   │   │   └── delete/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── framer/
│       │   │   │   │   │   └── backfill-leads-batch/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── fraud/
│       │   │   │   │   │   └── summary/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── fx-rates/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── groups/
│       │   │   │   │   │   ├── create-default-links/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── remap-default-links/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── remap-discount-codes/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── sync-utm/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── update-default-links/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── import/
│       │   │   │   │   │   ├── bitly/
│       │   │   │   │   │   │   ├── fetch-utils.ts
│       │   │   │   │   │   │   ├── queue-import.ts
│       │   │   │   │   │   │   ├── rate-limit.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   ├── sanitize-json.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── csv/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── firstpromoter/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── partnerstack/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── rebrandly/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── rewardful/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── short/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   └── tolt/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── invoices/
│       │   │   │   │   │   └── retry-failed/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── links/
│       │   │   │   │   │   ├── [linkId]/
│       │   │   │   │   │   │   └── complete-tests/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── delete/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── invalidate-for-discounts/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── invalidate-for-partners/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── messages/
│       │   │   │   │   │   ├── notify-partner/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── notify-program/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── network/
│       │   │   │   │   │   ├── calculate-program-similarities/
│       │   │   │   │   │   │   ├── calculate-category-similarity.ts
│       │   │   │   │   │   │   ├── calculate-partner-similarity.ts
│       │   │   │   │   │   │   ├── calculate-performance-similarity.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── update-partner-discoverability/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── partner-platforms/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── youtube/
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       └── youtube-channel-schema.ts
│       │   │   │   │   ├── partner-program-summary/
│       │   │   │   │   │   ├── process/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── partners/
│       │   │   │   │   │   ├── auto-approve/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── auto-reject/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── ban/
│       │   │   │   │   │   │   ├── cancel-commissions.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── deactivate/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── merge-accounts/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── aggregate-due-commissions/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── balance-available/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── charge-succeeded/
│       │   │   │   │   │   │   ├── queue-external-payouts.ts
│       │   │   │   │   │   │   ├── queue-stripe-payouts.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   ├── send-paypal-payouts.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── force-withdrawals/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── payout-failed/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── payout-paid/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── process/
│       │   │   │   │   │   │   ├── process-payouts.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   ├── split-payouts.ts
│       │   │   │   │   │   │   └── updates/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── reminders/
│       │   │   │   │   │   │   ├── partners/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── program-owners/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   └── send-stripe-payout/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── pending-applications-summary/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── program-application-reminder/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── programs/
│       │   │   │   │   │   └── deactivate/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── send-batch-email/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── shopify/
│       │   │   │   │   │   └── order-paid/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── streams/
│       │   │   │   │   │   ├── update-partner-stats/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── update-workspace-clicks/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── trigger-withdrawal/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── usage/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── utils.ts
│       │   │   │   │   ├── utils.ts
│       │   │   │   │   ├── welcome-user/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── workflows/
│       │   │   │   │   │   └── [workflowId]/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── workspaces/
│       │   │   │   │       └── delete/
│       │   │   │   │           ├── delete-workspace-customers.ts
│       │   │   │   │           ├── delete-workspace-domains.ts
│       │   │   │   │           ├── delete-workspace-folders.ts
│       │   │   │   │           ├── delete-workspace-links.ts
│       │   │   │   │           ├── delete-workspace.ts
│       │   │   │   │           ├── route.ts
│       │   │   │   │           └── utils.ts
│       │   │   │   ├── customers/
│       │   │   │   │   ├── [id]/
│       │   │   │   │   │   ├── activity/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── stripe-invoices/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── search-stripe/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── discount-codes/
│       │   │   │   │   ├── [discountCodeId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── domains/
│       │   │   │   │   ├── register/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── status/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── e2e/
│       │   │   │   │   ├── bounties/
│       │   │   │   │   │   └── [bountyId]/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── enrollments/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── guard.ts
│       │   │   │   │   ├── notification-emails/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── trigger-workflow/
│       │   │   │   │   │   └── [workflowId]/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── workflows/
│       │   │   │   │       ├── [workflowId]/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── route.ts
│       │   │   │   ├── email-domains/
│       │   │   │   │   ├── [domain]/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── verify/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── embed/
│       │   │   │   │   └── referrals/
│       │   │   │   │       ├── analytics/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── earnings/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── leaderboard/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── links/
│       │   │   │   │       │   ├── [linkId]/
│       │   │   │   │       │   │   └── route.ts
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── token/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── events/
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── fraud/
│       │   │   │   │   ├── events/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── groups/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── rules/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── groups/
│       │   │   │   │   ├── [groupIdOrSlug]/
│       │   │   │   │   │   ├── default/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── default-links/
│       │   │   │   │   │   │   ├── [defaultLinkId]/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── partners/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── rules/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── hubspot/
│       │   │   │   │   ├── callback/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── webhook/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── messages/
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── mock/
│       │   │   │   │   └── rewardful/
│       │   │   │   │       ├── affiliates/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── campaigns/
│       │   │   │   │       │   ├── [campaignId]/
│       │   │   │   │       │   │   └── route.ts
│       │   │   │   │       │   ├── campaigns.ts
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── commissions/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── referrals/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── network/
│       │   │   │   │   ├── partners/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── invites-usage/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── programs/
│       │   │   │   │       ├── count/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── route.ts
│       │   │   │   ├── partner-profile/
│       │   │   │   │   ├── invites/
│       │   │   │   │   │   ├── accept/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── messages/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── notification-preferences/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── settings/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── postbacks/
│       │   │   │   │   │   ├── [postbackId]/
│       │   │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── rotate-secret/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── send-test/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── programs/
│       │   │   │   │   │   ├── [programId]/
│       │   │   │   │   │   │   ├── activity-logs/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── analytics/
│       │   │   │   │   │   │   │   ├── export/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── bounties/
│       │   │   │   │   │   │   │   ├── [bountyId]/
│       │   │   │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   │   │   └── social-content-stats/
│       │   │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   │   ├── [customerId]/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── earnings/
│       │   │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   │   └── timeseries/
│       │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   │   ├── export/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── groups/
│       │   │   │   │   │   │   │   └── [groupIdOrSlug]/
│       │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   │   ├── [linkId]/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── referrals/
│       │   │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── resources/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── rewind/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── users/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── partners/
│       │   │   │   │   ├── [partnerId]/
│       │   │   │   │   │   ├── application-risks/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── comments/
│       │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── cross-program-summary/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── ban/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── deactivate/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── links/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── upsert/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── platforms/
│       │   │   │   │   │   └── callback/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── payouts/
│       │   │   │   │   ├── [payoutId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── paypal/
│       │   │   │   │   ├── callback/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── webhook/
│       │   │   │   │       ├── payouts-item-failed.ts
│       │   │   │   │       ├── payouts-item-succeeded.ts
│       │   │   │   │       ├── route.ts
│       │   │   │   │       ├── utils.ts
│       │   │   │   │       └── verify-signature.ts
│       │   │   │   ├── programs/
│       │   │   │   │   ├── [programId]/
│       │   │   │   │   │   ├── applications/
│       │   │   │   │   │   │   ├── [applicationId]/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── export/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── discounts/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── payouts/
│       │   │   │   │   │   │   └── eligible/
│       │   │   │   │   │   │       ├── count/
│       │   │   │   │   │   │       │   └── route.ts
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── referrals/
│       │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── resources/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── rewardful/
│       │   │   │   │       └── campaigns/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── rewards/
│       │   │   │   │   ├── [rewardId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── scim/
│       │   │   │   │   └── v2.0/
│       │   │   │   │       └── [...directory]/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── shopify/
│       │   │   │   │   ├── integration/
│       │   │   │   │   │   ├── callback/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── webhook/
│       │   │   │   │   │       ├── app-uninstalled.ts
│       │   │   │   │   │       ├── customers-data-request.ts
│       │   │   │   │   │       ├── customers-redact.ts
│       │   │   │   │   │       ├── orders-paid.ts
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       └── shop-redact.ts
│       │   │   │   │   └── pixel/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── singular/
│       │   │   │   │   └── webhook/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── stripe/
│       │   │   │   │   ├── connect/
│       │   │   │   │   │   ├── v2/
│       │   │   │   │   │   │   └── webhook/
│       │   │   │   │   │   │       ├── outbound-payment-failed.ts
│       │   │   │   │   │   │       ├── outbound-payment-posted.ts
│       │   │   │   │   │   │       ├── outbound-payment-returned.ts
│       │   │   │   │   │   │       ├── recipient-account-closed.ts
│       │   │   │   │   │   │       ├── recipient-configuration-updated.ts
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   └── webhook/
│       │   │   │   │   │       ├── account-application-deauthorized.ts
│       │   │   │   │   │       ├── account-updated.ts
│       │   │   │   │   │       ├── balance-available.ts
│       │   │   │   │   │       ├── payout-failed.ts
│       │   │   │   │   │       ├── payout-paid.ts
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── integration/
│       │   │   │   │   │   ├── callback/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── webhook/
│       │   │   │   │   │       ├── account-application-deauthorized.ts
│       │   │   │   │   │       ├── charge-refunded.ts
│       │   │   │   │   │       ├── checkout-session-completed.ts
│       │   │   │   │   │       ├── coupon-deleted.ts
│       │   │   │   │   │       ├── customer-created.ts
│       │   │   │   │   │       ├── customer-subscription-created.ts
│       │   │   │   │   │       ├── customer-subscription-deleted.ts
│       │   │   │   │   │       ├── customer-updated.ts
│       │   │   │   │   │       ├── invoice-paid.ts
│       │   │   │   │   │       ├── promotion-code-updated.ts
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       ├── sandbox/
│       │   │   │   │   │       │   └── route.ts
│       │   │   │   │   │       ├── test/
│       │   │   │   │   │       │   └── route.ts
│       │   │   │   │   │       └── utils/
│       │   │   │   │   │           ├── create-new-customer.ts
│       │   │   │   │   │           ├── get-connected-customer.ts
│       │   │   │   │   │           ├── get-promotion-code.ts
│       │   │   │   │   │           ├── get-subscription-product-id.ts
│       │   │   │   │   │           └── update-customer-with-stripe-customer-id.ts
│       │   │   │   │   └── webhook/
│       │   │   │   │       ├── charge-failed.ts
│       │   │   │   │       ├── charge-refunded.ts
│       │   │   │   │       ├── charge-succeeded.ts
│       │   │   │   │       ├── checkout-session-completed.ts
│       │   │   │   │       ├── customer-subscription-deleted.ts
│       │   │   │   │       ├── customer-subscription-updated.ts
│       │   │   │   │       ├── invoice-payment-failed.tsx
│       │   │   │   │       ├── payment-intent-requires-action.ts
│       │   │   │   │       ├── route.ts
│       │   │   │   │       ├── transfer-reversed.ts
│       │   │   │   │       └── utils/
│       │   │   │   │           ├── process-domain-renewal-failure.ts
│       │   │   │   │           ├── process-payout-invoice-failure.ts
│       │   │   │   │           ├── send-cancellation-feedback.ts
│       │   │   │   │           └── update-workspace-plan.ts
│       │   │   │   ├── track/
│       │   │   │   │   ├── click/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── lead/
│       │   │   │   │   │   ├── client/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── open/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── sale/
│       │   │   │   │   │   ├── client/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── visit/
│       │   │   │   │       └── route.ts
│       │   │   │   └── workflows/
│       │   │   │       └── partner-approved/
│       │   │   │           └── route.ts
│       │   │   ├── app.dub.co/
│       │   │   │   ├── (new-program)/
│       │   │   │   │   ├── [slug]/
│       │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   └── program/
│       │   │   │   │   │       └── new/
│       │   │   │   │   │           ├── form.tsx
│       │   │   │   │   │           ├── overview/
│       │   │   │   │   │           │   ├── page-client.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── page.tsx
│       │   │   │   │   │           ├── partners/
│       │   │   │   │   │           │   ├── form.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── rewards/
│       │   │   │   │   │           │   ├── form.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── step-page.tsx
│       │   │   │   │   │           └── support/
│       │   │   │   │   │               ├── form.tsx
│       │   │   │   │   │               └── page.tsx
│       │   │   │   │   ├── header.tsx
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   ├── sidebar-context.tsx
│       │   │   │   │   └── steps.tsx
│       │   │   │   ├── embed/
│       │   │   │   │   ├── referrals/
│       │   │   │   │   │   ├── activity.tsx
│       │   │   │   │   │   ├── add-edit-link.tsx
│       │   │   │   │   │   ├── dynamic-height-messenger.tsx
│       │   │   │   │   │   ├── earnings-summary.tsx
│       │   │   │   │   │   ├── earnings.tsx
│       │   │   │   │   │   ├── faq.tsx
│       │   │   │   │   │   ├── leaderboard.tsx
│       │   │   │   │   │   ├── links-list.tsx
│       │   │   │   │   │   ├── links.tsx
│       │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   ├── quickstart.tsx
│       │   │   │   │   │   ├── resources.tsx
│       │   │   │   │   │   ├── theme-options.ts
│       │   │   │   │   │   ├── token.tsx
│       │   │   │   │   │   ├── types.ts
│       │   │   │   │   │   └── utils.ts
│       │   │   │   │   └── use-embed-token.ts
│       │   │   │   ├── invoices/
│       │   │   │   │   └── [invoiceId]/
│       │   │   │   │       ├── domain-renewal-invoice.tsx
│       │   │   │   │       ├── partner-payout-invoice.tsx
│       │   │   │   │       └── route.tsx
│       │   │   │   └── layout.tsx
│       │   │   └── partners.dub.co/
│       │   │       ├── (apply)/
│       │   │       │   └── [programSlug]/
│       │   │       │       ├── (default)/
│       │   │       │       │   ├── apply/
│       │   │       │       │   │   ├── page.tsx
│       │   │       │       │   │   └── success/
│       │   │       │       │   │       ├── cta-buttons.tsx
│       │   │       │       │   │       ├── page.tsx
│       │   │       │       │   │       ├── pixel-conversion.tsx
│       │   │       │       │   │       └── screenshot.tsx
│       │   │       │       │   ├── apply-button.tsx
│       │   │       │       │   ├── header.tsx
│       │   │       │       │   ├── layout.tsx
│       │   │       │       │   └── page.tsx
│       │   │       │       └── (group-level)/
│       │   │       │           └── [groupSlug]/
│       │   │       │               ├── apply/
│       │   │       │               │   ├── page.tsx
│       │   │       │               │   └── success/
│       │   │       │               │       └── page.tsx
│       │   │       │               ├── layout.tsx
│       │   │       │               └── page.tsx
│       │   │       ├── (auth-login-register)/
│       │   │       │   ├── (generic)/
│       │   │       │   │   ├── layout.tsx
│       │   │       │   │   ├── login/
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   └── register/
│       │   │       │   │       ├── page-client.tsx
│       │   │       │   │       └── page.tsx
│       │   │       │   ├── (program)/
│       │   │       │   │   └── [programSlug]/
│       │   │       │   │       ├── layout.tsx
│       │   │       │   │       ├── login/
│       │   │       │   │       │   └── page.tsx
│       │   │       │   │       └── register/
│       │   │       │   │           └── page.tsx
│       │   │       │   ├── partner-banner.tsx
│       │   │       │   ├── program-logos.tsx
│       │   │       │   └── side-panel.tsx
│       │   │       ├── (auth-other)/
│       │   │       │   ├── auth/
│       │   │       │   │   ├── confirm-email-change/
│       │   │       │   │   │   └── [token]/
│       │   │       │   │   │       └── page.tsx
│       │   │       │   │   └── reset-password/
│       │   │       │   │       └── [token]/
│       │   │       │   │           └── page.tsx
│       │   │       │   ├── forgot-password/
│       │   │       │   │   └── page.tsx
│       │   │       │   ├── invite/
│       │   │       │   │   └── page.tsx
│       │   │       │   ├── layout.tsx
│       │   │       │   ├── logo.tsx
│       │   │       │   └── unsubscribe/
│       │   │       │       └── [token]/
│       │   │       │           └── page.tsx
│       │   │       ├── (dashboard)/
│       │   │       │   ├── account/
│       │   │       │   │   └── settings/
│       │   │       │   │       ├── page.tsx
│       │   │       │   │       └── security/
│       │   │       │   │           └── page.tsx
│       │   │       │   ├── auth.tsx
│       │   │       │   ├── layout.tsx
│       │   │       │   ├── messages/
│       │   │       │   │   ├── [programSlug]/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── layout.tsx
│       │   │       │   │   ├── page-client.tsx
│       │   │       │   │   └── page.tsx
│       │   │       │   ├── payouts/
│       │   │       │   │   ├── page.tsx
│       │   │       │   │   ├── partner-payout-details-sheet.tsx
│       │   │       │   │   ├── partner-payout-settings-button.tsx
│       │   │       │   │   ├── partner-payout-settings-sheet.tsx
│       │   │       │   │   ├── payout-stats.tsx
│       │   │       │   │   ├── payout-table.tsx
│       │   │       │   │   └── use-payout-filters.tsx
│       │   │       │   ├── profile/
│       │   │       │   │   ├── about-you-form.tsx
│       │   │       │   │   ├── how-you-work-form.tsx
│       │   │       │   │   ├── industry-interests-modal.tsx
│       │   │       │   │   ├── members/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── notifications/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── page-client.tsx
│       │   │       │   │   ├── page.tsx
│       │   │       │   │   ├── postbacks/
│       │   │       │   │   │   ├── [id]/
│       │   │       │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   └── page.tsx
│       │   │       │   │   │   ├── add-postback-button.tsx
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── profile-details-form.tsx
│       │   │       │   │   ├── profile-discovery-guide.tsx
│       │   │       │   │   ├── settings-row.tsx
│       │   │       │   │   └── use-partner-discovery-requirements.ts
│       │   │       │   ├── programs/
│       │   │       │   │   ├── [programSlug]/
│       │   │       │   │   │   ├── (enrolled)/
│       │   │       │   │   │   │   ├── analytics/
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── auth.tsx
│       │   │       │   │   │   │   ├── bounties/
│       │   │       │   │   │   │   │   ├── [bountyId]/
│       │   │       │   │   │   │   │   │   ├── bounty-performance-section.tsx
│       │   │       │   │   │   │   │   │   ├── bounty-submissions-table.tsx
│       │   │       │   │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   │   ├── bounty-card.tsx
│       │   │       │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── customers/
│       │   │       │   │   │   │   │   ├── (index)/
│       │   │       │   │   │   │   │   │   ├── layout.tsx
│       │   │       │   │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   │   │   ├── referrals/
│       │   │       │   │   │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   │   │   └── use-partner-customer-filters.tsx
│       │   │       │   │   │   │   │   └── [customerId]/
│       │   │       │   │   │   │   │       ├── page-client.tsx
│       │   │       │   │   │   │   │       └── page.tsx
│       │   │       │   │   │   │   ├── earnings/
│       │   │       │   │   │   │   │   ├── earnings-composite-chart.tsx
│       │   │       │   │   │   │   │   ├── earnings-table.tsx
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── events/
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── hide-program-details-button.tsx
│       │   │       │   │   │   │   ├── layout.tsx
│       │   │       │   │   │   │   ├── links/
│       │   │       │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   │   ├── partner-link-card.tsx
│       │   │       │   │   │   │   │   └── partner-link-controls.tsx
│       │   │       │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   ├── payouts-card.tsx
│       │   │       │   │   │   │   ├── resources/
│       │   │       │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── share-earnings-modal.tsx
│       │   │       │   │   │   │   └── unapproved-program-page.tsx
│       │   │       │   │   │   ├── apply/
│       │   │       │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   └── program-sidebar.tsx
│       │   │       │   │   │   └── invite/
│       │   │       │   │   │       ├── accept-program-invite-button.tsx
│       │   │       │   │   │       ├── page.tsx
│       │   │       │   │   │       └── program-invite-confetti.tsx
│       │   │       │   │   ├── invitations/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── marketplace/
│       │   │       │   │   │   ├── [programSlug]/
│       │   │       │   │   │   │   ├── header-controls.tsx
│       │   │       │   │   │   │   ├── loading.tsx
│       │   │       │   │   │   │   └── page.tsx
│       │   │       │   │   │   ├── featured-program-card.tsx
│       │   │       │   │   │   ├── featured-programs.tsx
│       │   │       │   │   │   ├── layout.tsx
│       │   │       │   │   │   ├── marketplace-empty-state.tsx
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   ├── page.tsx
│       │   │       │   │   │   ├── program-card.tsx
│       │   │       │   │   │   ├── program-sort.tsx
│       │   │       │   │   │   ├── program-status-badge.tsx
│       │   │       │   │   │   └── use-program-network-filters.tsx
│       │   │       │   │   ├── page-client.tsx
│       │   │       │   │   └── page.tsx
│       │   │       │   └── rewind/
│       │   │       │       └── 2025/
│       │   │       │           ├── conclusion.tsx
│       │   │       │           ├── intro.tsx
│       │   │       │           ├── page-client.tsx
│       │   │       │           ├── page.tsx
│       │   │       │           ├── rewind.tsx
│       │   │       │           └── share-rewind-modal.tsx
│       │   │       ├── (onboarding)/
│       │   │       │   ├── layout.tsx
│       │   │       │   └── onboarding/
│       │   │       │       ├── onboarding-form.tsx
│       │   │       │       ├── page.tsx
│       │   │       │       ├── payouts/
│       │   │       │       │   ├── page.tsx
│       │   │       │       │   └── payout-provider.tsx
│       │   │       │       └── platforms/
│       │   │       │           ├── page-client.tsx
│       │   │       │           └── page.tsx
│       │   │       ├── (redirects)/
│       │   │       │   └── apply/
│       │   │       │       └── [programSlug]/
│       │   │       │           └── [[...slug]]/
│       │   │       │               └── page.tsx
│       │   │       ├── invoices/
│       │   │       │   └── [payoutId]/
│       │   │       │       └── route.tsx
│       │   │       └── layout.tsx
│       │   ├── [domain]/
│       │   │   ├── browser-graphic.tsx
│       │   │   ├── layout.tsx
│       │   │   ├── not-found/
│       │   │   │   └── page.tsx
│       │   │   ├── page.tsx
│       │   │   ├── placeholder.tsx
│       │   │   └── stats/
│       │   │       └── [key]/
│       │   │           └── page.tsx
│       │   ├── api/
│       │   │   ├── (old)/
│       │   │   │   └── projects/
│       │   │   │       ├── [slug]/
│       │   │   │       │   ├── domains/
│       │   │   │       │   │   ├── [domain]/
│       │   │   │       │   │   │   ├── route.ts
│       │   │   │       │   │   │   └── verify/
│       │   │   │       │   │   │       └── route.ts
│       │   │   │       │   │   ├── default/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   └── route.ts
│       │   │   │       │   ├── links/
│       │   │   │       │   │   ├── [linkId]/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── bulk/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── count/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── info/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── random/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   └── route.ts
│       │   │   │       │   ├── route.ts
│       │   │   │       │   └── tags/
│       │   │   │       │       ├── [id]/
│       │   │   │       │       │   └── route.ts
│       │   │   │       │       └── route.ts
│       │   │   │       └── route.ts
│       │   │   ├── activity-logs/
│       │   │   │   └── route.ts
│       │   │   ├── ai/
│       │   │   │   ├── completion/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── support-chat/
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── upload/
│       │   │   │   │       └── route.ts
│       │   │   │   └── sync-embeddings/
│       │   │   │       ├── fetch-plausible-pageviews.ts
│       │   │   │       └── route.ts
│       │   │   ├── analytics/
│       │   │   │   ├── [eventType]/
│       │   │   │   │   ├── [endpoint]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── dashboard/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── export/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── auth/
│       │   │   │   ├── [...nextauth]/
│       │   │   │   │   └── route.tsx
│       │   │   │   └── reset-password/
│       │   │   │       └── route.ts
│       │   │   ├── callback/
│       │   │   │   ├── bitly/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── plain/
│       │   │   │   │   ├── partner/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── utils.ts
│       │   │   │   │   └── workspace/
│       │   │   │   │       └── route.ts
│       │   │   │   └── stripe/
│       │   │   │       └── route.ts
│       │   │   ├── dashboards/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── docs/
│       │   │   │   └── guides/
│       │   │   │       └── [guide]/
│       │   │   │           └── route.ts
│       │   │   ├── domains/
│       │   │   │   ├── [domain]/
│       │   │   │   │   ├── primary/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   ├── transfer/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── validate/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── verify/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── client/
│       │   │   │   │   ├── register/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── saved/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── default/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── route.ts
│       │   │   │   └── search-availability/
│       │   │   │       └── route.ts
│       │   │   ├── dub/
│       │   │   │   └── webhook/
│       │   │   │       ├── lead-created.ts
│       │   │   │       ├── route.ts
│       │   │   │       └── sale-created.ts
│       │   │   ├── folders/
│       │   │   │   ├── [folderId]/
│       │   │   │   │   ├── dashboard/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── users/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── access-requests/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── permissions/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── integrations/
│       │   │   │   ├── route.ts
│       │   │   │   └── uninstall/
│       │   │   │       └── route.ts
│       │   │   ├── links/
│       │   │   │   ├── [linkId]/
│       │   │   │   │   ├── dashboard/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── transfer/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── bulk/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── exists/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── export/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── iframeable/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── info/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── metatags/
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── random/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── route.ts
│       │   │   │   ├── sync/
│       │   │   │   │   └── route.ts
│       │   │   │   └── upsert/
│       │   │   │       └── route.ts
│       │   │   ├── me/
│       │   │   │   └── route.ts
│       │   │   ├── misc/
│       │   │   │   ├── check-favicon/
│       │   │   │   │   └── route.ts
│       │   │   │   └── check-workspace-slug/
│       │   │   │       └── route.ts
│       │   │   ├── oauth/
│       │   │   │   ├── apps/
│       │   │   │   │   ├── [appId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── authorize/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── token/
│       │   │   │   │   ├── exchange-code-for-token.ts
│       │   │   │   │   ├── refresh-access-token.ts
│       │   │   │   │   └── route.ts
│       │   │   │   └── userinfo/
│       │   │   │       └── route.ts
│       │   │   ├── og/
│       │   │   │   ├── analytics/
│       │   │   │   │   └── route.tsx
│       │   │   │   ├── avatar/
│       │   │   │   │   └── [[...seed]]/
│       │   │   │   │       └── route.tsx
│       │   │   │   ├── load-google-font.ts
│       │   │   │   ├── partner-earnings/
│       │   │   │   │   └── route.tsx
│       │   │   │   ├── partner-rewind/
│       │   │   │   │   └── route.tsx
│       │   │   │   └── program/
│       │   │   │       └── route.tsx
│       │   │   ├── postbacks/
│       │   │   │   └── callback/
│       │   │   │       └── route.ts
│       │   │   ├── providers/
│       │   │   │   └── route.ts
│       │   │   ├── qr/
│       │   │   │   └── route.tsx
│       │   │   ├── resend/
│       │   │   │   └── webhook/
│       │   │   │       ├── email-bounced.ts
│       │   │   │       ├── email-delivered.ts
│       │   │   │       ├── email-opened.ts
│       │   │   │       └── route.ts
│       │   │   ├── resumes/
│       │   │   │   └── upload-url/
│       │   │   │       └── route.ts
│       │   │   ├── route.ts
│       │   │   ├── slack/
│       │   │   │   ├── callback/
│       │   │   │   │   └── route.ts
│       │   │   │   └── slash-commands/
│       │   │   │       └── route.ts
│       │   │   ├── supported-countries/
│       │   │   │   └── route.ts
│       │   │   ├── tags/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── tokens/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── embed/
│       │   │   │   │   └── referrals/
│       │   │   │   │       └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── unsplash/
│       │   │   │   ├── download/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── search/
│       │   │   │   │   └── route.ts
│       │   │   │   └── utils.ts
│       │   │   ├── user/
│       │   │   │   ├── notification-preferences/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── password/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── referrals-token/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── route.ts
│       │   │   │   ├── set-password/
│       │   │   │   │   └── route.ts
│       │   │   │   └── tokens/
│       │   │   │       └── route.ts
│       │   │   ├── utm/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── webhooks/
│       │   │   │   ├── [webhookId]/
│       │   │   │   │   ├── events/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── callback/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   └── workspaces/
│       │   │       ├── [idOrSlug]/
│       │   │       │   ├── billing/
│       │   │       │   │   ├── cancel/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── invoices/
│       │   │       │   │   │   ├── [invoiceId]/
│       │   │       │   │   │   │   └── route.ts
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── manage/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── payment-methods/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── upgrade/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   └── usage/
│       │   │       │   │       └── route.ts
│       │   │       │   ├── import/
│       │   │       │   │   ├── [importId]/
│       │   │       │   │   │   └── download/
│       │   │       │   │   │       └── route.ts
│       │   │       │   │   ├── bitly/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── csv/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── rebrandly/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   └── short/
│       │   │       │   │       └── route.ts
│       │   │       │   ├── invites/
│       │   │       │   │   ├── accept/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── decline/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── reset/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   └── route.ts
│       │   │       │   ├── notification-preferences/
│       │   │       │   │   └── route.ts
│       │   │       │   ├── route.ts
│       │   │       │   ├── saml/
│       │   │       │   │   └── route.ts
│       │   │       │   ├── scim/
│       │   │       │   │   └── route.ts
│       │   │       │   ├── stats/
│       │   │       │   │   └── [endpoint]/
│       │   │       │   │       └── route.ts
│       │   │       │   ├── upload-url/
│       │   │       │   │   └── route.ts
│       │   │       │   └── users/
│       │   │       │       └── route.ts
│       │   │       └── route.ts
│       │   ├── app.dub.co/
│       │   │   ├── (auth)/
│       │   │   │   ├── auth/
│       │   │   │   │   ├── confirm-email-change/
│       │   │   │   │   │   └── [token]/
│       │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   ├── reset-password/
│       │   │   │   │   │   └── [token]/
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   └── saml/
│       │   │   │   │       ├── form.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── customer-logos.tsx
│       │   │   │   ├── forgot-password/
│       │   │   │   │   └── page.tsx
│       │   │   │   ├── invites/
│       │   │   │   │   └── [code]/
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── login/
│       │   │   │   │   └── page.tsx
│       │   │   │   ├── oauth/
│       │   │   │   │   └── authorize/
│       │   │   │   │       ├── authorize-form.tsx
│       │   │   │   │       ├── loading.tsx
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       └── scopes-requested.tsx
│       │   │   │   ├── register/
│       │   │   │   │   ├── page-client.tsx
│       │   │   │   │   └── page.tsx
│       │   │   │   ├── side-panel.tsx
│       │   │   │   └── unsubscribe/
│       │   │   │       └── [token]/
│       │   │   │           ├── page.tsx
│       │   │   │           └── unsubscribe-form.tsx
│       │   │   ├── (dashboard)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   ├── (ee)/
│       │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   ├── [customerId]/
│       │   │   │   │   │   │   │   ├── earnings/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   └── sales/
│       │   │   │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   ├── program/
│       │   │   │   │   │   │   ├── analytics/
│       │   │   │   │   │   │   │   ├── analytics-chart.tsx
│       │   │   │   │   │   │   │   ├── analytics-partners-table.tsx
│       │   │   │   │   │   │   │   ├── analytics-timeseries-chart.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   └── partner-analytics-filter-cell.tsx
│       │   │   │   │   │   │   ├── auth.tsx
│       │   │   │   │   │   │   ├── bounties/
│       │   │   │   │   │   │   │   ├── [bountyId]/
│       │   │   │   │   │   │   │   │   ├── bounty-header.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-info.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-submission-details-sheet.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-submission-row-menu.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-submissions-table.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── use-bounty-submission-filters.tsx
│       │   │   │   │   │   │   │   ├── add-edit-bounty/
│       │   │   │   │   │   │   │   │   ├── add-edit-bounty-sheet.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-amount-input.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-criteria-manual-submission.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-criteria-social-metrics.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-criteria.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-form-context.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-logic.tsx
│       │   │   │   │   │   │   │   │   ├── confirm-create-bounty-modal.tsx
│       │   │   │   │   │   │   │   │   └── use-add-edit-bounty-form.ts
│       │   │   │   │   │   │   │   ├── bounty-action-button.tsx
│       │   │   │   │   │   │   │   ├── bounty-card.tsx
│       │   │   │   │   │   │   │   ├── bounty-list.tsx
│       │   │   │   │   │   │   │   ├── create-bounty-button.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── campaigns/
│       │   │   │   │   │   │   │   ├── [campaignId]/
│       │   │   │   │   │   │   │   │   ├── campaign-action-bar.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-controls.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-editor-skeleton.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-editor.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-events-columns.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-events-modal.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-events.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-form-context.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-groups-selector.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-metrics.tsx
│       │   │   │   │   │   │   │   │   ├── duplicate-logic-warning.tsx
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   ├── send-email-preview-modal.tsx
│       │   │   │   │   │   │   │   │   ├── transactional-campaign-logic.tsx
│       │   │   │   │   │   │   │   │   ├── use-campaign-confirmation-modals.tsx
│       │   │   │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   │   │   ├── campaign-stats.tsx
│       │   │   │   │   │   │   │   ├── campaign-status-badges.tsx
│       │   │   │   │   │   │   │   ├── campaign-type-badges.tsx
│       │   │   │   │   │   │   │   ├── campaign-type-icon.tsx
│       │   │   │   │   │   │   │   ├── campaigns-page-content.tsx
│       │   │   │   │   │   │   │   ├── campaigns-table.tsx
│       │   │   │   │   │   │   │   ├── campaigns-upsell.tsx
│       │   │   │   │   │   │   │   ├── create-campaign-button.tsx
│       │   │   │   │   │   │   │   ├── delete-campaign-modal.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── use-campaign.tsx
│       │   │   │   │   │   │   │   ├── use-campaigns-count.tsx
│       │   │   │   │   │   │   │   └── use-campaigns-filters.tsx
│       │   │   │   │   │   │   ├── coming-soon-page.tsx
│       │   │   │   │   │   │   ├── commissions/
│       │   │   │   │   │   │   │   ├── [commissionId]/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── commission-popover-buttons.tsx
│       │   │   │   │   │   │   │   ├── commissions-stats.tsx
│       │   │   │   │   │   │   │   ├── commissions-table.tsx
│       │   │   │   │   │   │   │   ├── create-clawback-sheet.tsx
│       │   │   │   │   │   │   │   ├── create-commission-button.tsx
│       │   │   │   │   │   │   │   ├── create-commission-sheet.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   └── use-commission-filters.tsx
│       │   │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   │   ├── (index)/
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── referrals/
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── [customerId]/
│       │   │   │   │   │   │   │   │   ├── earnings/
│       │   │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── sales/
│       │   │   │   │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   └── customers-dropdown-menu.tsx
│       │   │   │   │   │   │   ├── fraud/
│       │   │   │   │   │   │   │   ├── example-fraud-events.tsx
│       │   │   │   │   │   │   │   ├── fraud-group-table.tsx
│       │   │   │   │   │   │   │   ├── fraud-paid-traffic-settings.tsx
│       │   │   │   │   │   │   │   ├── fraud-referral-source-settings.tsx
│       │   │   │   │   │   │   │   ├── fraud-rule-toggle-settings.tsx
│       │   │   │   │   │   │   │   ├── fraud-upsell.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── program-fraud-actions-menu.tsx
│       │   │   │   │   │   │   │   ├── program-fraud-settings-button.tsx
│       │   │   │   │   │   │   │   ├── program-fraud-settings-sheet.tsx
│       │   │   │   │   │   │   │   ├── resolved/
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── resolved-fraud-group-table.tsx
│       │   │   │   │   │   │   │   └── use-fraud-group-filters.tsx
│       │   │   │   │   │   │   ├── groups/
│       │   │   │   │   │   │   │   ├── [groupSlug]/
│       │   │   │   │   │   │   │   │   ├── branding/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── discounts/
│       │   │   │   │   │   │   │   │   │   ├── group-discounts.tsx
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── group-header.tsx
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   │   │   │   ├── add-edit-group-additional-link-modal.tsx
│       │   │   │   │   │   │   │   │   │   ├── add-edit-group-default-link-sheet.tsx
│       │   │   │   │   │   │   │   │   │   ├── change-program-domain-modal.tsx
│       │   │   │   │   │   │   │   │   │   ├── group-additional-links.tsx
│       │   │   │   │   │   │   │   │   │   ├── group-default-links.tsx
│       │   │   │   │   │   │   │   │   │   ├── group-link-settings.tsx
│       │   │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   │   └── partner-link-preview.tsx
│       │   │   │   │   │   │   │   │   ├── rewards/
│       │   │   │   │   │   │   │   │   │   ├── group-rewards.tsx
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   └── settings/
│       │   │   │   │   │   │   │   │       ├── group-additional-settings.tsx
│       │   │   │   │   │   │   │   │       ├── group-move-rules.tsx
│       │   │   │   │   │   │   │   │       ├── group-settings.tsx
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── create-group-button.tsx
│       │   │   │   │   │   │   │   ├── create-group-modal.tsx
│       │   │   │   │   │   │   │   ├── groups-table.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   ├── messages/
│       │   │   │   │   │   │   │   ├── [partnerId]/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── messages-disabled.tsx
│       │   │   │   │   │   │   │   ├── messages-upsell.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── network/
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── network-empty-state.tsx
│       │   │   │   │   │   │   │   ├── network-upsell.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   └── use-partner-network-filters.tsx
│       │   │   │   │   │   │   ├── overview-chart.tsx
│       │   │   │   │   │   │   ├── overview-links.tsx
│       │   │   │   │   │   │   ├── overview-tasks.tsx
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   ├── partners/
│       │   │   │   │   │   │   │   ├── [partnerId]/
│       │   │   │   │   │   │   │   │   ├── comments/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── partner-nav.tsx
│       │   │   │   │   │   │   │   │   ├── partner-stats.tsx
│       │   │   │   │   │   │   │   │   └── payouts/
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── applications/
│       │   │   │   │   │   │   │   │   ├── applications-menu.tsx
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── rejected/
│       │   │   │   │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── import-export-buttons.tsx
│       │   │   │   │   │   │   │   ├── invite-partner-button.tsx
│       │   │   │   │   │   │   │   ├── invite-partner-sheet.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── partners-table.tsx
│       │   │   │   │   │   │   │   └── use-partner-filters.tsx
│       │   │   │   │   │   │   ├── partners-graphic.tsx
│       │   │   │   │   │   │   ├── partners-upgrade-cta.tsx
│       │   │   │   │   │   │   ├── payouts/
│       │   │   │   │   │   │   │   ├── [payoutId]/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── payout-paid-cell.tsx
│       │   │   │   │   │   │   │   ├── payout-stats.tsx
│       │   │   │   │   │   │   │   ├── payout-table.tsx
│       │   │   │   │   │   │   │   ├── program-payout-methods.tsx
│       │   │   │   │   │   │   │   ├── program-payout-mode-section.tsx
│       │   │   │   │   │   │   │   ├── program-payout-settings-button.tsx
│       │   │   │   │   │   │   │   ├── program-payout-settings-sheet.tsx
│       │   │   │   │   │   │   │   ├── success/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   └── use-payout-filters.tsx
│       │   │   │   │   │   │   ├── program-settings-row.tsx
│       │   │   │   │   │   │   └── resources/
│       │   │   │   │   │   │       ├── page.tsx
│       │   │   │   │   │   │       ├── program-brand-assets/
│       │   │   │   │   │   │       │   ├── add-color-modal.tsx
│       │   │   │   │   │   │       │   ├── add-file-modal.tsx
│       │   │   │   │   │   │       │   ├── add-link-modal.tsx
│       │   │   │   │   │   │       │   ├── add-logo-modal.tsx
│       │   │   │   │   │   │       │   ├── index.tsx
│       │   │   │   │   │   │       │   └── use-upload-program-resource.ts
│       │   │   │   │   │   │       └── program-help-and-support.tsx
│       │   │   │   │   │   └── settings/
│       │   │   │   │   │       ├── billing/
│       │   │   │   │   │       │   ├── invoices/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page.tsx
│       │   │   │   │   │       │   ├── payment-method-types.ts
│       │   │   │   │   │       │   ├── payment-methods.tsx
│       │   │   │   │   │       │   ├── plan-usage.tsx
│       │   │   │   │   │       │   ├── upgrade/
│       │   │   │   │   │       │   │   ├── adjust-usage-row.tsx
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   └── usage-chart.tsx
│       │   │   │   │   │       ├── domains/
│       │   │   │   │   │       │   ├── default/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── email/
│       │   │   │   │   │       │   │   ├── constants.ts
│       │   │   │   │   │       │   │   ├── email-domain-card.tsx
│       │   │   │   │   │       │   │   ├── email-domain-dns-records.tsx
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── header.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── integrations/
│       │   │   │   │   │       │   ├── [integrationSlug]/
│       │   │   │   │   │       │   │   ├── loading.tsx
│       │   │   │   │   │       │   │   ├── manage/
│       │   │   │   │   │       │   │   │   └── page.tsx
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── enabled/
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── enabled-integrations.tsx
│       │   │   │   │   │       │   ├── featured-integrations.tsx
│       │   │   │   │   │       │   ├── integrations-cards.tsx
│       │   │   │   │   │       │   ├── integrations-list.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── new/
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── members/
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── notifications/
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── oauth-apps/
│       │   │   │   │   │       │   ├── [appId]/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── create-oauth-app-button.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── new/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │       ├── page.tsx
│       │   │   │   │   │       ├── security/
│       │   │   │   │   │       │   ├── audit-logs.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   ├── page.tsx
│       │   │   │   │   │       │   ├── saml.tsx
│       │   │   │   │   │       │   └── scim.tsx
│       │   │   │   │   │       ├── tokens/
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── tracking/
│       │   │   │   │   │       │   ├── add-hostname-modal.tsx
│       │   │   │   │   │       │   ├── base-script-section.tsx
│       │   │   │   │   │       │   ├── complete-step-button.tsx
│       │   │   │   │   │       │   ├── connection-instructions.tsx
│       │   │   │   │   │       │   ├── conversion-tracking-section.tsx
│       │   │   │   │   │       │   ├── conversion-tracking-toggle.tsx
│       │   │   │   │   │       │   ├── guide.tsx
│       │   │   │   │   │       │   ├── hostname-menu.tsx
│       │   │   │   │   │       │   ├── hostname-section.tsx
│       │   │   │   │   │       │   ├── outbound-domain-tracking-section.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   ├── page.tsx
│       │   │   │   │   │       │   ├── publishable-key-form.tsx
│       │   │   │   │   │       │   ├── publishable-key-menu.tsx
│       │   │   │   │   │       │   ├── site-visit-tracking-section.tsx
│       │   │   │   │   │       │   ├── step.tsx
│       │   │   │   │   │       │   ├── track-lead-guides-section.tsx
│       │   │   │   │   │       │   ├── track-sales-guides-section.tsx
│       │   │   │   │   │       │   ├── use-dynamic-guide.ts
│       │   │   │   │   │       │   ├── use-selected-guide.ts
│       │   │   │   │   │       │   └── verify-install.tsx
│       │   │   │   │   │       └── webhooks/
│       │   │   │   │   │           ├── [webhookId]/
│       │   │   │   │   │           │   ├── edit/
│       │   │   │   │   │           │   │   ├── page-client.tsx
│       │   │   │   │   │           │   │   └── page.tsx
│       │   │   │   │   │           │   ├── layout.tsx
│       │   │   │   │   │           │   ├── page-client.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── create-webhook-button.tsx
│       │   │   │   │   │           ├── layout.tsx
│       │   │   │   │   │           ├── new/
│       │   │   │   │   │           │   ├── page-client.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── page-client.tsx
│       │   │   │   │   │           └── page.tsx
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   ├── client.tsx
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── auth.tsx
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   └── links/
│       │   │   │   │       ├── [...link]/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── domains/
│       │   │   │   │       │   ├── default/
│       │   │   │   │       │   │   └── page.tsx
│       │   │   │   │       │   ├── email/
│       │   │   │   │       │   │   └── page.tsx
│       │   │   │   │       │   ├── layout.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── folders/
│       │   │   │   │       │   ├── [folderId]/
│       │   │   │   │       │   │   └── members/
│       │   │   │   │       │   │       ├── page-client.tsx
│       │   │   │   │       │   │       └── page.tsx
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── page-client.tsx
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       ├── tags/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   ├── page.tsx
│       │   │   │   │       │   ├── tag-card-placeholder.tsx
│       │   │   │   │       │   └── tag-card.tsx
│       │   │   │   │       └── utm/
│       │   │   │   │           ├── page-client.tsx
│       │   │   │   │           ├── page.tsx
│       │   │   │   │           ├── template-card-placeholder.tsx
│       │   │   │   │           └── template-card.tsx
│       │   │   │   ├── account/
│       │   │   │   │   └── settings/
│       │   │   │   │       ├── page-client.tsx
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       ├── referrals/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── security/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   ├── page.tsx
│       │   │   │   │       │   ├── request-set-password.tsx
│       │   │   │   │       │   └── update-password.tsx
│       │   │   │   │       └── tokens/
│       │   │   │   │           ├── page-client.tsx
│       │   │   │   │           └── page.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   └── loading.tsx
│       │   │   ├── (deeplink)/
│       │   │   │   └── deeplink/
│       │   │   │       └── [domain]/
│       │   │   │           └── [[...key]]/
│       │   │   │               ├── action-buttons.tsx
│       │   │   │               ├── brand-logo-badge.tsx
│       │   │   │               ├── page.tsx
│       │   │   │               └── translations.ts
│       │   │   ├── (invites)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   └── invite/
│       │   │   │   │       ├── accept-invite-button.tsx
│       │   │   │   │       ├── close-invite-button.tsx
│       │   │   │   │       ├── invite-confetti.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   └── layout.tsx
│       │   │   ├── (onboarding)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   └── wrapped/
│       │   │   │   │       ├── [year]/
│       │   │   │   │       │   ├── client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── onboarding/
│       │   │   │   │   ├── (steps)/
│       │   │   │   │   │   ├── domain/
│       │   │   │   │   │   │   ├── custom/
│       │   │   │   │   │   │   │   ├── form.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── default-domain-selector.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   └── register/
│       │   │   │   │   │   │       ├── form.tsx
│       │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   ├── plan/
│       │   │   │   │   │   │   ├── enterprise-link.tsx
│       │   │   │   │   │   │   ├── free-plan-button.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   └── plan-selector.tsx
│       │   │   │   │   │   ├── products/
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   └── product-selector.tsx
│       │   │   │   │   │   ├── program/
│       │   │   │   │   │   │   ├── form.tsx
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   ├── reward/
│       │   │   │   │   │   │   │   ├── form.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   └── use-onboarding-program.tsx
│       │   │   │   │   │   ├── step-page.tsx
│       │   │   │   │   │   ├── success/
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   └── workspace/
│       │   │   │   │   │       ├── form.tsx
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   ├── later-button.tsx
│       │   │   │   │   ├── next-button.tsx
│       │   │   │   │   ├── use-onboarding-product.ts
│       │   │   │   │   ├── use-onboarding-progress.ts
│       │   │   │   │   └── welcome/
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       └── track-signup.tsx
│       │   │   │   └── signed-in-hint.tsx
│       │   │   ├── (redirects)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   ├── domains/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   └── settings/
│       │   │   │   │       ├── referrals/
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       └── tags/
│       │   │   │   │           └── page.tsx
│       │   │   │   ├── analytics/
│       │   │   │   │   └── page.tsx
│       │   │   │   └── loading.tsx
│       │   │   ├── (share)/
│       │   │   │   └── share/
│       │   │   │       └── [dashboardId]/
│       │   │   │           ├── action.ts
│       │   │   │           ├── form.tsx
│       │   │   │           └── page.tsx
│       │   │   ├── embed/
│       │   │   │   └── support-chat/
│       │   │   │       ├── dynamic-height-messenger.tsx
│       │   │   │       ├── layout.tsx
│       │   │   │       └── page.tsx
│       │   │   └── layout.tsx
│       │   ├── banned/
│       │   │   └── page.tsx
│       │   ├── cloaked/
│       │   │   └── [url]/
│       │   │       └── page.tsx
│       │   ├── custom-uri-scheme/
│       │   │   └── [url]/
│       │   │       └── page.tsx
│       │   ├── expired/
│       │   │   └── [domain]/
│       │   │       └── page.tsx
│       │   ├── inspect/
│       │   │   └── [domain]/
│       │   │       └── [key]/
│       │   │           ├── card.tsx
│       │   │           └── page.tsx
│       │   ├── layout.tsx
│       │   ├── manifest.ts
│       │   ├── not-found-hint.tsx
│       │   ├── not-found.tsx
│       │   ├── password/
│       │   │   └── [linkId]/
│       │   │       ├── action.ts
│       │   │       ├── form.tsx
│       │   │       ├── loading.tsx
│       │   │       └── page.tsx
│       │   ├── providers.tsx
│       │   ├── proxy/
│       │   │   └── [domain]/
│       │   │       └── [key]/
│       │   │           └── page.tsx
│       │   ├── robots.ts
│       │   ├── sitemap.ts
│       │   └── wellknown/
│       │       └── [domain]/
│       │           └── [file]/
│       │               └── route.ts
│       ├── docker-compose.yml
│       ├── global-setup.ts
│       ├── guides/
│       │   ├── appwrite.md
│       │   ├── auth0.md
│       │   ├── better-auth.md
│       │   ├── clerk.md
│       │   ├── framer.md
│       │   ├── gtm-client-sdk.md
│       │   ├── gtm-track-lead.md
│       │   ├── gtm-track-sale.md
│       │   ├── manual-client-sdk.md
│       │   ├── manual-track-lead.md
│       │   ├── manual-track-sale.md
│       │   ├── next-auth.md
│       │   ├── react.md
│       │   ├── rest-api.md
│       │   ├── segment-track-lead.md
│       │   ├── segment-track-sale.md
│       │   ├── shopify.md
│       │   ├── stripe-checkout.md
│       │   ├── stripe-customers.md
│       │   ├── stripe-payment-links.md
│       │   ├── supabase.md
│       │   ├── webflow.md
│       │   └── wordpress.md
│       ├── instrumentation.ts
│       ├── lib/
│       │   ├── actions/
│       │   │   ├── add-edit-integration.ts
│       │   │   ├── auth/
│       │   │   │   └── throw-if-authenticated.ts
│       │   │   ├── check-account-exists.ts
│       │   │   ├── create-oauth-url.ts
│       │   │   ├── create-user-account.ts
│       │   │   ├── enable-disable-webhook.ts
│       │   │   ├── folders/
│       │   │   │   ├── request-folder-edit-access.ts
│       │   │   │   ├── set-default-folder.ts
│       │   │   │   └── update-folder-user-role.ts
│       │   │   ├── fraud/
│       │   │   │   ├── bulk-resolve-fraud-groups.ts
│       │   │   │   └── resolve-fraud-group.ts
│       │   │   ├── generate-client-secret.ts
│       │   │   ├── generate-unsubscribe-url.ts
│       │   │   ├── get-integration-install-url.ts
│       │   │   ├── parse-action-errors.ts
│       │   │   ├── partners/
│       │   │   │   ├── accept-program-invite.ts
│       │   │   │   ├── approve-bounty-submission.ts
│       │   │   │   ├── approve-partner.ts
│       │   │   │   ├── archive-partner.ts
│       │   │   │   ├── ban-partner.ts
│       │   │   │   ├── bulk-approve-partners.ts
│       │   │   │   ├── bulk-archive-partners.ts
│       │   │   │   ├── bulk-ban-partners.ts
│       │   │   │   ├── bulk-deactivate-partners.ts
│       │   │   │   ├── bulk-invite-partners.ts
│       │   │   │   ├── bulk-reject-partner-applications.ts
│       │   │   │   ├── confirm-payouts.ts
│       │   │   │   ├── create-bounty-submission.ts
│       │   │   │   ├── create-clawback.ts
│       │   │   │   ├── create-discount.ts
│       │   │   │   ├── create-manual-commission.ts
│       │   │   │   ├── create-partner-comment.ts
│       │   │   │   ├── create-program-application.ts
│       │   │   │   ├── create-program.ts
│       │   │   │   ├── create-reward.ts
│       │   │   │   ├── deactivate-partner.ts
│       │   │   │   ├── delete-discount.ts
│       │   │   │   ├── delete-partner-comment.ts
│       │   │   │   ├── delete-program-invite.ts
│       │   │   │   ├── delete-reward.ts
│       │   │   │   ├── force-withdrawal.ts
│       │   │   │   ├── generate-lander.ts
│       │   │   │   ├── generate-paypal-oauth-url.ts
│       │   │   │   ├── generate-stripe-account-link.ts
│       │   │   │   ├── generate-stripe-recipient-account-link.ts
│       │   │   │   ├── get-conversion-score.ts
│       │   │   │   ├── invite-partner-from-network.ts
│       │   │   │   ├── invite-partner.ts
│       │   │   │   ├── mark-commission-duplicate.ts
│       │   │   │   ├── mark-commission-fraud-or-canceled.ts
│       │   │   │   ├── mark-partner-messages-read.ts
│       │   │   │   ├── mark-program-messages-read.ts
│       │   │   │   ├── merge-partner-accounts.ts
│       │   │   │   ├── message-partner.ts
│       │   │   │   ├── message-program.ts
│       │   │   │   ├── onboard-partner.ts
│       │   │   │   ├── onboard-program.ts
│       │   │   │   ├── program-resources/
│       │   │   │   │   ├── add-program-resource.ts
│       │   │   │   │   ├── constants.ts
│       │   │   │   │   ├── delete-program-resource.ts
│       │   │   │   │   ├── get-program-resource-upload-url.ts
│       │   │   │   │   └── update-program-resource.ts
│       │   │   │   ├── reactivate-partner.ts
│       │   │   │   ├── reject-bounty-submission.ts
│       │   │   │   ├── reject-partner-application.ts
│       │   │   │   ├── reopen-bounty-submission.ts
│       │   │   │   ├── resend-program-invite.ts
│       │   │   │   ├── retry-failed-paypal-payouts.ts
│       │   │   │   ├── revoke-program-invite.ts
│       │   │   │   ├── save-invite-email-data.ts
│       │   │   │   ├── set-rewardful-token.ts
│       │   │   │   ├── set-tolt-token.ts
│       │   │   │   ├── start-firstpromoter-import.ts
│       │   │   │   ├── start-partner-platform-verification.ts
│       │   │   │   ├── start-partnerstack-import.ts
│       │   │   │   ├── start-rewardful-import.ts
│       │   │   │   ├── start-tolt-import.ts
│       │   │   │   ├── trigger-aggregate-due-commissions.ts
│       │   │   │   ├── unban-partner.ts
│       │   │   │   ├── update-application-settings.ts
│       │   │   │   ├── update-discount.ts
│       │   │   │   ├── update-discovered-partner.ts
│       │   │   │   ├── update-group-branding.ts
│       │   │   │   ├── update-partner-comment.ts
│       │   │   │   ├── update-partner-enrollment.ts
│       │   │   │   ├── update-partner-notification-preference.ts
│       │   │   │   ├── update-partner-payout-settings.ts
│       │   │   │   ├── update-partner-platforms.ts
│       │   │   │   ├── update-partner-profile.ts
│       │   │   │   ├── update-program.ts
│       │   │   │   ├── update-reward.ts
│       │   │   │   ├── upload-bounty-submission-file.ts
│       │   │   │   ├── upload-campaign-image.ts
│       │   │   │   ├── upload-lander-image.ts
│       │   │   │   ├── upload-program-application-image.ts
│       │   │   │   ├── verify-partner-website.ts
│       │   │   │   ├── verify-social-account-by-code.ts
│       │   │   │   └── withdraw-partner-application.ts
│       │   │   ├── referrals/
│       │   │   │   ├── submit-referral.ts
│       │   │   │   ├── update-referral-status.ts
│       │   │   │   └── update-referral.ts
│       │   │   ├── request-password-reset.ts
│       │   │   ├── safe-action.ts
│       │   │   ├── send-invite-referral-email.ts
│       │   │   ├── send-otp.ts
│       │   │   ├── send-test-webhook.ts
│       │   │   ├── set-onboarding-progress.ts
│       │   │   ├── submit-oauth-app-for-review.ts
│       │   │   ├── throw-if-no-permission.ts
│       │   │   ├── update-workspace-notification-preference.ts
│       │   │   ├── update-workspace-preferences.ts
│       │   │   ├── update-workspace-store.ts
│       │   │   └── verify-workspace-setup.ts
│       │   ├── ai/
│       │   │   ├── build-system-prompt.ts
│       │   │   ├── create-support-ticket.ts
│       │   │   ├── find-relevant-docs.ts
│       │   │   ├── generate-csv-mapping.ts
│       │   │   ├── generate-filters.ts
│       │   │   ├── get-program-performance.ts
│       │   │   ├── get-workspace-details.ts
│       │   │   ├── request-support-ticket.ts
│       │   │   └── upsert-docs-embedding.ts
│       │   ├── analytics/
│       │   │   ├── allowed-hostnames-cache.ts
│       │   │   ├── constants.ts
│       │   │   ├── convert-currency.ts
│       │   │   ├── events-export-helpers.ts
│       │   │   ├── filter-helpers.ts
│       │   │   ├── format-date-tooltip.ts
│       │   │   ├── get-analytics.ts
│       │   │   ├── get-customer-events.ts
│       │   │   ├── get-events.ts
│       │   │   ├── get-folder-ids-to-filter.ts
│       │   │   ├── is-first-conversion.ts
│       │   │   ├── metadata-query-parser.ts
│       │   │   ├── types.ts
│       │   │   ├── utils/
│       │   │   │   ├── convert-to-csv.ts
│       │   │   │   ├── edit-query-string.ts
│       │   │   │   ├── format-utc-datetime-clickhouse.ts
│       │   │   │   ├── get-interval-data.ts
│       │   │   │   ├── get-start-end-dates.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── valid-date-range-for-plan.ts
│       │   │   └── verify-analytics-allowed-hostnames.ts
│       │   ├── api/
│       │   │   ├── activity-log/
│       │   │   │   ├── build-program-enrollment-change-set.ts
│       │   │   │   ├── get-resource-diff.ts
│       │   │   │   ├── track-activity-log.ts
│       │   │   │   └── track-reward-activity-log.ts
│       │   │   ├── audit-logs/
│       │   │   │   ├── get-audit-logs.ts
│       │   │   │   ├── record-audit-log.ts
│       │   │   │   └── schemas.ts
│       │   │   ├── campaigns/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── get-campaign-events.ts
│       │   │   │   ├── get-campaign-or-throw.ts
│       │   │   │   ├── get-campaign-summary.ts
│       │   │   │   ├── schedule-campaigns.ts
│       │   │   │   └── validate-campaign.ts
│       │   │   ├── commissions/
│       │   │   │   ├── format-commissions-for-export.ts
│       │   │   │   ├── get-commissions-count.ts
│       │   │   │   └── get-commissions.ts
│       │   │   ├── conversions/
│       │   │   │   ├── track-lead.ts
│       │   │   │   └── track-sale.ts
│       │   │   ├── cors.ts
│       │   │   ├── create-downloadable-export.ts
│       │   │   ├── create-id.ts
│       │   │   ├── customers/
│       │   │   │   ├── get-customer-or-throw.ts
│       │   │   │   ├── get-customer-stripe-invoices.ts
│       │   │   │   └── transform-customer.ts
│       │   │   ├── discounts/
│       │   │   │   ├── construct-discount-code.ts
│       │   │   │   ├── create-discount-code.ts
│       │   │   │   ├── delete-discount-code.ts
│       │   │   │   └── is-discount-equivalent.ts
│       │   │   ├── domains/
│       │   │   │   ├── add-domain-vercel.ts
│       │   │   │   ├── claim-dot-link-domain.ts
│       │   │   │   ├── configure-vercel-nameservers.ts
│       │   │   │   ├── get-config-response.ts
│       │   │   │   ├── get-domain-or-throw.ts
│       │   │   │   ├── get-domain-response.ts
│       │   │   │   ├── get-email-domain-or-throw.ts
│       │   │   │   ├── is-valid-domain.ts
│       │   │   │   ├── mark-domain-deleted.ts
│       │   │   │   ├── queue-domain-update.ts
│       │   │   │   ├── remove-domain-vercel.ts
│       │   │   │   ├── transform-domain.ts
│       │   │   │   ├── utils.ts
│       │   │   │   └── verify-domain.ts
│       │   │   ├── environment.ts
│       │   │   ├── error-codes.ts
│       │   │   ├── errors.ts
│       │   │   ├── folders/
│       │   │   │   ├── delete-workspace-folders.ts
│       │   │   │   └── queue-folder-deletion.ts
│       │   │   ├── fraud/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── create-fraud-events.ts
│       │   │   │   ├── define-fraud-rule.ts
│       │   │   │   ├── detect-duplicate-payout-method-fraud.ts
│       │   │   │   ├── detect-record-fraud-application.ts
│       │   │   │   ├── detect-record-fraud-event.ts
│       │   │   │   ├── execute-fraud-rule.ts
│       │   │   │   ├── get-merged-fraud-rules.ts
│       │   │   │   ├── get-partner-application-risks.ts
│       │   │   │   ├── report-cross-program-ban-to-network.ts
│       │   │   │   ├── report-fraud-to-network.ts
│       │   │   │   ├── resolve-fraud-groups.ts
│       │   │   │   ├── rules/
│       │   │   │   │   ├── check-customer-email-match.ts
│       │   │   │   │   ├── check-customer-email-suspicious.ts
│       │   │   │   │   ├── check-paid-traffic-detected.ts
│       │   │   │   │   ├── check-partner-email-domain-mismatch.ts
│       │   │   │   │   ├── check-partner-email-masked.ts
│       │   │   │   │   ├── check-partner-no-social-links.ts
│       │   │   │   │   ├── check-partner-no-verified-social-links.ts
│       │   │   │   │   └── check-referral-source-banned.ts
│       │   │   │   └── utils.ts
│       │   │   ├── get-ratelimit-for-plan.ts
│       │   │   ├── get-workspace-users.ts
│       │   │   ├── groups/
│       │   │   │   ├── find-groups-with-matching-rules.ts
│       │   │   │   ├── get-group-move-rules.ts
│       │   │   │   ├── get-group-or-throw.ts
│       │   │   │   ├── get-groups.ts
│       │   │   │   ├── move-partners-to-group.ts
│       │   │   │   ├── throw-if-invalid-group-ids.ts
│       │   │   │   ├── upsert-group-move-rules.ts
│       │   │   │   └── validate-group-move-rules.ts
│       │   │   ├── links/
│       │   │   │   ├── ab-test-scheduler.ts
│       │   │   │   ├── archive-link.ts
│       │   │   │   ├── bulk-create-links.ts
│       │   │   │   ├── bulk-delete-links.ts
│       │   │   │   ├── bulk-update-links.ts
│       │   │   │   ├── cache.ts
│       │   │   │   ├── case-sensitivity.ts
│       │   │   │   ├── complete-ab-tests.ts
│       │   │   │   ├── create-link.ts
│       │   │   │   ├── delete-link.ts
│       │   │   │   ├── format-links-for-export.ts
│       │   │   │   ├── get-link-or-throw.ts
│       │   │   │   ├── get-links-count.ts
│       │   │   │   ├── get-links-for-workspace.ts
│       │   │   │   ├── include-program-enrollment.ts
│       │   │   │   ├── include-tags.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── plan-features-check.ts
│       │   │   │   ├── process-link.ts
│       │   │   │   ├── propagate-bulk-link-changes.ts
│       │   │   │   ├── record-click-cache.ts
│       │   │   │   ├── update-link-stats-for-importer.ts
│       │   │   │   ├── update-link.ts
│       │   │   │   ├── update-links-usage.ts
│       │   │   │   ├── usage-checks.ts
│       │   │   │   ├── utils/
│       │   │   │   │   ├── check-if-links-have-folders.ts
│       │   │   │   │   ├── check-if-links-have-tags.ts
│       │   │   │   │   ├── check-if-links-have-webhooks.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── key-checks.ts
│       │   │   │   │   ├── process-key.ts
│       │   │   │   │   └── transform-link.ts
│       │   │   │   ├── validate-links-query-filters.ts
│       │   │   │   └── validate-partner-link-url.ts
│       │   │   ├── network/
│       │   │   │   └── calculate-partner-ranking.ts
│       │   │   ├── oauth/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── constants.ts
│       │   │   │   └── utils.ts
│       │   │   ├── pagination.ts
│       │   │   ├── partner-profile/
│       │   │   │   ├── client.ts
│       │   │   │   ├── get-partner-earnings-timeseries.ts
│       │   │   │   ├── get-partner-for-program.ts
│       │   │   │   ├── obfuscate-customer-email.ts
│       │   │   │   ├── partner-platforms-providers.ts
│       │   │   │   └── upsert-partner-platform.ts
│       │   │   ├── partners/
│       │   │   │   ├── bulk-deactivate-partners.ts
│       │   │   │   ├── bulk-delete-partners.ts
│       │   │   │   ├── create-and-enroll-partner.ts
│       │   │   │   ├── create-partner-default-links.ts
│       │   │   │   ├── deactivate-partner.ts
│       │   │   │   ├── format-partners-for-export.ts
│       │   │   │   ├── generate-partner-link.ts
│       │   │   │   ├── get-discount-or-throw.ts
│       │   │   │   ├── get-group-rewards-and-bounties.ts
│       │   │   │   ├── get-network-invites-usage.ts
│       │   │   │   ├── get-partner-rewind.ts
│       │   │   │   ├── get-partner-users.ts
│       │   │   │   ├── get-partners-count.ts
│       │   │   │   ├── get-partners.ts
│       │   │   │   ├── get-reward-or-throw.ts
│       │   │   │   ├── invite-partner-user.ts
│       │   │   │   ├── notify-partner-application.ts
│       │   │   │   ├── notify-partner-commission.ts
│       │   │   │   ├── notify-partner-group-change.ts
│       │   │   │   ├── process-partner-deactivation.ts
│       │   │   │   ├── serialize-reward.ts
│       │   │   │   ├── sync-partner-links-stats.ts
│       │   │   │   ├── sync-total-commissions.ts
│       │   │   │   └── throw-if-existing-tenant-id-exists.ts
│       │   │   ├── payouts/
│       │   │   │   ├── get-effective-payout-mode.ts
│       │   │   │   ├── get-eligible-payouts.ts
│       │   │   │   ├── get-payout-or-throw.ts
│       │   │   │   └── payout-eligibility-filter.ts
│       │   │   ├── postbacks/
│       │   │   │   └── get-postback-or-throw.ts
│       │   │   ├── programs/
│       │   │   │   ├── deactivate-program.ts
│       │   │   │   ├── get-default-program-id-or-throw.ts
│       │   │   │   ├── get-program-enrollment-or-throw.ts
│       │   │   │   └── get-program-or-throw.ts
│       │   │   ├── rbac/
│       │   │   │   ├── permissions.ts
│       │   │   │   └── resources.ts
│       │   │   ├── referrals/
│       │   │   │   ├── get-referral-or-throw.ts
│       │   │   │   ├── mark-referral-closed-won.ts
│       │   │   │   ├── mark-referral-qualified.ts
│       │   │   │   ├── notify-partner-referral-submitted.ts
│       │   │   │   └── notify-referral-status-update.ts
│       │   │   ├── rewards/
│       │   │   │   └── validate-reward.ts
│       │   │   ├── sales/
│       │   │   │   ├── calculate-sale-earnings.ts
│       │   │   │   ├── construct-discount-amount.ts
│       │   │   │   └── construct-reward-amount.ts
│       │   │   ├── scrape-creators/
│       │   │   │   ├── client.ts
│       │   │   │   ├── get-linkedin-post.ts
│       │   │   │   ├── get-social-content.ts
│       │   │   │   ├── get-social-profile.ts
│       │   │   │   └── schema.ts
│       │   │   ├── tags/
│       │   │   │   └── combine-tag-ids.ts
│       │   │   ├── tokens/
│       │   │   │   ├── scopes.ts
│       │   │   │   └── throw-if-no-access.ts
│       │   │   ├── users.ts
│       │   │   ├── utils/
│       │   │   │   ├── assert-valid-date-range-for-plan.ts
│       │   │   │   ├── generate-export-filename.ts
│       │   │   │   ├── generate-random-string.ts
│       │   │   │   ├── get-ip.ts
│       │   │   │   ├── is-non-empty-json.ts
│       │   │   │   └── with-prisma-retry.ts
│       │   │   ├── utils.ts
│       │   │   ├── utm/
│       │   │   │   └── extract-utm-params.ts
│       │   │   ├── validate-allowed-hostnames.ts
│       │   │   ├── workflows/
│       │   │   │   ├── evaluate-workflow-conditions.ts
│       │   │   │   ├── execute-complete-bounty-workflow.ts
│       │   │   │   ├── execute-move-group-workflow.ts
│       │   │   │   ├── execute-send-campaign-workflow.ts
│       │   │   │   ├── execute-workflows.ts
│       │   │   │   ├── interpolate-email-template.ts
│       │   │   │   ├── parse-workflow-config.ts
│       │   │   │   ├── render-campaign-email-html.ts
│       │   │   │   ├── render-campaign-email-markdown.ts
│       │   │   │   └── utils.ts
│       │   │   └── workspaces/
│       │   │       ├── assert-role-plan.ts
│       │   │       ├── create-workspace-id.ts
│       │   │       ├── delete-workspace.ts
│       │   │       ├── is-saml-enforced-for-email-domain.ts
│       │   │       ├── onboarding-step-cache.ts
│       │   │       └── workspace-id.ts
│       │   ├── auth/
│       │   │   ├── admin.ts
│       │   │   ├── confirm-email-change.ts
│       │   │   ├── constants.ts
│       │   │   ├── hash-token.ts
│       │   │   ├── index.ts
│       │   │   ├── lock-account.ts
│       │   │   ├── options.ts
│       │   │   ├── partner-users/
│       │   │   │   ├── partner-user-permissions.ts
│       │   │   │   └── throw-if-no-permission.ts
│       │   │   ├── partner.ts
│       │   │   ├── password.ts
│       │   │   ├── publishable-key.ts
│       │   │   ├── rate-limit-request.ts
│       │   │   ├── session.ts
│       │   │   ├── token-cache.ts
│       │   │   ├── track-dub-lead.ts
│       │   │   ├── utils.ts
│       │   │   └── workspace.ts
│       │   ├── axiom/
│       │   │   ├── axiom.ts
│       │   │   └── server.ts
│       │   ├── bounty/
│       │   │   ├── api/
│       │   │   │   ├── approve-bounty-submission.ts
│       │   │   │   ├── create-bounty-submission.ts
│       │   │   │   ├── generate-performance-bounty-name.ts
│       │   │   │   ├── get-bounties-by-groups.ts
│       │   │   │   ├── get-bounty-or-throw.ts
│       │   │   │   ├── get-bounty-with-details.ts
│       │   │   │   ├── get-group-bounty-summaries.ts
│       │   │   │   ├── get-social-metrics-updates.ts
│       │   │   │   ├── performance-bounty-scope-attributes.ts
│       │   │   │   ├── reject-bounty-submission.ts
│       │   │   │   ├── trigger-draft-bounty-submissions.ts
│       │   │   │   └── validate-bounty.ts
│       │   │   ├── constants.ts
│       │   │   ├── periods.ts
│       │   │   ├── rewards.ts
│       │   │   ├── social-content.ts
│       │   │   ├── submission-status.ts
│       │   │   └── utils.ts
│       │   ├── client-access-check.ts
│       │   ├── constants/
│       │   │   ├── misc.ts
│       │   │   ├── notification-preferences.ts
│       │   │   ├── partner-profile.ts
│       │   │   ├── payouts-supported-countries.ts
│       │   │   ├── payouts.ts
│       │   │   └── program.ts
│       │   ├── cron/
│       │   │   ├── enqueue-batch-jobs.ts
│       │   │   ├── index.ts
│       │   │   ├── limiter.ts
│       │   │   ├── qstash-workflow-logger.ts
│       │   │   ├── qstash-workflow.ts
│       │   │   ├── send-limit-email.ts
│       │   │   ├── verify-qstash.ts
│       │   │   ├── verify-vercel.ts
│       │   │   └── with-cron.ts
│       │   ├── customers/
│       │   │   └── api/
│       │   │       ├── customer-count-where.ts
│       │   │       ├── fetch-customers-batch.ts
│       │   │       ├── format-customers-export.ts
│       │   │       └── get-customers.ts
│       │   ├── dub.ts
│       │   ├── dynadot/
│       │   │   ├── constants.ts
│       │   │   ├── register-domain.ts
│       │   │   ├── search-domains.ts
│       │   │   └── set-renew-option.ts
│       │   ├── edge-config/
│       │   │   ├── get-feature-flags.ts
│       │   │   ├── get-partner-feature-flags.ts
│       │   │   ├── index.ts
│       │   │   ├── is-blacklisted-domain.ts
│       │   │   ├── is-blacklisted-email.ts
│       │   │   ├── is-blacklisted-key.ts
│       │   │   ├── is-blacklisted-referrer.ts
│       │   │   ├── is-reserved-username.ts
│       │   │   └── update.ts
│       │   ├── email/
│       │   │   ├── email-templates-map.ts
│       │   │   ├── extract-email-domain.ts
│       │   │   ├── queue-batch-email.ts
│       │   │   └── unsubscribe-token.ts
│       │   ├── embed/
│       │   │   ├── constants.ts
│       │   │   └── referrals/
│       │   │       ├── auth.ts
│       │   │       └── token-class.ts
│       │   ├── exceeded-limit-error.ts
│       │   ├── fetchers/
│       │   │   ├── get-content-api.ts
│       │   │   ├── get-dashboard.ts
│       │   │   ├── get-network-program.ts
│       │   │   ├── get-program-slugs.ts
│       │   │   ├── get-program.ts
│       │   │   └── index.ts
│       │   ├── firstpromoter/
│       │   │   ├── api.ts
│       │   │   ├── import-campaigns.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   ├── types.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── folder/
│       │   │   ├── constants.ts
│       │   │   ├── get-folder-or-throw.ts
│       │   │   ├── get-folders.ts
│       │   │   └── permissions.ts
│       │   ├── form-utils.ts
│       │   ├── get-highest-severity.ts
│       │   ├── get-integration-guide-markdown.ts
│       │   ├── hooks/
│       │   │   └── use-synced-local-storage.ts
│       │   ├── integrations/
│       │   │   ├── bitly/
│       │   │   │   └── oauth.ts
│       │   │   ├── common/
│       │   │   │   └── ui/
│       │   │   │       └── configure-webhook.tsx
│       │   │   ├── hubspot/
│       │   │   │   ├── api.ts
│       │   │   │   ├── constants.ts
│       │   │   │   ├── oauth.ts
│       │   │   │   ├── schema.ts
│       │   │   │   ├── track-lead.ts
│       │   │   │   ├── track-sale.ts
│       │   │   │   ├── ui/
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── update-hubspot-settings.ts
│       │   │   ├── install.ts
│       │   │   ├── oauth-provider.ts
│       │   │   ├── segment/
│       │   │   │   ├── install.ts
│       │   │   │   ├── transform.ts
│       │   │   │   ├── ui/
│       │   │   │   │   ├── set-write-key.tsx
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── utils.ts
│       │   │   ├── shopify/
│       │   │   │   ├── create-lead.ts
│       │   │   │   ├── create-sale.ts
│       │   │   │   ├── process-order.ts
│       │   │   │   └── schema.ts
│       │   │   ├── singular/
│       │   │   │   ├── track-lead.ts
│       │   │   │   └── track-sale.ts
│       │   │   ├── slack/
│       │   │   │   ├── commands.ts
│       │   │   │   ├── oauth.ts
│       │   │   │   ├── schema.ts
│       │   │   │   ├── transform.ts
│       │   │   │   ├── ui/
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── verify-request.ts
│       │   │   ├── stripe/
│       │   │   │   ├── schema.ts
│       │   │   │   ├── ui/
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── update-stripe-settings.ts
│       │   │   ├── types.ts
│       │   │   ├── utils.ts
│       │   │   └── zapier/
│       │   │       └── ui/
│       │   │           └── settings.tsx
│       │   ├── is-generic-email.ts
│       │   ├── jackson.ts
│       │   ├── links/
│       │   │   └── links-display.ts
│       │   ├── middleware/
│       │   │   ├── admin.ts
│       │   │   ├── api.ts
│       │   │   ├── app.ts
│       │   │   ├── create-link.ts
│       │   │   ├── embed.ts
│       │   │   ├── link.ts
│       │   │   ├── new-link.ts
│       │   │   ├── partners.ts
│       │   │   ├── utils/
│       │   │   │   ├── app-redirect.ts
│       │   │   │   ├── bots-list.ts
│       │   │   │   ├── cache-deeplink-click-data.ts
│       │   │   │   ├── crawl-bitly.ts
│       │   │   │   ├── create-response-with-cookies.ts
│       │   │   │   ├── detect-bot.ts
│       │   │   │   ├── detect-qr.ts
│       │   │   │   ├── get-default-partner.ts
│       │   │   │   ├── get-default-workspace.ts
│       │   │   │   ├── get-final-url.ts
│       │   │   │   ├── get-identity-hash.ts
│       │   │   │   ├── get-user-via-token.ts
│       │   │   │   ├── get-workspace-product.ts
│       │   │   │   ├── handle-not-found-link.ts
│       │   │   │   ├── has-pending-invites.ts
│       │   │   │   ├── is-google-play-store-url.ts
│       │   │   │   ├── is-ios-app-store-url.ts
│       │   │   │   ├── is-ip-in-range.ts
│       │   │   │   ├── is-singular-tracking-url.ts
│       │   │   │   ├── is-supported-custom-uri-scheme.ts
│       │   │   │   ├── is-top-level-settings-redirect.ts
│       │   │   │   ├── is-valid-internal-redirect.ts
│       │   │   │   ├── parse.ts
│       │   │   │   ├── partners-redirect.ts
│       │   │   │   └── resolve-ab-test-url.ts
│       │   │   └── workspaces.ts
│       │   ├── names.ts
│       │   ├── network/
│       │   │   ├── get-discoverability-requirements.ts
│       │   │   ├── get-partner-profile-checklist-progress.ts
│       │   │   └── program-categories.ts
│       │   ├── next-auth.d.ts
│       │   ├── onboarding/
│       │   │   └── types.ts
│       │   ├── openapi/
│       │   │   ├── analytics/
│       │   │   │   └── index.ts
│       │   │   ├── bounties/
│       │   │   │   ├── approve-bounty-submission.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-bounty-submissions.ts
│       │   │   │   └── reject-bounty-submission.ts
│       │   │   ├── commissions/
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-commissions.ts
│       │   │   │   └── update-commission.ts
│       │   │   ├── customers/
│       │   │   │   ├── delete-customer.ts
│       │   │   │   ├── get-customer.ts
│       │   │   │   ├── get-customers.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── update-customer.ts
│       │   │   ├── domains/
│       │   │   │   ├── check-domain-status.ts
│       │   │   │   ├── create-domain.ts
│       │   │   │   ├── delete-domain.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-domains.ts
│       │   │   │   ├── register-domain.ts
│       │   │   │   └── update-domain.ts
│       │   │   ├── embed-tokens/
│       │   │   │   ├── create-referrals-embed-token.ts
│       │   │   │   └── index.ts
│       │   │   ├── events/
│       │   │   │   └── index.ts
│       │   │   ├── folders/
│       │   │   │   ├── create-folder.ts
│       │   │   │   ├── delete-folder.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-folders.ts
│       │   │   │   └── update-folder.ts
│       │   │   ├── index.ts
│       │   │   ├── links/
│       │   │   │   ├── bulk-create-links.ts
│       │   │   │   ├── bulk-delete-links.ts
│       │   │   │   ├── bulk-update-links.ts
│       │   │   │   ├── create-link.ts
│       │   │   │   ├── delete-link.ts
│       │   │   │   ├── get-link-info.ts
│       │   │   │   ├── get-links-count.ts
│       │   │   │   ├── get-links.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── update-link.ts
│       │   │   │   └── upsert-link.ts
│       │   │   ├── partners/
│       │   │   │   ├── ban-partner.ts
│       │   │   │   ├── create-partner-link.ts
│       │   │   │   ├── create-partner.ts
│       │   │   │   ├── deactivate-partner.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-partners.ts
│       │   │   │   ├── retrieve-analytics.ts
│       │   │   │   ├── retrieve-partner-links.ts
│       │   │   │   └── upsert-partner-link.ts
│       │   │   ├── payouts/
│       │   │   │   ├── index.ts
│       │   │   │   └── list-payouts.ts
│       │   │   ├── qr/
│       │   │   │   └── index.ts
│       │   │   ├── responses.ts
│       │   │   ├── tags/
│       │   │   │   ├── create-tag.ts
│       │   │   │   ├── delete-tag.ts
│       │   │   │   ├── get-tags.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── update-tag.ts
│       │   │   └── track/
│       │   │       ├── index.ts
│       │   │       ├── lead.ts
│       │   │       ├── open.ts
│       │   │       └── sale.ts
│       │   ├── partners/
│       │   │   ├── aggregate-partner-links-stats.ts
│       │   │   ├── approve-partner-enrollment.ts
│       │   │   ├── calculate-payout-fee-with-waiver.ts
│       │   │   ├── complete-program-applications.ts
│       │   │   ├── construct-partner-link.ts
│       │   │   ├── create-partner-commission.ts
│       │   │   ├── create-stablecoin-payout.ts
│       │   │   ├── create-stripe-transfer.ts
│       │   │   ├── cutoff-period.ts
│       │   │   ├── determine-partner-reward.ts
│       │   │   ├── evaluate-application-requirements.ts
│       │   │   ├── evaluate-reward-conditions.ts
│       │   │   ├── format-application-form-data.ts
│       │   │   ├── get-group-rewards-and-discount.ts
│       │   │   ├── get-link-structure-options.ts
│       │   │   ├── get-partner-bank-account.ts
│       │   │   ├── get-payout-methods-for-country.ts
│       │   │   ├── get-reward-amount.ts
│       │   │   ├── partner-platforms.ts
│       │   │   ├── partner-profile.ts
│       │   │   ├── query-link-structure-help-text.tsx
│       │   │   ├── sanitize-markdown.ts
│       │   │   ├── sort-rewards-by-event-order.ts
│       │   │   └── throw-if-no-partnerid-tenantid.ts
│       │   ├── partnerstack/
│       │   │   ├── api.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-groups.ts
│       │   │   ├── import-links.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   ├── types.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── payouts/
│       │   │   ├── create-payouts-idempotency-key.ts
│       │   │   ├── get-partner-payout-methods.ts
│       │   │   ├── mark-payouts-as-processed.ts
│       │   │   └── recompute-partner-payout-state.ts
│       │   ├── paypal/
│       │   │   ├── create-batch-payout.ts
│       │   │   ├── create-paypal-token.ts
│       │   │   ├── env.ts
│       │   │   ├── get-pending-payouts.ts
│       │   │   ├── oauth.ts
│       │   │   └── schema.ts
│       │   ├── plain/
│       │   │   ├── client.ts
│       │   │   ├── create-plain-thread.ts
│       │   │   ├── sync-user-plan.ts
│       │   │   └── upsert-plain-customer.ts
│       │   ├── plan-capabilities.ts
│       │   ├── planetscale/
│       │   │   ├── check-if-key-exists.ts
│       │   │   ├── check-if-user-exists.ts
│       │   │   ├── connection.ts
│       │   │   ├── get-domain-via-edge.ts
│       │   │   ├── get-link-via-edge.ts
│       │   │   ├── get-link-with-partner.ts
│       │   │   ├── get-partner-enrollment-info.ts
│       │   │   ├── get-random-key.ts
│       │   │   ├── get-shortlink-via-edge.ts
│       │   │   ├── get-workspace-via-edge.ts
│       │   │   ├── granularity.ts
│       │   │   ├── index.ts
│       │   │   └── types.ts
│       │   ├── plans/
│       │   │   └── has-partner-access.ts
│       │   ├── postback/
│       │   │   ├── api/
│       │   │   │   ├── get-postback-events.ts
│       │   │   │   ├── postback-adapter-custom.ts
│       │   │   │   ├── postback-adapter-slack.ts
│       │   │   │   ├── postback-adapters.ts
│       │   │   │   ├── postback-event-enrichers.ts
│       │   │   │   ├── postback-event-transformers.ts
│       │   │   │   ├── record-postback-event.ts
│       │   │   │   ├── send-partner-postback.ts
│       │   │   │   └── utils.ts
│       │   │   ├── constants.ts
│       │   │   ├── sample-events/
│       │   │   │   ├── commission-created.json
│       │   │   │   ├── lead-created.json
│       │   │   │   └── sale-created.json
│       │   │   └── schemas.ts
│       │   ├── qr/
│       │   │   ├── api.tsx
│       │   │   ├── codegen.ts
│       │   │   ├── constants.ts
│       │   │   ├── index.tsx
│       │   │   ├── types.ts
│       │   │   └── utils.tsx
│       │   ├── referrals/
│       │   │   └── constants.ts
│       │   ├── rewardful/
│       │   │   ├── api.ts
│       │   │   ├── import-affiliate-coupons.ts
│       │   │   ├── import-campaigns.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   └── types.ts
│       │   ├── social-utils.ts
│       │   ├── storage.ts
│       │   ├── stripe/
│       │   │   ├── cancel-subscription.ts
│       │   │   ├── check-payment-method-mandate.ts
│       │   │   ├── client.ts
│       │   │   ├── coupon-discount-converter.ts
│       │   │   ├── create-connected-account.ts
│       │   │   ├── create-fx-quote.ts
│       │   │   ├── create-payment-intent.ts
│       │   │   ├── create-stripe-discount-code.ts
│       │   │   ├── create-stripe-outbound-payment.ts
│       │   │   ├── create-stripe-recipient-account-link.ts
│       │   │   ├── create-stripe-recipient-account.ts
│       │   │   ├── disable-stripe-discount-code.ts
│       │   │   ├── fund-financial-account.ts
│       │   │   ├── get-stripe-outbound-payment.ts
│       │   │   ├── get-stripe-recipient-account.ts
│       │   │   ├── get-stripe-recipient-payout-method.ts
│       │   │   ├── index.ts
│       │   │   ├── payment-methods.ts
│       │   │   ├── stripe-v2-client.ts
│       │   │   └── stripe-v2-schemas.ts
│       │   ├── swr/
│       │   │   ├── mutate.ts
│       │   │   ├── use-activity-logs.ts
│       │   │   ├── use-api-mutation.ts
│       │   │   ├── use-bounty-submissions-count.ts
│       │   │   ├── use-bounty.ts
│       │   │   ├── use-commission.ts
│       │   │   ├── use-commissions-count.ts
│       │   │   ├── use-commissions-timeseries.ts
│       │   │   ├── use-current-folder-id.ts
│       │   │   ├── use-customer-activity.ts
│       │   │   ├── use-customer.ts
│       │   │   ├── use-customers-count.ts
│       │   │   ├── use-customers.ts
│       │   │   ├── use-default-domains.ts
│       │   │   ├── use-discount-codes.ts
│       │   │   ├── use-discounts.ts
│       │   │   ├── use-domain.ts
│       │   │   ├── use-domains-count.ts
│       │   │   ├── use-domains.ts
│       │   │   ├── use-email-domains.ts
│       │   │   ├── use-folder-access-requests.ts
│       │   │   ├── use-folder-link-count.ts
│       │   │   ├── use-folder-permissions.ts
│       │   │   ├── use-folder-users.ts
│       │   │   ├── use-folder.ts
│       │   │   ├── use-folders-count.ts
│       │   │   ├── use-folders.ts
│       │   │   ├── use-fraud-events-count.ts
│       │   │   ├── use-fraud-events-paginated.ts
│       │   │   ├── use-fraud-events.ts
│       │   │   ├── use-fraud-groups-count.ts
│       │   │   ├── use-fraud-groups.ts
│       │   │   ├── use-group-move-rules.ts
│       │   │   ├── use-group.ts
│       │   │   ├── use-groups-count.ts
│       │   │   ├── use-groups.ts
│       │   │   ├── use-guide.ts
│       │   │   ├── use-integrations.ts
│       │   │   ├── use-link.ts
│       │   │   ├── use-links-count.ts
│       │   │   ├── use-links.ts
│       │   │   ├── use-network-partners-count.ts
│       │   │   ├── use-network-programs-count.ts
│       │   │   ├── use-partner-activity-logs.ts
│       │   │   ├── use-partner-analytics.ts
│       │   │   ├── use-partner-application-risks.ts
│       │   │   ├── use-partner-bounty.ts
│       │   │   ├── use-partner-comments-count.ts
│       │   │   ├── use-partner-comments.ts
│       │   │   ├── use-partner-cross-program-summary.ts
│       │   │   ├── use-partner-customer.ts
│       │   │   ├── use-partner-customers-count.ts
│       │   │   ├── use-partner-customers.ts
│       │   │   ├── use-partner-earnings-count.ts
│       │   │   ├── use-partner-earnings-timeseries.ts
│       │   │   ├── use-partner-group-default-links.ts
│       │   │   ├── use-partner-links.ts
│       │   │   ├── use-partner-messages-count.ts
│       │   │   ├── use-partner-messages.ts
│       │   │   ├── use-partner-network-invites-usage.ts
│       │   │   ├── use-partner-payout-settings.ts
│       │   │   ├── use-partner-payouts-count.ts
│       │   │   ├── use-partner-payouts.ts
│       │   │   ├── use-partner-profile.ts
│       │   │   ├── use-partner-program-bounties.ts
│       │   │   ├── use-partner-referrals-count.ts
│       │   │   ├── use-partner-referrals.ts
│       │   │   ├── use-partner-rewind.ts
│       │   │   ├── use-partner.ts
│       │   │   ├── use-partners-count-by-groupids.ts
│       │   │   ├── use-partners-count.ts
│       │   │   ├── use-partners.ts
│       │   │   ├── use-payment-methods.ts
│       │   │   ├── use-payout.ts
│       │   │   ├── use-payouts-count.ts
│       │   │   ├── use-payouts.ts
│       │   │   ├── use-program-enrollment.ts
│       │   │   ├── use-program-enrollments-count.ts
│       │   │   ├── use-program-enrollments.ts
│       │   │   ├── use-program-messages-count.ts
│       │   │   ├── use-program-messages.ts
│       │   │   ├── use-program-referrals-count.ts
│       │   │   ├── use-program-resources.ts
│       │   │   ├── use-program.ts
│       │   │   ├── use-refresh-session.ts
│       │   │   ├── use-rewardful-campaigns.ts
│       │   │   ├── use-rewards.ts
│       │   │   ├── use-saml.ts
│       │   │   ├── use-scim.ts
│       │   │   ├── use-tags-count.ts
│       │   │   ├── use-tags.ts
│       │   │   ├── use-usage-timeseries.ts
│       │   │   ├── use-user.ts
│       │   │   ├── use-webhook.ts
│       │   │   ├── use-webhooks.ts
│       │   │   ├── use-workspace-preferences.ts
│       │   │   ├── use-workspace-store.ts
│       │   │   ├── use-workspace-users.ts
│       │   │   ├── use-workspace.ts
│       │   │   └── use-workspaces.ts
│       │   ├── tinybird/
│       │   │   ├── client.ts
│       │   │   ├── get-click-event.ts
│       │   │   ├── get-customer-events-tb.ts
│       │   │   ├── get-import-error-logs.ts
│       │   │   ├── get-lead-event.ts
│       │   │   ├── get-lead-events.ts
│       │   │   ├── get-top-links-by-countries.ts
│       │   │   ├── get-webhook-events.ts
│       │   │   ├── index.ts
│       │   │   ├── log-conversion-events.ts
│       │   │   ├── log-import-error.ts
│       │   │   ├── record-click-zod.ts
│       │   │   ├── record-click.ts
│       │   │   ├── record-fake-click.ts
│       │   │   ├── record-lead.ts
│       │   │   ├── record-link.ts
│       │   │   ├── record-sale.ts
│       │   │   └── record-webhook-event.ts
│       │   ├── tolt/
│       │   │   ├── api.ts
│       │   │   ├── cleanup-partners.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-links.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   ├── types.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── types.ts
│       │   ├── upstash/
│       │   │   ├── format-redis-link.ts
│       │   │   ├── index.ts
│       │   │   ├── ratelimit-policy.ts
│       │   │   ├── ratelimit.ts
│       │   │   ├── record-metatags.ts
│       │   │   ├── redis-streams.ts
│       │   │   ├── redis.ts
│       │   │   └── vector.ts
│       │   ├── webhook/
│       │   │   ├── cache.ts
│       │   │   ├── constants.ts
│       │   │   ├── create-webhook.ts
│       │   │   ├── failure.ts
│       │   │   ├── get-webhooks.ts
│       │   │   ├── handle-external-payout-event.ts
│       │   │   ├── publish.ts
│       │   │   ├── qstash.ts
│       │   │   ├── sample-events/
│       │   │   │   ├── bounty-created.json
│       │   │   │   ├── bounty-updated.json
│       │   │   │   ├── commission-created.json
│       │   │   │   ├── lead-created.json
│       │   │   │   ├── link-clicked.json
│       │   │   │   ├── link-created.json
│       │   │   │   ├── link-deleted.json
│       │   │   │   ├── link-updated.json
│       │   │   │   ├── partner-application-submitted.json
│       │   │   │   ├── partner-enrolled.json
│       │   │   │   ├── payload.ts
│       │   │   │   ├── payout-confirmed.json
│       │   │   │   └── sale-created.json
│       │   │   ├── schemas.ts
│       │   │   ├── secret.ts
│       │   │   ├── signature.ts
│       │   │   ├── transform.ts
│       │   │   ├── types.ts
│       │   │   ├── update-webhook.ts
│       │   │   ├── utils.ts
│       │   │   └── validate-webhook.ts
│       │   ├── well-known.ts
│       │   ├── workspace-roles.ts
│       │   └── zod/
│       │       └── schemas/
│       │           ├── activity-log.ts
│       │           ├── analytics-response.ts
│       │           ├── analytics.ts
│       │           ├── auth.ts
│       │           ├── bounties.ts
│       │           ├── campaigns.ts
│       │           ├── clicks.ts
│       │           ├── commissions.ts
│       │           ├── customer-activity.ts
│       │           ├── customers.ts
│       │           ├── dashboard.ts
│       │           ├── deep-links.ts
│       │           ├── deprecated.ts
│       │           ├── discount.ts
│       │           ├── domains.ts
│       │           ├── email-domains.ts
│       │           ├── folders.ts
│       │           ├── fraud.ts
│       │           ├── group-bounties.ts
│       │           ├── group-with-program.ts
│       │           ├── groups.ts
│       │           ├── import-csv.ts
│       │           ├── import-error-log.ts
│       │           ├── integration.ts
│       │           ├── invites.ts
│       │           ├── invoices.ts
│       │           ├── leads.ts
│       │           ├── links.ts
│       │           ├── messages.ts
│       │           ├── misc.ts
│       │           ├── oauth.ts
│       │           ├── opens.ts
│       │           ├── partner-network.ts
│       │           ├── partner-profile.ts
│       │           ├── partners.ts
│       │           ├── payouts.ts
│       │           ├── program-application-form.ts
│       │           ├── program-application.ts
│       │           ├── program-embed.ts
│       │           ├── program-invite-email.ts
│       │           ├── program-lander.ts
│       │           ├── program-network.ts
│       │           ├── program-onboarding.ts
│       │           ├── program-resources.ts
│       │           ├── programs.ts
│       │           ├── qr.ts
│       │           ├── referral-form.ts
│       │           ├── referrals-embed.ts
│       │           ├── referrals.ts
│       │           ├── rewards.ts
│       │           ├── sales.ts
│       │           ├── schemas.ts
│       │           ├── tags.ts
│       │           ├── token.ts
│       │           ├── usage.ts
│       │           ├── users.ts
│       │           ├── utils.ts
│       │           ├── utm.ts
│       │           ├── webhooks.ts
│       │           ├── workflows.ts
│       │           ├── workspace-preferences.ts
│       │           └── workspaces.ts
│       ├── middleware.ts
│       ├── next.config.js
│       ├── package.json
│       ├── playwright/
│       │   ├── README.md
│       │   ├── auth.setup.ts
│       │   ├── env.ts
│       │   ├── partner-login.spec.ts
│       │   ├── partner-onboarding.spec.ts
│       │   └── seed.ts
│       ├── playwright.config.ts
│       ├── postcss.config.js
│       ├── public/
│       │   └── .well-known/
│       │       └── security.txt
│       ├── scripts/
│       │   ├── analyze-bundle.ts
│       │   ├── analyze-domains.ts
│       │   ├── analyze-link-webhooks.ts
│       │   ├── analyze-top-utms.ts
│       │   ├── analyze-utm-usage.ts
│       │   ├── annature/
│       │   │   └── import-domains.ts
│       │   ├── buffer/
│       │   │   ├── delete-old-links.ts
│       │   │   └── migrate-to-case-sensitive.ts
│       │   ├── bulk-archive-links.ts
│       │   ├── bulk-create-domains.ts
│       │   ├── bulk-create-links.ts
│       │   ├── bulk-delete-links.ts
│       │   ├── bulk-update-links.ts
│       │   ├── cache-popular-urls.ts
│       │   ├── cal/
│       │   │   └── backfill-referral-links.ts
│       │   ├── check-customers.ts
│       │   ├── conversion-customers.ts
│       │   ├── convert-case-sensitive.ts
│       │   ├── convert-manual-commissions.ts
│       │   ├── create-integration.ts
│       │   ├── create-key.ts
│       │   ├── deactivate-programs.ts
│       │   ├── delete-link-cache.ts
│       │   ├── dev/
│       │   │   ├── data.json
│       │   │   └── seed.ts
│       │   ├── download-links.ts
│       │   ├── download-top-links.ts
│       │   ├── dub-domain-users.ts
│       │   ├── dub-partner-rewind.ts
│       │   ├── dub-sdk.ts
│       │   ├── dub-wrapped.ts
│       │   ├── find-link.ts
│       │   ├── find-workspaces-without-users.ts
│       │   ├── fix-broken-applications.ts
│       │   ├── fix-broken-link-tags.ts
│       │   ├── fix-broken-partner-users.ts
│       │   ├── fix-broken-root-domains.ts
│       │   ├── fix-broken-workspace-users.ts
│       │   ├── fix-usage-count.ts
│       │   ├── format-clicks.ts
│       │   ├── format-links.ts
│       │   ├── framer/
│       │   │   ├── 1-process-framer-combined.ts
│       │   │   ├── 2-sort-lead-events-by-date.ts
│       │   │   ├── 3-backfill-tb-events.ts
│       │   │   ├── backfill-commissions.ts
│       │   │   ├── check-pending-payout-totals.ts
│       │   │   ├── get-links-to-backfill.ts
│       │   │   ├── get-remaining-links-to-backfill.ts
│       │   │   ├── mark-commissions-paid.ts
│       │   │   ├── mark-commissions-pending.ts
│       │   │   ├── process-lead-events.ts
│       │   │   └── tally-commissions.ts
│       │   ├── generate-openapi.ts
│       │   ├── get-api-users.ts
│       │   ├── get-customers.ts
│       │   ├── get-inactive-users.ts
│       │   ├── get-premium-workspaces.ts
│       │   ├── get-top-domains-for-links.ts
│       │   ├── get-top-links-for-workspace.ts
│       │   ├── get-users-by-links.ts
│       │   ├── get-users-with-multiple-free-workspaces.ts
│       │   ├── get-users.ts
│       │   ├── get-workspaces-by-clicks.ts
│       │   ├── get-workspaces-by-links.ts
│       │   ├── hash-speed.ts
│       │   ├── lua-convert.ts
│       │   ├── migrate-commission-attributes.ts
│       │   ├── migrations/
│       │   │   ├── backfill-application-groupId.ts
│       │   │   ├── backfill-attribution.ts
│       │   │   ├── backfill-banned-partner-links.ts
│       │   │   ├── backfill-click-commissions.ts
│       │   │   ├── backfill-commissions-rewardId.ts
│       │   │   ├── backfill-cross-program-ban-fraud-events.ts
│       │   │   ├── backfill-customer-first-sale.ts
│       │   │   ├── backfill-customer-partner-ids.ts
│       │   │   ├── backfill-customer-sales.ts
│       │   │   ├── backfill-customer-subscription-cancellation.ts
│       │   │   ├── backfill-customers.ts
│       │   │   ├── backfill-dashboards.ts
│       │   │   ├── backfill-deepview.ts
│       │   │   ├── backfill-default-payout-method.ts
│       │   │   ├── backfill-default-program-ids.ts
│       │   │   ├── backfill-discoverableat.ts
│       │   │   ├── backfill-domain-logo.ts
│       │   │   ├── backfill-folders-limit.ts
│       │   │   ├── backfill-folders-usage.ts
│       │   │   ├── backfill-group-links-pgdl-acme.ts
│       │   │   ├── backfill-group-links-pgdl.ts
│       │   │   ├── backfill-group-links-settings.ts
│       │   │   ├── backfill-group-settings.ts
│       │   │   ├── backfill-invoice-paid-at.ts
│       │   │   ├── backfill-invoice-payment-method.ts
│       │   │   ├── backfill-invoice-prefixes.ts
│       │   │   ├── backfill-link-commissions.ts
│       │   │   ├── backfill-link-partner-group-ids.ts
│       │   │   ├── backfill-link-stats.ts
│       │   │   ├── backfill-link-webhooks.ts
│       │   │   ├── backfill-missing-lead-commissions.ts
│       │   │   ├── backfill-missing-sales.ts
│       │   │   ├── backfill-notification-email-columns.ts
│       │   │   ├── backfill-notification-email-deliveredat.ts
│       │   │   ├── backfill-notification-preferences.ts
│       │   │   ├── backfill-partner-groupid-logs.ts
│       │   │   ├── backfill-partner-groups-verify.ts
│       │   │   ├── backfill-partner-groups.ts
│       │   │   ├── backfill-partner-platforms.ts
│       │   │   ├── backfill-payout-initiated-at.ts
│       │   │   ├── backfill-payout-method-hash.ts
│       │   │   ├── backfill-payout-method.ts
│       │   │   ├── backfill-payout-mode.ts
│       │   │   ├── backfill-performance-bounty-submissions.ts
│       │   │   ├── backfill-plain-customers.ts
│       │   │   ├── backfill-program-categories.ts
│       │   │   ├── backfill-program-marketplace-descriptions.ts
│       │   │   ├── backfill-program-marketplace.ts
│       │   │   ├── backfill-referral-links.ts
│       │   │   ├── backfill-reward-activity-log.ts
│       │   │   ├── backfill-reward-modifier-ids.ts
│       │   │   ├── backfill-saml-sso.ts
│       │   │   ├── backfill-short-links.ts
│       │   │   ├── backfill-stripe-connect.ts
│       │   │   ├── backfill-submission-completedat.ts
│       │   │   ├── backfill-total-commissions.ts
│       │   │   ├── migrate-application-formdata.ts
│       │   │   ├── migrate-application-submissions.ts
│       │   │   ├── migrate-bounties-submission-requirements.ts
│       │   │   ├── migrate-campaign-message-to-markdown.ts
│       │   │   ├── migrate-discounts.ts
│       │   │   ├── migrate-domains.ts
│       │   │   ├── migrate-images.ts
│       │   │   ├── migrate-integrations.ts
│       │   │   ├── migrate-lander-data.ts
│       │   │   ├── migrate-links-to-workspaces.ts
│       │   │   ├── migrate-partner-links.ts
│       │   │   ├── migrate-partners-with-tenantids.ts
│       │   │   ├── migrate-reward-amounts.ts
│       │   │   ├── migrate-rewards-remainder.ts
│       │   │   ├── migrate-rewards.ts
│       │   │   ├── migrate-sales.ts
│       │   │   ├── migrate-workflow-triggers.ts
│       │   │   ├── remove-duplicate-notification-emails.ts
│       │   │   ├── restore-group-ids.ts
│       │   │   ├── sanitize-partner-platform.ts
│       │   │   ├── update-discoverable-partners.ts
│       │   │   └── update-payout-mode-to-internal.ts
│       │   ├── misc/
│       │   │   ├── cleanup-fraud-events.ts
│       │   │   ├── cleanup-generic-email-fraud-events.ts
│       │   │   ├── fraud-campaign-ids.ts
│       │   │   ├── remove-fraud-events.ts
│       │   │   ├── restore-link-analytics.ts
│       │   │   ├── restore-links.ts
│       │   │   ├── restore-program-enrollments.ts
│       │   │   └── restore-program-folders.ts
│       │   ├── move-links-to-folder.ts
│       │   ├── partners/
│       │   │   ├── aggregate-stats-seeding.ts
│       │   │   ├── check-pending-paypal-payouts.ts
│       │   │   ├── combine-payouts.ts
│       │   │   ├── delete-partner-profile.ts
│       │   │   ├── delete-partners-for-program.ts
│       │   │   ├── delete-program-application.ts
│       │   │   ├── delete-program-enrollment.ts
│       │   │   ├── delete-program.ts
│       │   │   ├── export-partners.ts
│       │   │   ├── fix-partner-groups.ts
│       │   │   ├── fix-partner-payouts.ts
│       │   │   ├── get-largest-programs.ts
│       │   │   ├── invalidate-partner-links.ts
│       │   │   ├── merge-partner-profile.ts
│       │   │   ├── update-links.ts
│       │   │   ├── update-partner-country.ts
│       │   │   └── update-payout-dates.ts
│       │   ├── perplexity/
│       │   │   ├── backfill-leads.ts
│       │   │   ├── backfill-tenantids.ts
│       │   │   ├── ban-partners.ts
│       │   │   ├── deactivate-partners.ts
│       │   │   ├── move-partners.ts
│       │   │   ├── partners-updated-countries.ts
│       │   │   ├── review-bounties.ts
│       │   │   ├── update-commissions.ts
│       │   │   └── update-notifications.ts
│       │   ├── persist-customer-avatars.ts
│       │   ├── processed-payouts.ts
│       │   ├── programs/
│       │   │   ├── 1-import-partners.ts
│       │   │   ├── 2-import-partner-links.ts
│       │   │   ├── 3-import-customer-leads.ts
│       │   │   ├── 4-export-stripe-invoices.ts
│       │   │   ├── 5-import-customer-sales.ts
│       │   │   ├── add-to-marketplace.ts
│       │   │   ├── backfill-custom-commissions.ts
│       │   │   ├── backfill-discount-codes.ts
│       │   │   ├── backfill-reuse-commission.ts
│       │   │   ├── delete-program-enrollments.ts
│       │   │   ├── update-commissions-canceled.ts
│       │   │   └── update-commissions-paid.ts
│       │   ├── referral-form-sample.json
│       │   ├── remove-workspace-scopes.ts
│       │   ├── restore-backup.ts
│       │   ├── revert-partner-payout-demo.ts
│       │   ├── reward-conditions.ts
│       │   ├── run.ts
│       │   ├── seed-invite-codes.ts
│       │   ├── seed-support-embeddings.ts
│       │   ├── send-batch-emails.ts
│       │   ├── sent-mail-reset.ts
│       │   ├── ship30/
│       │   │   └── backfill-leads.ts
│       │   ├── sitemap-importer.ts
│       │   ├── stripe/
│       │   │   ├── backfill-stripe-webhook-events.ts
│       │   │   ├── backfill-trace-id.ts
│       │   │   ├── connect-client.ts
│       │   │   ├── delete-connected-account.ts
│       │   │   ├── fix-processed-payouts.ts
│       │   │   ├── get-connected-customer.ts
│       │   │   ├── manual-payouts.ts
│       │   │   ├── retrieve-balance.ts
│       │   │   ├── search-customers.ts
│       │   │   ├── update-payouts-schedule.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── sync-conversions.ts
│       │   ├── sync-domain-clicks.ts
│       │   ├── sync-expired-links.ts
│       │   ├── sync-limits.ts
│       │   ├── sync-link-clicks.ts
│       │   ├── sync-link-tags.ts
│       │   ├── sync-links-metadata.ts
│       │   ├── sync-tag-analytics.ts
│       │   ├── tella/
│       │   │   ├── remind-applications.ts
│       │   │   ├── update-commission-flat.ts
│       │   │   ├── update-commission-percentage.ts
│       │   │   ├── update-commissions.ts
│       │   │   └── update-reward-tier.ts
│       │   ├── test-paypal-payouts.ts
│       │   ├── testimonial/
│       │   │   ├── final-sync-commissions.ts
│       │   │   ├── sync-commissions.ts
│       │   │   └── update-commissions.ts
│       │   ├── tinybird/
│       │   │   ├── delete-lead-event.ts
│       │   │   ├── delete-links.ts
│       │   │   ├── delete-sale-event.ts
│       │   │   ├── update-click-event.ts
│       │   │   ├── update-lead-event.ts
│       │   │   └── update-sale-event.ts
│       │   ├── trigger-update-partner-stats.ts
│       │   ├── unban-links.ts
│       │   ├── update-integrations.ts
│       │   ├── update-link-owner.ts
│       │   ├── update-not-found.ts
│       │   ├── update-payment-failed.ts
│       │   ├── update-payouts-limits.ts
│       │   ├── update-referral-form-data.ts
│       │   ├── update-spam-links.ts
│       │   ├── update-subscribers.ts
│       │   ├── update-user-notifications.ts
│       │   ├── update-webhook-cache.ts
│       │   ├── update-workspace-dates.ts
│       │   ├── update-workspace-tags.ts
│       │   ├── upload-users.ts
│       │   └── wispr-flow/
│       │       └── update-links.ts
│       ├── styles/
│       │   ├── fonts.ts
│       │   └── globals.css
│       ├── tailwind.config.ts
│       ├── tests/
│       │   ├── analytics/
│       │   │   ├── advanced-filter-helpers.test.ts
│       │   │   ├── get-analytics-advanced.test.ts
│       │   │   ├── get-analytics.test.ts
│       │   │   ├── get-events.test.ts
│       │   │   ├── metadata-query-parser.test.ts
│       │   │   ├── partner-analytics.test.ts
│       │   │   └── public-analytics-dashboard.test.ts
│       │   ├── bounties/
│       │   │   └── index.test.ts
│       │   ├── campaigns/
│       │   │   └── index.test.ts
│       │   ├── commissions/
│       │   │   ├── index.test.ts
│       │   │   └── pagination.test.ts
│       │   ├── customers/
│       │   │   ├── index.test.ts
│       │   │   └── pagination.test.ts
│       │   ├── discounts/
│       │   │   └── index.test.ts
│       │   ├── domains/
│       │   │   └── index.test.ts
│       │   ├── embed-tokens/
│       │   │   └── referrals.test.ts
│       │   ├── folders/
│       │   │   └── index.test.ts
│       │   ├── fraud/
│       │   │   ├── fraud-groups.test.ts
│       │   │   └── index.test.ts
│       │   ├── links/
│       │   │   ├── bulk-create-link.test.ts
│       │   │   ├── bulk-delete-link.test.ts
│       │   │   ├── bulk-update-link.test.ts
│       │   │   ├── count-links.test.ts
│       │   │   ├── create-link-error.test.ts
│       │   │   ├── create-link.test.ts
│       │   │   ├── delete-link.test.ts
│       │   │   ├── folder-link-access.test.ts
│       │   │   ├── list-links.test.ts
│       │   │   ├── retrieve-link.test.ts
│       │   │   ├── retrieve-metatags.test.ts
│       │   │   ├── update-link.test.ts
│       │   │   └── upsert-link.test.ts
│       │   ├── misc/
│       │   │   ├── allowed-hostnames.test.ts
│       │   │   ├── base64.test.ts
│       │   │   ├── calculate-payout-fee-with-waiver.test.ts
│       │   │   ├── case-sensitive-keys.test.ts
│       │   │   ├── check-eligibility-requirements.test.ts
│       │   │   ├── create-id.test.ts
│       │   │   ├── eligibility-condition-schema.test.ts
│       │   │   ├── email-domain-validation.test.ts
│       │   │   ├── filter-active-group-bounties.test.ts
│       │   │   ├── interpolate-email-template.test.ts
│       │   │   └── ip-cidr.test.ts
│       │   ├── partner-groups/
│       │   │   └── index.test.ts
│       │   ├── partners/
│       │   │   ├── analytics.test.ts
│       │   │   ├── ban-partner.test.ts
│       │   │   ├── create-partner-link.test.ts
│       │   │   ├── create-partner.test.ts
│       │   │   ├── deactivate-partner.test.ts
│       │   │   ├── list-partners.test.ts
│       │   │   ├── resource.ts
│       │   │   └── upsert-partner-link.test.ts
│       │   ├── payouts/
│       │   │   └── index.test.ts
│       │   ├── redirects/
│       │   │   └── index.test.ts
│       │   ├── rewards/
│       │   │   ├── click-reward.test.ts
│       │   │   ├── lead-reward.test.ts
│       │   │   ├── reward-conditions.test.ts
│       │   │   └── sale-reward.test.ts
│       │   ├── setupTests.ts
│       │   ├── tags/
│       │   │   ├── create-tag-error.test.ts
│       │   │   ├── create-tag.test.ts
│       │   │   └── list-tags.test.ts
│       │   ├── tracks/
│       │   │   ├── track-click.test.ts
│       │   │   ├── track-lead-client.test.ts
│       │   │   ├── track-lead.test.ts
│       │   │   ├── track-open.test.ts
│       │   │   ├── track-sale-client.test.ts
│       │   │   └── track-sale.test.ts
│       │   ├── utils/
│       │   │   ├── env.ts
│       │   │   ├── fetch-partner.ts
│       │   │   ├── helpers.ts
│       │   │   ├── http.ts
│       │   │   ├── integration-member.ts
│       │   │   ├── integration-old.ts
│       │   │   ├── integration.ts
│       │   │   ├── resource.ts
│       │   │   ├── schema.ts
│       │   │   └── verify-commission.ts
│       │   ├── webhooks/
│       │   │   └── index.test.ts
│       │   ├── workflows/
│       │   │   ├── award-bounty-workflow.test.ts
│       │   │   ├── e2e-endpoints-guard.test.ts
│       │   │   ├── move-group-workflow.test.ts
│       │   │   ├── send-campaign-workflow.test.ts
│       │   │   └── utils/
│       │   │       ├── delete-bounty-and-submissions.ts
│       │   │       ├── track-e2e-lead.ts
│       │   │       ├── verify-bounty-submission.ts
│       │   │       ├── verify-campaign-sent.ts
│       │   │       └── verify-partner-group-move.ts
│       │   └── workspaces/
│       │       ├── retrieve-workspace.error.test.ts
│       │       └── retrieve-workspace.test.ts
│       ├── tsconfig.json
│       ├── ui/
│       │   ├── account/
│       │   │   ├── delete-account.tsx
│       │   │   ├── update-default-workspace.tsx
│       │   │   ├── update-subscription.tsx
│       │   │   ├── upload-avatar.tsx
│       │   │   └── user-id.tsx
│       │   ├── activity-logs/
│       │   │   ├── action-renderers/
│       │   │   │   ├── partner-group-changed-renderer.tsx
│       │   │   │   ├── referral-created-renderer.tsx
│       │   │   │   ├── referral-status-changed-renderer.tsx
│       │   │   │   └── reward-activity-renderer.tsx
│       │   │   ├── activity-entry-chips.tsx
│       │   │   ├── activity-feed.tsx
│       │   │   ├── activity-log-context.tsx
│       │   │   ├── activity-log-description.tsx
│       │   │   ├── activity-log-registry.tsx
│       │   │   ├── partner-group-activity-item.tsx
│       │   │   ├── partner-group-activity-section.tsx
│       │   │   ├── partner-group-history-sheet.tsx
│       │   │   ├── partner-referral-activity-section.tsx
│       │   │   ├── referral-activity-item.tsx
│       │   │   ├── referral-activity-section.tsx
│       │   │   ├── reward-activity-item.tsx
│       │   │   ├── reward-activity-section.tsx
│       │   │   └── reward-history-sheet.tsx
│       │   ├── analytics/
│       │   │   ├── analytics-area-chart.tsx
│       │   │   ├── analytics-card.tsx
│       │   │   ├── analytics-export-button.tsx
│       │   │   ├── analytics-funnel-chart.tsx
│       │   │   ├── analytics-loading-spinner.tsx
│       │   │   ├── analytics-options.tsx
│       │   │   ├── analytics-provider.tsx
│       │   │   ├── analytics-tabs.tsx
│       │   │   ├── bar-list.tsx
│       │   │   ├── chart-section.tsx
│       │   │   ├── chart-view-switcher.tsx
│       │   │   ├── continent-icon.tsx
│       │   │   ├── device-icon.tsx
│       │   │   ├── device-section.tsx
│       │   │   ├── events/
│       │   │   │   ├── events-export-button.tsx
│       │   │   │   ├── events-provider.tsx
│       │   │   │   ├── events-table.tsx
│       │   │   │   ├── events-tabs.tsx
│       │   │   │   ├── example-data.ts
│       │   │   │   ├── index.tsx
│       │   │   │   ├── metadata-viewer.tsx
│       │   │   │   └── row-menu-button.tsx
│       │   │   ├── index.tsx
│       │   │   ├── link-preview.tsx
│       │   │   ├── location-section.tsx
│       │   │   ├── partner-section.tsx
│       │   │   ├── referrer-icon.tsx
│       │   │   ├── referrers-utms.tsx
│       │   │   ├── share-button.tsx
│       │   │   ├── toggle.tsx
│       │   │   ├── top-links.tsx
│       │   │   ├── trigger-display.tsx
│       │   │   ├── use-analytics-connected-status.ts
│       │   │   ├── use-analytics-filters.tsx
│       │   │   ├── use-analytics-query.tsx
│       │   │   └── utils.ts
│       │   ├── auth/
│       │   │   ├── auth-alternative-banner.tsx
│       │   │   ├── auth-methods-separator.tsx
│       │   │   ├── forgot-password-form.tsx
│       │   │   ├── login/
│       │   │   │   ├── email-sign-in.tsx
│       │   │   │   ├── framer-button.tsx
│       │   │   │   ├── github-button.tsx
│       │   │   │   ├── google-button.tsx
│       │   │   │   ├── login-form.tsx
│       │   │   │   └── sso-sign-in.tsx
│       │   │   ├── register/
│       │   │   │   ├── context.tsx
│       │   │   │   ├── resend-otp.tsx
│       │   │   │   ├── signup-email.tsx
│       │   │   │   ├── signup-form.tsx
│       │   │   │   ├── signup-oauth.tsx
│       │   │   │   └── verify-email-form.tsx
│       │   │   └── reset-password-form.tsx
│       │   ├── colors.ts
│       │   ├── customers/
│       │   │   ├── customer-activity-list.tsx
│       │   │   ├── customer-avatar.tsx
│       │   │   ├── customer-details-column.tsx
│       │   │   ├── customer-partner-earnings-table.tsx
│       │   │   ├── customer-row-item.tsx
│       │   │   ├── customer-sales-table.tsx
│       │   │   ├── customer-selector.tsx
│       │   │   ├── customer-stats.tsx
│       │   │   ├── customer-tabs.tsx
│       │   │   ├── customers-table/
│       │   │   │   ├── customers-table.tsx
│       │   │   │   ├── example-data.ts
│       │   │   │   └── use-customer-filters.tsx
│       │   │   └── export-customers-button.tsx
│       │   ├── domains/
│       │   │   ├── add-edit-domain-form.tsx
│       │   │   ├── domain-card-placeholder.tsx
│       │   │   ├── domain-card-title-column.tsx
│       │   │   ├── domain-card.tsx
│       │   │   ├── domain-configuration.tsx
│       │   │   ├── domain-selector.tsx
│       │   │   ├── free-dot-link-banner.tsx
│       │   │   └── register-domain-form.tsx
│       │   ├── dub-partners-logo.tsx
│       │   ├── folders/
│       │   │   ├── add-folder-form.tsx
│       │   │   ├── edit-folder-form.tsx
│       │   │   ├── edit-folder-sheet.tsx
│       │   │   ├── folder-actions.tsx
│       │   │   ├── folder-card-placeholder.tsx
│       │   │   ├── folder-card.tsx
│       │   │   ├── folder-dropdown.tsx
│       │   │   ├── folder-icon.tsx
│       │   │   ├── folder-info-panel.tsx
│       │   │   ├── move-link-form.tsx
│       │   │   ├── rename-folder-form.tsx
│       │   │   ├── request-edit-button.tsx
│       │   │   ├── simple-folder-card.tsx
│       │   │   └── utils.ts
│       │   ├── guides/
│       │   │   ├── guide-action-button.tsx
│       │   │   ├── guide-list.tsx
│       │   │   ├── guide-selector.tsx
│       │   │   ├── guide.tsx
│       │   │   ├── icons/
│       │   │   │   ├── appwrite.tsx
│       │   │   │   ├── auth-js.tsx
│       │   │   │   ├── auth0.tsx
│       │   │   │   ├── better-auth.tsx
│       │   │   │   ├── clerk.tsx
│       │   │   │   ├── code-editor.tsx
│       │   │   │   ├── custom.tsx
│       │   │   │   ├── framer.tsx
│       │   │   │   ├── gtm.tsx
│       │   │   │   ├── next-auth.tsx
│       │   │   │   ├── react.tsx
│       │   │   │   ├── segment.tsx
│       │   │   │   ├── shopify.tsx
│       │   │   │   ├── supabase.tsx
│       │   │   │   ├── webflow.tsx
│       │   │   │   └── wordpress.tsx
│       │   │   ├── install-stripe-integration-button.tsx
│       │   │   ├── integrations.ts
│       │   │   └── markdown.tsx
│       │   ├── integrations/
│       │   │   ├── integration-card.tsx
│       │   │   └── integration-logo.tsx
│       │   ├── layout/
│       │   │   ├── auth-layout.tsx
│       │   │   ├── changelog-popup.tsx
│       │   │   ├── layout-loader.tsx
│       │   │   ├── main-nav.tsx
│       │   │   ├── page-content/
│       │   │   │   ├── index.tsx
│       │   │   │   ├── nav-button.tsx
│       │   │   │   ├── page-content-header.tsx
│       │   │   │   ├── page-content-old.tsx
│       │   │   │   ├── page-content-with-side-panel.tsx
│       │   │   │   └── toggle-side-panel-button.tsx
│       │   │   ├── page-nav-tabs.tsx
│       │   │   ├── page-width-wrapper.tsx
│       │   │   ├── settings-layout.tsx
│       │   │   ├── sidebar/
│       │   │   │   ├── affiliate-program-popup.tsx
│       │   │   │   ├── app-sidebar-nav.tsx
│       │   │   │   ├── dub-partners-popup.tsx
│       │   │   │   ├── help-button.tsx
│       │   │   │   ├── icons/
│       │   │   │   │   ├── compass.tsx
│       │   │   │   │   ├── connected-dots4.tsx
│       │   │   │   │   ├── cursor-rays.tsx
│       │   │   │   │   ├── gear.tsx
│       │   │   │   │   ├── hyperlink.tsx
│       │   │   │   │   ├── lines-y.tsx
│       │   │   │   │   └── user.tsx
│       │   │   │   ├── news-rsc.tsx
│       │   │   │   ├── news.tsx
│       │   │   │   ├── partner-program-dropdown.tsx
│       │   │   │   ├── partners-sidebar-nav.tsx
│       │   │   │   ├── payout-stats.tsx
│       │   │   │   ├── program-help-support.tsx
│       │   │   │   ├── refer-button.tsx
│       │   │   │   ├── sidebar-nav.tsx
│       │   │   │   ├── sidebar-usage.tsx
│       │   │   │   ├── use-program-applications-count.tsx
│       │   │   │   ├── user-dropdown.tsx
│       │   │   │   ├── workspace-dropdown.tsx
│       │   │   │   └── year-in-review-card.tsx
│       │   │   ├── toolbar/
│       │   │   │   ├── onboarding/
│       │   │   │   │   └── onboarding-button.tsx
│       │   │   │   └── toolbar.tsx
│       │   │   ├── upgrade-banner.tsx
│       │   │   └── user-survey/
│       │   │       ├── index.tsx
│       │   │       └── survey-form.tsx
│       │   ├── links/
│       │   │   ├── archived-links-hint.tsx
│       │   │   ├── comments-badge.tsx
│       │   │   ├── destination-url-input.tsx
│       │   │   ├── disabled-link-tooltip.tsx
│       │   │   ├── link-analytics-badge.tsx
│       │   │   ├── link-builder/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── controls/
│       │   │   │   │   ├── link-builder-destination-url-input.tsx
│       │   │   │   │   ├── link-builder-folder-selector.tsx
│       │   │   │   │   ├── link-builder-short-link-input.tsx
│       │   │   │   │   └── link-comments-input.tsx
│       │   │   │   ├── conversion-tracking-toggle.tsx
│       │   │   │   ├── draft-controls.tsx
│       │   │   │   ├── link-action-bar.tsx
│       │   │   │   ├── link-builder-header.tsx
│       │   │   │   ├── link-builder-provider.tsx
│       │   │   │   ├── link-creator-info.tsx
│       │   │   │   ├── link-feature-buttons.tsx
│       │   │   │   ├── link-partner-details.tsx
│       │   │   │   ├── link-preview.tsx
│       │   │   │   ├── more-dropdown.tsx
│       │   │   │   ├── multi-tags-icon.tsx
│       │   │   │   ├── options-list.tsx
│       │   │   │   ├── qr-code-preview.tsx
│       │   │   │   ├── tag-select.tsx
│       │   │   │   ├── use-link-builder-keyboard-shortcut.ts
│       │   │   │   ├── use-link-builder-submit.tsx
│       │   │   │   ├── use-metatags.ts
│       │   │   │   └── utm-templates-button.tsx
│       │   │   ├── link-card-placeholder.tsx
│       │   │   ├── link-card.tsx
│       │   │   ├── link-controls.tsx
│       │   │   ├── link-details-column.tsx
│       │   │   ├── link-display.tsx
│       │   │   ├── link-icon.tsx
│       │   │   ├── link-not-found.tsx
│       │   │   ├── link-selection-provider.tsx
│       │   │   ├── link-sort.tsx
│       │   │   ├── link-tests.tsx
│       │   │   ├── link-title-column.tsx
│       │   │   ├── links-container.tsx
│       │   │   ├── links-display-provider.tsx
│       │   │   ├── links-toolbar.tsx
│       │   │   ├── short-link-input.tsx
│       │   │   ├── simple-link-card.tsx
│       │   │   ├── tag-badge.tsx
│       │   │   ├── tests-badge.tsx
│       │   │   ├── use-available-domains.ts
│       │   │   ├── use-folder-filter-options.ts
│       │   │   └── use-link-filters.tsx
│       │   ├── messages/
│       │   │   ├── message-markdown.tsx
│       │   │   ├── messages-context.tsx
│       │   │   ├── messages-list.tsx
│       │   │   ├── messages-panel.tsx
│       │   │   └── toggle-side-panel-button.tsx
│       │   ├── modals/
│       │   │   ├── add-customer-modal.tsx
│       │   │   ├── add-discount-code-modal.tsx
│       │   │   ├── add-edit-domain-modal.tsx
│       │   │   ├── add-edit-email-domain-modal.tsx
│       │   │   ├── add-edit-tag-modal.tsx
│       │   │   ├── add-edit-token-modal.tsx
│       │   │   ├── add-edit-utm-template.modal.tsx
│       │   │   ├── add-folder-modal.tsx
│       │   │   ├── add-partner-link-modal.tsx
│       │   │   ├── add-payment-method-modal.tsx
│       │   │   ├── add-workspace-modal.tsx
│       │   │   ├── application-settings-modal.tsx
│       │   │   ├── archive-domain-modal.tsx
│       │   │   ├── archive-link-modal.tsx
│       │   │   ├── archive-partner-modal.tsx
│       │   │   ├── ban-partner-modal.tsx
│       │   │   ├── bulk-approve-partners-modal.tsx
│       │   │   ├── bulk-archive-partners-modal.tsx
│       │   │   ├── bulk-ban-partners-modal.tsx
│       │   │   ├── bulk-deactivate-partners-modal.tsx
│       │   │   ├── bulk-reject-partners-modal.tsx
│       │   │   ├── bulk-resolve-fraud-groups-modal.tsx
│       │   │   ├── change-group-modal.tsx
│       │   │   ├── confirm-approve-bounty-submission-modal.tsx
│       │   │   ├── confirm-modal.tsx
│       │   │   ├── confirm-referral-status-change-modal.tsx
│       │   │   ├── confirm-set-default-group-modal.tsx
│       │   │   ├── deactivate-partner-modal.tsx
│       │   │   ├── delete-account-modal.tsx
│       │   │   ├── delete-discount-code-modal.tsx
│       │   │   ├── delete-domain-modal.tsx
│       │   │   ├── delete-email-domain-modal.tsx
│       │   │   ├── delete-folder-modal.tsx
│       │   │   ├── delete-group-modal.tsx
│       │   │   ├── delete-link-modal.tsx
│       │   │   ├── delete-partner-link-modal.tsx
│       │   │   ├── delete-token-modal.tsx
│       │   │   ├── delete-webhook-modal.tsx
│       │   │   ├── delete-workspace-modal.tsx
│       │   │   ├── disable-fraud-rules-modal.tsx
│       │   │   ├── domain-auto-renewal-modal.tsx
│       │   │   ├── domain-verification-modal.tsx
│       │   │   ├── dot-link-offer-modal.tsx
│       │   │   ├── edit-customer-modal.tsx
│       │   │   ├── edit-referral-modal.tsx
│       │   │   ├── export-applications-modal.tsx
│       │   │   ├── export-commissions-modal.tsx
│       │   │   ├── export-customers-modal.tsx
│       │   │   ├── export-links-modal.tsx
│       │   │   ├── export-partners-modal.tsx
│       │   │   ├── google-oauth-modal.tsx
│       │   │   ├── import-bitly-modal.tsx
│       │   │   ├── import-csv-modal/
│       │   │   │   ├── field-mapping.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   └── select-file.tsx
│       │   │   ├── import-firstpromoter-modal.tsx
│       │   │   ├── import-partnerstack-modal.tsx
│       │   │   ├── import-rebrandly-modal.tsx
│       │   │   ├── import-rewardful-modal.tsx
│       │   │   ├── import-short-modal.tsx
│       │   │   ├── import-tolt-modal.tsx
│       │   │   ├── invite-code-modal.tsx
│       │   │   ├── invite-partner-user-modal.tsx
│       │   │   ├── invite-referral-modal.tsx
│       │   │   ├── invite-workspace-user-modal.tsx
│       │   │   ├── link-builder/
│       │   │   │   ├── ab-testing/
│       │   │   │   │   ├── ab-testing-modal.tsx
│       │   │   │   │   ├── end-ab-testing-modal.tsx
│       │   │   │   │   └── traffic-split-slider.tsx
│       │   │   │   ├── ab-testing-modal.tsx
│       │   │   │   ├── advanced-modal.tsx
│       │   │   │   ├── expiration-modal.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   ├── og-modal.tsx
│       │   │   │   ├── partners-modal.tsx
│       │   │   │   ├── password-modal.tsx
│       │   │   │   ├── targeting-modal.tsx
│       │   │   │   ├── unsplash-search.tsx
│       │   │   │   ├── use-link-drafts.ts
│       │   │   │   ├── utm-modal.tsx
│       │   │   │   ├── utm-templates-combo.tsx
│       │   │   │   └── webhooks-modal.tsx
│       │   │   ├── link-conversion-tracking-modal.tsx
│       │   │   ├── link-qr-modal.tsx
│       │   │   ├── manage-usage-modal.tsx
│       │   │   ├── modal-provider.tsx
│       │   │   ├── move-link-to-folder-modal.tsx
│       │   │   ├── oauth-app-created-modal.tsx
│       │   │   ├── partner-link-modal.tsx
│       │   │   ├── partner-link-qr-modal.tsx
│       │   │   ├── plan-change-confirmation-modal.tsx
│       │   │   ├── primary-domain-modal.tsx
│       │   │   ├── program-welcome-modal.tsx
│       │   │   ├── prompt-modal.tsx
│       │   │   ├── reactivate-partner-modal.tsx
│       │   │   ├── register-domain-modal.tsx
│       │   │   ├── register-domain-success-modal.tsx
│       │   │   ├── reject-partner-application-modal.tsx
│       │   │   ├── remove-oauth-app-modal.tsx
│       │   │   ├── remove-partner-user-modal.tsx
│       │   │   ├── remove-saml-modal.tsx
│       │   │   ├── remove-scim-modal.tsx
│       │   │   ├── remove-workspace-user-modal.tsx
│       │   │   ├── rename-folder-modal.tsx
│       │   │   ├── saml-modal.tsx
│       │   │   ├── scim-modal.tsx
│       │   │   ├── send-test-webhook-modal.tsx
│       │   │   ├── set-default-folder-modal.tsx
│       │   │   ├── share-dashboard-modal.tsx
│       │   │   ├── social-verification-by-code-modal.tsx
│       │   │   ├── submit-oauth-app-modal.tsx
│       │   │   ├── tag-link-modal.tsx
│       │   │   ├── token-created-modal.tsx
│       │   │   ├── transfer-domain-modal.tsx
│       │   │   ├── transfer-link-modal.tsx
│       │   │   ├── unban-partner-modal.tsx
│       │   │   ├── uninstall-integration-modal.tsx
│       │   │   ├── update-partner-user-modal.tsx
│       │   │   ├── update-workspace-user-role.tsx
│       │   │   └── upgraded-modal.tsx
│       │   ├── oauth-apps/
│       │   │   ├── add-edit-app-form.tsx
│       │   │   ├── add-edit-integration-form.tsx
│       │   │   ├── oauth-app-card.tsx
│       │   │   ├── oauth-app-credentials.tsx
│       │   │   └── oauth-app-placeholder.tsx
│       │   ├── partners/
│       │   │   ├── activity-event.tsx
│       │   │   ├── bounties/
│       │   │   │   ├── bounty-description.tsx
│       │   │   │   ├── bounty-incremental-bonus-tooltip.tsx
│       │   │   │   ├── bounty-performance.tsx
│       │   │   │   ├── bounty-platform-icons.ts
│       │   │   │   ├── bounty-progress-bar-row.tsx
│       │   │   │   ├── bounty-reward-criteria.tsx
│       │   │   │   ├── bounty-reward-description.tsx
│       │   │   │   ├── bounty-social-content-preview.tsx
│       │   │   │   ├── bounty-social-content.tsx
│       │   │   │   ├── bounty-social-metrics-rewards-table.tsx
│       │   │   │   ├── bounty-status-badge.tsx
│       │   │   │   ├── bounty-submission-details-sheet.tsx
│       │   │   │   ├── bounty-submission-requirements.tsx
│       │   │   │   ├── bounty-thumbnail-image.tsx
│       │   │   │   ├── claim-bounty-context.tsx
│       │   │   │   ├── claim-bounty-sheet.tsx
│       │   │   │   ├── reject-bounty-submission-modal.tsx
│       │   │   │   ├── use-claim-bounty-form.ts
│       │   │   │   └── use-social-content.ts
│       │   │   ├── comission-type-icon.tsx
│       │   │   ├── commission-row-menu.tsx
│       │   │   ├── commission-status-badges.tsx
│       │   │   ├── commission-type-badge.tsx
│       │   │   ├── confirm-payouts-sheet.tsx
│       │   │   ├── constants.ts
│       │   │   ├── conversion-score-icon.tsx
│       │   │   ├── country-combobox.tsx
│       │   │   ├── discounts/
│       │   │   │   ├── add-edit-discount-sheet.tsx
│       │   │   │   └── discount-code-badge.tsx
│       │   │   ├── eligibility-requirements.tsx
│       │   │   ├── external-payouts-indicator.tsx
│       │   │   ├── format-discount-description.ts
│       │   │   ├── format-reward-description.ts
│       │   │   ├── fraud-risks/
│       │   │   │   ├── commissions-on-hold-table.tsx
│       │   │   │   ├── fraud-disclaimer-banner.tsx
│       │   │   │   ├── fraud-events-tables/
│       │   │   │   │   ├── fraud-cross-program-ban-table.tsx
│       │   │   │   │   ├── fraud-matching-customer-email-table.tsx
│       │   │   │   │   ├── fraud-paid-traffic-detected-table.tsx
│       │   │   │   │   ├── fraud-partner-info-table.tsx
│       │   │   │   │   ├── fraud-referral-source-banned-table.tsx
│       │   │   │   │   └── index.tsx
│       │   │   │   ├── fraud-review-sheet.tsx
│       │   │   │   ├── partner-application-fraud-severity-indicator.tsx
│       │   │   │   ├── partner-application-risk-summary-modal.tsx
│       │   │   │   ├── partner-application-risk-summary.tsx
│       │   │   │   ├── partner-cross-program-summary.tsx
│       │   │   │   ├── partner-fraud-banner.tsx
│       │   │   │   ├── partner-fraud-indicator.tsx
│       │   │   │   ├── resolve-fraud-group-modal.tsx
│       │   │   │   └── resolved-fraud-group-table.tsx
│       │   │   ├── groups/
│       │   │   │   ├── design/
│       │   │   │   │   ├── application-form/
│       │   │   │   │   │   ├── application-hero-preview.tsx
│       │   │   │   │   │   ├── fields/
│       │   │   │   │   │   │   ├── form-control.tsx
│       │   │   │   │   │   │   ├── image-upload-field.tsx
│       │   │   │   │   │   │   ├── index.tsx
│       │   │   │   │   │   │   ├── long-text-field.tsx
│       │   │   │   │   │   │   ├── max-character-count.tsx
│       │   │   │   │   │   │   ├── multiple-choice-field.tsx
│       │   │   │   │   │   │   ├── select-field.tsx
│       │   │   │   │   │   │   ├── short-text-field.tsx
│       │   │   │   │   │   │   └── website-and-socials-field.tsx
│       │   │   │   │   │   ├── form-data-for-application-form-data.ts
│       │   │   │   │   │   ├── modals/
│       │   │   │   │   │   │   ├── add-field-modal.tsx
│       │   │   │   │   │   │   ├── edit-application-hero-modal.tsx
│       │   │   │   │   │   │   ├── generate-lander-modal.tsx
│       │   │   │   │   │   │   ├── image-upload-field-modal.tsx
│       │   │   │   │   │   │   ├── long-text-field-modal.tsx
│       │   │   │   │   │   │   ├── multiple-choice-field-modal.tsx
│       │   │   │   │   │   │   ├── select-field-modal.tsx
│       │   │   │   │   │   │   ├── short-text-field-modal.tsx
│       │   │   │   │   │   │   └── website-and-socials-field-modal.tsx
│       │   │   │   │   │   ├── program-application-form.tsx
│       │   │   │   │   │   ├── program-terms-preview.tsx
│       │   │   │   │   │   └── required-fields-preview.tsx
│       │   │   │   │   ├── branding-context-provider.tsx
│       │   │   │   │   ├── branding-form.tsx
│       │   │   │   │   ├── branding-settings-form.tsx
│       │   │   │   │   ├── edit-list.tsx
│       │   │   │   │   ├── lander/
│       │   │   │   │   │   ├── lander-ai-banner.tsx
│       │   │   │   │   │   ├── lander-preview-controls.tsx
│       │   │   │   │   │   └── modals/
│       │   │   │   │   │       ├── accordion-block-modal.tsx
│       │   │   │   │   │       ├── add-block-modal.tsx
│       │   │   │   │   │       ├── earnings-calculator-block-modal.tsx
│       │   │   │   │   │       ├── edit-hero-modal.tsx
│       │   │   │   │   │       ├── files-block-modal.tsx
│       │   │   │   │   │       ├── generate-lander-modal.tsx
│       │   │   │   │   │       ├── image-block-modal.tsx
│       │   │   │   │   │       └── text-block-modal.tsx
│       │   │   │   │   ├── preview-window.tsx
│       │   │   │   │   ├── previews/
│       │   │   │   │   │   ├── application-preview.tsx
│       │   │   │   │   │   ├── embed-preview.tsx
│       │   │   │   │   │   ├── lander-preview.tsx
│       │   │   │   │   │   └── portal-preview.tsx
│       │   │   │   │   └── studs-pattern.tsx
│       │   │   │   ├── group-color-circle.tsx
│       │   │   │   ├── group-color-picker.tsx
│       │   │   │   ├── group-selector.tsx
│       │   │   │   ├── group-settings-row.tsx
│       │   │   │   ├── groups-multi-select.tsx
│       │   │   │   └── reward-discount-partners-card.tsx
│       │   │   ├── hero-background.tsx
│       │   │   ├── lander/
│       │   │   │   ├── blocks/
│       │   │   │   │   ├── accordion-block.tsx
│       │   │   │   │   ├── block-description.tsx
│       │   │   │   │   ├── block-markdown.tsx
│       │   │   │   │   ├── block-title.tsx
│       │   │   │   │   ├── earnings-calculator-block.tsx
│       │   │   │   │   ├── files-block.tsx
│       │   │   │   │   ├── image-block.tsx
│       │   │   │   │   ├── index.tsx
│       │   │   │   │   ├── text-block.tsx
│       │   │   │   │   └── wave-pattern.tsx
│       │   │   │   ├── lander-hero.tsx
│       │   │   │   └── lander-rewards.tsx
│       │   │   ├── mark-commission-duplicate-modal.tsx
│       │   │   ├── mark-commission-fraud-or-canceled-modal.tsx
│       │   │   ├── merge-accounts/
│       │   │   │   ├── account-input-group.tsx
│       │   │   │   ├── form-context.tsx
│       │   │   │   ├── merge-account-form.tsx
│       │   │   │   ├── merge-partner-accounts-modal.tsx
│       │   │   │   ├── otp-input-field.tsx
│       │   │   │   ├── send-verification-code-form.tsx
│       │   │   │   ├── step-progress-bar.tsx
│       │   │   │   └── verify-code-form.tsx
│       │   │   ├── overview/
│       │   │   │   ├── blocks/
│       │   │   │   │   ├── commissions-block.tsx
│       │   │   │   │   ├── conversion-block.tsx
│       │   │   │   │   ├── countries-block.tsx
│       │   │   │   │   ├── links-block.tsx
│       │   │   │   │   ├── partners-block.tsx
│       │   │   │   │   ├── sale-type-block.tsx
│       │   │   │   │   └── traffic-sources-block.tsx
│       │   │   │   ├── exceeded-events-limit.tsx
│       │   │   │   ├── program-overview-block.tsx
│       │   │   │   └── program-overview-card.tsx
│       │   │   ├── partner-about.tsx
│       │   │   ├── partner-advanced-settings-modal.tsx
│       │   │   ├── partner-application-details.tsx
│       │   │   ├── partner-application-sheet.tsx
│       │   │   ├── partner-avatar.tsx
│       │   │   ├── partner-comments.tsx
│       │   │   ├── partner-info-cards.tsx
│       │   │   ├── partner-info-group.tsx
│       │   │   ├── partner-info-section.tsx
│       │   │   ├── partner-info-stats.tsx
│       │   │   ├── partner-link-selector.tsx
│       │   │   ├── partner-network/
│       │   │   │   ├── conversion-score-tooltip.tsx
│       │   │   │   ├── invites-usage.tsx
│       │   │   │   └── network-partner-sheet.tsx
│       │   │   ├── partner-platform-card.tsx
│       │   │   ├── partner-platform-summary.tsx
│       │   │   ├── partner-platforms-form.tsx
│       │   │   ├── partner-profile-sheet.tsx
│       │   │   ├── partner-row-item.tsx
│       │   │   ├── partner-selector.tsx
│       │   │   ├── partner-sheet-tabs.tsx
│       │   │   ├── partner-social-column.tsx
│       │   │   ├── partner-star-button.tsx
│       │   │   ├── partner-status-badge-with-tooltip.tsx
│       │   │   ├── partner-status-badges.ts
│       │   │   ├── partners-upgrade-modal.tsx
│       │   │   ├── payout-row-menu.tsx
│       │   │   ├── payout-status-badge-partner.tsx
│       │   │   ├── payout-status-badges.tsx
│       │   │   ├── payout-status-descriptions.ts
│       │   │   ├── payouts/
│       │   │   │   ├── bank-account-requirements-modal.tsx
│       │   │   │   ├── connect-payout-button.tsx
│       │   │   │   ├── connect-payout-modal.tsx
│       │   │   │   ├── payout-method-cards.tsx
│       │   │   │   ├── payout-method-config.ts
│       │   │   │   ├── payout-method-dropdown.tsx
│       │   │   │   ├── stablecoin-payout-banner.tsx
│       │   │   │   ├── stablecoin-payout-card.tsx
│       │   │   │   ├── stablecoin-payout-icon.tsx
│       │   │   │   ├── stablecoin-payout-modal.tsx
│       │   │   │   ├── use-payout-connect-flow.tsx
│       │   │   │   └── use-stablecoin-payout-promo.tsx
│       │   │   ├── program-application-sheet.tsx
│       │   │   ├── program-card.tsx
│       │   │   ├── program-category-select.tsx
│       │   │   ├── program-color-picker.tsx
│       │   │   ├── program-eligibility-card.tsx
│       │   │   ├── program-help-links.tsx
│       │   │   ├── program-invite-card.tsx
│       │   │   ├── program-link-configuration.tsx
│       │   │   ├── program-marketplace/
│       │   │   │   ├── program-category.tsx
│       │   │   │   ├── program-marketplace-banner.tsx
│       │   │   │   ├── program-marketplace-card.tsx
│       │   │   │   ├── program-marketplace-logos.tsx
│       │   │   │   ├── program-reward-icon.tsx
│       │   │   │   ├── program-rewards-display.tsx
│       │   │   │   ├── programs-promo-banner.tsx
│       │   │   │   ├── programs-promo-card.tsx
│       │   │   │   └── use-program-marketplace-promo.tsx
│       │   │   ├── program-onboarding-form-wrapper.tsx
│       │   │   ├── program-reward-description.tsx
│       │   │   ├── program-reward-list.tsx
│       │   │   ├── program-reward-modifiers-tooltip.tsx
│       │   │   ├── program-reward-terms.tsx
│       │   │   ├── program-rewards-panel.tsx
│       │   │   ├── program-selector.tsx
│       │   │   ├── program-sheet-accordion.tsx
│       │   │   ├── program-stats-filter.tsx
│       │   │   ├── resources/
│       │   │   │   ├── resource-card.tsx
│       │   │   │   └── resource-section.tsx
│       │   │   ├── rewards/
│       │   │   │   ├── add-edit-reward-sheet.tsx
│       │   │   │   ├── reward-icon-square.tsx
│       │   │   │   ├── reward-preview-card.tsx
│       │   │   │   └── rewards-logic.tsx
│       │   │   ├── rewind/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── partner-rewind-banner.tsx
│       │   │   │   ├── partner-rewind-card.tsx
│       │   │   │   └── use-partner-rewind-status.tsx
│       │   │   ├── trusted-partner-badge.tsx
│       │   │   └── use-country-change-warning-modal.tsx
│       │   ├── placeholders/
│       │   │   ├── bubble-icon.tsx
│       │   │   ├── button-link.tsx
│       │   │   ├── cta.tsx
│       │   │   ├── feature-graphics/
│       │   │   │   ├── analytics.tsx
│       │   │   │   ├── collaboration.tsx
│       │   │   │   ├── domains.tsx
│       │   │   │   ├── personalization.tsx
│       │   │   │   └── qr.tsx
│       │   │   ├── features-section.tsx
│       │   │   ├── hero.tsx
│       │   │   └── logos.tsx
│       │   ├── postbacks/
│       │   │   ├── add-edit-postback-modal.tsx
│       │   │   ├── partner-postback-actions.tsx
│       │   │   ├── postback-card.tsx
│       │   │   ├── postback-detail-skeleton.tsx
│       │   │   ├── postback-event-details-sheet.tsx
│       │   │   ├── postback-event-list-skeleton.tsx
│       │   │   ├── postback-event-list.tsx
│       │   │   ├── postback-placeholder.tsx
│       │   │   ├── postback-secret-modal.tsx
│       │   │   ├── postback-status.tsx
│       │   │   └── send-test-postback-modal.tsx
│       │   ├── referrals/
│       │   │   ├── form-fields/
│       │   │   │   ├── country-field.tsx
│       │   │   │   ├── date-field.tsx
│       │   │   │   ├── form-control.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   ├── max-character-count.tsx
│       │   │   │   ├── multi-select-field.tsx
│       │   │   │   ├── number-field.tsx
│       │   │   │   ├── phone-field.tsx
│       │   │   │   ├── select-field.tsx
│       │   │   │   ├── text-field.tsx
│       │   │   │   └── textarea-field.tsx
│       │   │   ├── partner-profile-referral-sheet.tsx
│       │   │   ├── partner-profile-referrals-empty-state.tsx
│       │   │   ├── partner-referral-sheet.tsx
│       │   │   ├── partner-referral-table.tsx
│       │   │   ├── referral-details.tsx
│       │   │   ├── referral-form.tsx
│       │   │   ├── referral-lead-details.tsx
│       │   │   ├── referral-partner-details.tsx
│       │   │   ├── referral-status-badge.tsx
│       │   │   ├── referral-status-badges.ts
│       │   │   ├── referral-status-dropdown.tsx
│       │   │   ├── referral-utils.ts
│       │   │   ├── submit-referral-sheet.tsx
│       │   │   └── use-program-referral-filters.tsx
│       │   ├── shared/
│       │   │   ├── amount-input.tsx
│       │   │   ├── animated-empty-state.tsx
│       │   │   ├── back-link.tsx
│       │   │   ├── business-badge-tooltip.tsx
│       │   │   ├── conditional-link.tsx
│       │   │   ├── custom-toast.tsx
│       │   │   ├── emoji-picker.tsx
│       │   │   ├── empty-state.tsx
│       │   │   ├── filter-button-table-row.tsx
│       │   │   ├── icons/
│       │   │   │   ├── airplay.tsx
│       │   │   │   ├── alert-circle-fill.tsx
│       │   │   │   ├── chart.tsx
│       │   │   │   ├── check-circle-fill.tsx
│       │   │   │   ├── clipboard.tsx
│       │   │   │   ├── delete.tsx
│       │   │   │   ├── devices.tsx
│       │   │   │   ├── divider.tsx
│       │   │   │   ├── download.tsx
│       │   │   │   ├── drag.tsx
│       │   │   │   ├── edit.tsx
│       │   │   │   ├── external-link.tsx
│       │   │   │   ├── eye-off.tsx
│       │   │   │   ├── eye.tsx
│       │   │   │   ├── filter.tsx
│       │   │   │   ├── heart.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   ├── infinity.tsx
│       │   │   │   ├── link.tsx
│       │   │   │   ├── lock.tsx
│       │   │   │   ├── logout.tsx
│       │   │   │   ├── message.tsx
│       │   │   │   ├── qr.tsx
│       │   │   │   ├── random.tsx
│       │   │   │   ├── repeat.tsx
│       │   │   │   ├── save.tsx
│       │   │   │   ├── search.tsx
│       │   │   │   ├── sort.tsx
│       │   │   │   ├── three-dots.tsx
│       │   │   │   ├── upload-cloud.tsx
│       │   │   │   ├── users.tsx
│       │   │   │   ├── x-circle-fill.tsx
│       │   │   │   └── x.tsx
│       │   │   ├── inline-badge-popover.tsx
│       │   │   ├── markdown-description.tsx
│       │   │   ├── markdown.tsx
│       │   │   ├── max-characters-counter.tsx
│       │   │   ├── message-input.tsx
│       │   │   ├── modal-hero.tsx
│       │   │   ├── new-background.tsx
│       │   │   ├── password-requirements.tsx
│       │   │   ├── pro-badge-tooltip.tsx
│       │   │   ├── qr-code.tsx
│       │   │   ├── search-box.tsx
│       │   │   ├── simple-date-range-picker.tsx
│       │   │   ├── simple-empty-state.tsx
│       │   │   ├── upgrade-required-toast.tsx
│       │   │   └── zoom-image.tsx
│       │   ├── support/
│       │   │   ├── chat-bubble.tsx
│       │   │   ├── chat-interface.tsx
│       │   │   ├── clear-chat-button.tsx
│       │   │   ├── code-block.tsx
│       │   │   ├── embedded-chat.tsx
│       │   │   ├── message.tsx
│       │   │   ├── program-combobox.tsx
│       │   │   ├── source-citations.tsx
│       │   │   ├── starter-questions.tsx
│       │   │   ├── status-indicator.tsx
│       │   │   ├── ticket-upload.tsx
│       │   │   ├── types.ts
│       │   │   └── workspace-combobox.tsx
│       │   ├── token-avatar.tsx
│       │   ├── users/
│       │   │   ├── user-avatar.tsx
│       │   │   └── user-row-item.tsx
│       │   ├── webhooks/
│       │   │   ├── add-edit-webhook-form.tsx
│       │   │   ├── link-selector.tsx
│       │   │   ├── loading-events-skelton.tsx
│       │   │   ├── no-events-placeholder.tsx
│       │   │   ├── webhook-card.tsx
│       │   │   ├── webhook-event-details-sheet.tsx
│       │   │   ├── webhook-event-list.tsx
│       │   │   ├── webhook-header.tsx
│       │   │   ├── webhook-placeholder.tsx
│       │   │   └── webhook-status.tsx
│       │   └── workspaces/
│       │       ├── create-workspace-button.tsx
│       │       ├── create-workspace-form.tsx
│       │       ├── delete-workspace.tsx
│       │       ├── invite-teammates-form.tsx
│       │       ├── manage-subscription-button.tsx
│       │       ├── plan-badge.tsx
│       │       ├── plan-features.tsx
│       │       ├── subscription-menu.tsx
│       │       ├── upgrade-plan-button.tsx
│       │       ├── upload-logo.tsx
│       │       ├── workspace-arrow.tsx
│       │       ├── workspace-exceeded-events.tsx
│       │       └── workspace-selector.tsx
│       ├── vercel.json
│       └── vitest.config.ts
├── package.json
├── packages/
│   ├── cli/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── api/
│   │   │   │   ├── callback.ts
│   │   │   │   ├── domains.ts
│   │   │   │   └── links.ts
│   │   │   ├── commands/
│   │   │   │   ├── config.ts
│   │   │   │   ├── domains.ts
│   │   │   │   ├── links.ts
│   │   │   │   ├── login.ts
│   │   │   │   └── shorten.ts
│   │   │   ├── index.ts
│   │   │   ├── types/
│   │   │   │   └── index.ts
│   │   │   └── utils/
│   │   │       ├── config.ts
│   │   │       ├── get-nanoid.ts
│   │   │       ├── get-package-info.ts
│   │   │       ├── handle-error.ts
│   │   │       ├── logger.ts
│   │   │       ├── oauth.ts
│   │   │       └── parser.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── email/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── bounty-thumbnail.tsx
│   │   │   │   └── footer.tsx
│   │   │   ├── index.ts
│   │   │   ├── react-email.d.ts
│   │   │   ├── resend/
│   │   │   │   ├── client.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── send-via-nodemailer.ts
│   │   │   ├── send-via-resend.ts
│   │   │   ├── templates/
│   │   │   │   ├── api-key-created.tsx
│   │   │   │   ├── bounty-approved.tsx
│   │   │   │   ├── bounty-completed.tsx
│   │   │   │   ├── bounty-new-submission.tsx
│   │   │   │   ├── bounty-rejected.tsx
│   │   │   │   ├── bounty-submitted.tsx
│   │   │   │   ├── broadcasts/
│   │   │   │   │   ├── dub-product-update-mar26.tsx
│   │   │   │   │   ├── dub-wrapped.tsx
│   │   │   │   │   ├── payout-auto-withdrawals.tsx
│   │   │   │   │   ├── program-marketplace-announcement.tsx
│   │   │   │   │   └── stablecoin-payouts-announcement.tsx
│   │   │   │   ├── campaign-email.tsx
│   │   │   │   ├── clicks-exceeded.tsx
│   │   │   │   ├── clicks-summary.tsx
│   │   │   │   ├── confirm-email-change.tsx
│   │   │   │   ├── connect-payout-reminder.tsx
│   │   │   │   ├── connect-platforms-reminder.tsx
│   │   │   │   ├── connected-payout-method.tsx
│   │   │   │   ├── connected-paypal-account.tsx
│   │   │   │   ├── discount-deleted.tsx
│   │   │   │   ├── domain-claimed.tsx
│   │   │   │   ├── domain-deleted.tsx
│   │   │   │   ├── domain-expired.tsx
│   │   │   │   ├── domain-renewal-failed.tsx
│   │   │   │   ├── domain-renewal-reminder.tsx
│   │   │   │   ├── domain-renewed.tsx
│   │   │   │   ├── domain-transferred.tsx
│   │   │   │   ├── dub-partner-rewind.tsx
│   │   │   │   ├── duplicate-payout-method.tsx
│   │   │   │   ├── email-domain-status-changed.tsx
│   │   │   │   ├── email-updated.tsx
│   │   │   │   ├── export-ready.tsx
│   │   │   │   ├── failed-payment.tsx
│   │   │   │   ├── feedback-email.tsx
│   │   │   │   ├── folder-edit-access-requested.tsx
│   │   │   │   ├── integration-installed.tsx
│   │   │   │   ├── invalid-domain.tsx
│   │   │   │   ├── links-import-errors.tsx
│   │   │   │   ├── links-imported.tsx
│   │   │   │   ├── links-limit.tsx
│   │   │   │   ├── login-link.tsx
│   │   │   │   ├── new-bounty-available.tsx
│   │   │   │   ├── new-commission-alert-partner.tsx
│   │   │   │   ├── new-message-from-partner.tsx
│   │   │   │   ├── new-message-from-program.tsx
│   │   │   │   ├── new-referral-signup.tsx
│   │   │   │   ├── new-sale-alert-program-owner.tsx
│   │   │   │   ├── notify-partner-reapply.tsx
│   │   │   │   ├── partner-account-merged.tsx
│   │   │   │   ├── partner-application-approved.tsx
│   │   │   │   ├── partner-application-received.tsx
│   │   │   │   ├── partner-application-rejected.tsx
│   │   │   │   ├── partner-banned.tsx
│   │   │   │   ├── partner-deactivated.tsx
│   │   │   │   ├── partner-group-changed.tsx
│   │   │   │   ├── partner-payout-confirmed.tsx
│   │   │   │   ├── partner-payout-failed.tsx
│   │   │   │   ├── partner-payout-force-withdrawal.tsx
│   │   │   │   ├── partner-payout-processed.tsx
│   │   │   │   ├── partner-payout-withdrawal-completed.tsx
│   │   │   │   ├── partner-payout-withdrawal-failed.tsx
│   │   │   │   ├── partner-payout-withdrawal-initiated.tsx
│   │   │   │   ├── partner-paypal-payout-failed.tsx
│   │   │   │   ├── partner-program-summary.tsx
│   │   │   │   ├── partner-referral-submitted.tsx
│   │   │   │   ├── partner-user-invited.tsx
│   │   │   │   ├── password-updated.tsx
│   │   │   │   ├── pending-applications-summary.tsx
│   │   │   │   ├── program-application-reminder.tsx
│   │   │   │   ├── program-imported.tsx
│   │   │   │   ├── program-invite.tsx
│   │   │   │   ├── program-network-invite.tsx
│   │   │   │   ├── program-payout-reminder.tsx
│   │   │   │   ├── program-payout-thank-you.tsx
│   │   │   │   ├── program-welcome.tsx
│   │   │   │   ├── referral-invite.tsx
│   │   │   │   ├── referral-status-update.tsx
│   │   │   │   ├── reset-password-link.tsx
│   │   │   │   ├── unresolved-fraud-events-summary.tsx
│   │   │   │   ├── upgrade-email.tsx
│   │   │   │   ├── verify-email-for-account-merge.tsx
│   │   │   │   ├── verify-email.tsx
│   │   │   │   ├── webhook-added.tsx
│   │   │   │   ├── webhook-disabled.tsx
│   │   │   │   ├── webhook-failed.tsx
│   │   │   │   ├── welcome-email-partner.tsx
│   │   │   │   ├── welcome-email.tsx
│   │   │   │   └── workspace-invite.tsx
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── embeds/
│   │   ├── core/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── constants.ts
│   │   │   │   ├── core.ts
│   │   │   │   ├── embed.ts
│   │   │   │   ├── error.ts
│   │   │   │   ├── example/
│   │   │   │   │   └── index.html
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsup.config.ts
│   │   └── react/
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── postcss.config.js
│   │       ├── prepublish.js
│   │       ├── src/
│   │       │   ├── embed.tsx
│   │       │   ├── example/
│   │       │   │   └── app.tsx
│   │       │   └── index.ts
│   │       ├── tailwind.config.ts
│   │       ├── tsconfig.json
│   │       └── tsup.config.ts
│   ├── hubspot-app/
│   │   ├── CLAUDE.md
│   │   ├── README.md
│   │   ├── hsproject.json
│   │   ├── package.json
│   │   └── src/
│   │       └── app/
│   │           ├── app-hsmeta.json
│   │           └── webhooks/
│   │               └── webhooks-hsmeta.json
│   ├── prisma/
│   │   ├── client.ts
│   │   ├── edge.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── schema/
│   │   │   ├── activity.prisma
│   │   │   ├── bounty.prisma
│   │   │   ├── campaign.prisma
│   │   │   ├── comment.prisma
│   │   │   ├── commission.prisma
│   │   │   ├── customer.prisma
│   │   │   ├── dashboard.prisma
│   │   │   ├── discount.prisma
│   │   │   ├── domain.prisma
│   │   │   ├── folder.prisma
│   │   │   ├── fraud.prisma
│   │   │   ├── group.prisma
│   │   │   ├── integration.prisma
│   │   │   ├── invoice.prisma
│   │   │   ├── jackson.prisma
│   │   │   ├── link.prisma
│   │   │   ├── message.prisma
│   │   │   ├── misc.prisma
│   │   │   ├── network.prisma
│   │   │   ├── notification.prisma
│   │   │   ├── oauth.prisma
│   │   │   ├── partner.prisma
│   │   │   ├── payout.prisma
│   │   │   ├── platform.prisma
│   │   │   ├── postback.prisma
│   │   │   ├── program.prisma
│   │   │   ├── referral.prisma
│   │   │   ├── reward.prisma
│   │   │   ├── schema.prisma
│   │   │   ├── tag.prisma
│   │   │   ├── token.prisma
│   │   │   ├── utm.prisma
│   │   │   ├── webhook.prisma
│   │   │   ├── workflow.prisma
│   │   │   └── workspace.prisma
│   │   └── tsconfig.json
│   ├── stripe-app/
│   │   ├── README.md
│   │   ├── jest.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── hooks/
│   │   │   │   └── use-workspace.ts
│   │   │   ├── utils/
│   │   │   │   ├── constants.ts
│   │   │   │   ├── dub.ts
│   │   │   │   ├── oauth.ts
│   │   │   │   ├── secrets.ts
│   │   │   │   ├── stripe.ts
│   │   │   │   └── types.ts
│   │   │   └── views/
│   │   │       └── AppSettings.tsx
│   │   ├── stripe-app.dev.json
│   │   ├── stripe-app.json
│   │   ├── tsconfig.json
│   │   └── ui-extensions.d.ts
│   ├── tailwind-config/
│   │   ├── package.json
│   │   ├── tailwind.config.ts
│   │   └── themes.css
│   ├── tinybird/
│   │   ├── README.md
│   │   ├── datasources/
│   │   │   ├── dub_audit_logs.datasource
│   │   │   ├── dub_click_events.datasource
│   │   │   ├── dub_click_events_id.datasource
│   │   │   ├── dub_click_events_mv.datasource
│   │   │   ├── dub_conversion_events_log.datasource
│   │   │   ├── dub_first_sale_mv.datasource
│   │   │   ├── dub_import_error_logs.datasource
│   │   │   ├── dub_lead_events.datasource
│   │   │   ├── dub_lead_events_mv.datasource
│   │   │   ├── dub_links_metadata.datasource
│   │   │   ├── dub_links_metadata_latest.datasource
│   │   │   ├── dub_postback_events.datasource
│   │   │   ├── dub_sale_events.datasource
│   │   │   ├── dub_sale_events_mv.datasource
│   │   │   └── dub_webhook_events.datasource
│   │   └── pipes/
│   │       ├── all_stats.pipe
│   │       ├── coordinates_all.pipe
│   │       ├── coordinates_sales.pipe
│   │       ├── dub_click_events_id_pipe.pipe
│   │       ├── dub_click_events_pipe.pipe
│   │       ├── dub_first_sale_pipe.pipe
│   │       ├── dub_lead_events_pipe.pipe
│   │       ├── dub_links_metadata_pipe.pipe
│   │       ├── dub_sale_events_pipe.pipe
│   │       ├── get_audit_logs.pipe
│   │       ├── get_click_event.pipe
│   │       ├── get_framer_lead_events.pipe
│   │       ├── get_import_error_logs.pipe
│   │       ├── get_lead_event.pipe
│   │       ├── get_lead_events.pipe
│   │       ├── get_postback_events.pipe
│   │       ├── get_webhook_events.pipe
│   │       ├── v2_customer_events.pipe
│   │       ├── v2_top_programs.pipe
│   │       ├── v3_count.pipe
│   │       ├── v3_events.pipe
│   │       ├── v3_group_by.pipe
│   │       ├── v3_group_by_link_country.pipe
│   │       ├── v3_group_by_link_metadata.pipe
│   │       ├── v3_timeseries.pipe
│   │       ├── v3_usage.pipe
│   │       ├── v3_usage_latest.pipe
│   │       ├── v4_count.pipe
│   │       ├── v4_events.pipe
│   │       ├── v4_group_by.pipe
│   │       ├── v4_group_by_link_metadata.pipe
│   │       └── v4_timeseries.pipe
│   ├── tsconfig/
│   │   ├── base.json
│   │   ├── nextjs.json
│   │   ├── package.json
│   │   └── react-library.json
│   ├── ui/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── accordion.tsx
│   │   │   ├── activity-ring.tsx
│   │   │   ├── alert.tsx
│   │   │   ├── animated-size-container.tsx
│   │   │   ├── avatar.tsx
│   │   │   ├── background.tsx
│   │   │   ├── badge.tsx
│   │   │   ├── blur-image.tsx
│   │   │   ├── button.tsx
│   │   │   ├── card-list/
│   │   │   │   ├── card-list-card.tsx
│   │   │   │   ├── card-list.tsx
│   │   │   │   └── index.ts
│   │   │   ├── card-selector.tsx
│   │   │   ├── carousel/
│   │   │   │   ├── carousel.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── nav-bar.tsx
│   │   │   │   └── thumbnails.tsx
│   │   │   ├── charts/
│   │   │   │   ├── areas.tsx
│   │   │   │   ├── bars.tsx
│   │   │   │   ├── chart-context.ts
│   │   │   │   ├── funnel-chart.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── time-series-chart.tsx
│   │   │   │   ├── tooltip-sync.tsx
│   │   │   │   ├── types.ts
│   │   │   │   ├── use-tooltip.ts
│   │   │   │   ├── utils.ts
│   │   │   │   ├── x-axis.tsx
│   │   │   │   └── y-axis.tsx
│   │   │   ├── checkbox.tsx
│   │   │   ├── client-only.tsx
│   │   │   ├── combobox/
│   │   │   │   └── index.tsx
│   │   │   ├── composite-logo.tsx
│   │   │   ├── content.ts
│   │   │   ├── copy-button.tsx
│   │   │   ├── copy-text.tsx
│   │   │   ├── date-picker/
│   │   │   │   ├── calendar.tsx
│   │   │   │   ├── date-picker.tsx
│   │   │   │   ├── date-range-picker.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── presets.tsx
│   │   │   │   ├── shared.ts
│   │   │   │   ├── trigger.tsx
│   │   │   │   └── types.ts
│   │   │   ├── dots-pattern.tsx
│   │   │   ├── dub-status-badge.tsx
│   │   │   ├── empty-state.tsx
│   │   │   ├── file-upload.tsx
│   │   │   ├── filter/
│   │   │   │   ├── filter-list.tsx
│   │   │   │   ├── filter-select.tsx
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── footer.tsx
│   │   │   ├── form.tsx
│   │   │   ├── grid.tsx
│   │   │   ├── hooks/
│   │   │   │   ├── index.ts
│   │   │   │   ├── use-click-handlers.ts
│   │   │   │   ├── use-column-visibility.ts
│   │   │   │   ├── use-cookies.ts
│   │   │   │   ├── use-copy-to-clipboard.tsx
│   │   │   │   ├── use-current-anchor.ts
│   │   │   │   ├── use-current-subdomain.ts
│   │   │   │   ├── use-enter-submit.ts
│   │   │   │   ├── use-in-viewport.tsx
│   │   │   │   ├── use-input-focused.ts
│   │   │   │   ├── use-intersection-observer.ts
│   │   │   │   ├── use-keyboard-shortcut.tsx
│   │   │   │   ├── use-local-storage.ts
│   │   │   │   ├── use-media-query.ts
│   │   │   │   ├── use-optimistic-update.ts
│   │   │   │   ├── use-pagination.ts
│   │   │   │   ├── use-remove-ga-params.ts
│   │   │   │   ├── use-resize-observer.ts
│   │   │   │   ├── use-router-stuff.ts
│   │   │   │   ├── use-scroll-progress.ts
│   │   │   │   ├── use-scroll.ts
│   │   │   │   └── use-toast-with-undo.tsx
│   │   │   ├── icon-menu.tsx
│   │   │   ├── icons/
│   │   │   │   ├── anthropic.tsx
│   │   │   │   ├── arrow-up-right-2.tsx
│   │   │   │   ├── bing.tsx
│   │   │   │   ├── continents/
│   │   │   │   │   ├── af.tsx
│   │   │   │   │   ├── as.tsx
│   │   │   │   │   ├── eu.tsx
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── na.tsx
│   │   │   │   │   ├── oc.tsx
│   │   │   │   │   └── sa.tsx
│   │   │   │   ├── copy.tsx
│   │   │   │   ├── crown-small.tsx
│   │   │   │   ├── default-domains/
│   │   │   │   │   ├── amazon.tsx
│   │   │   │   │   ├── chatgpt.tsx
│   │   │   │   │   ├── figma.tsx
│   │   │   │   │   ├── github-enhanced.tsx
│   │   │   │   │   ├── google-enhanced.tsx
│   │   │   │   │   └── spotify.tsx
│   │   │   │   ├── dub-analytics.tsx
│   │   │   │   ├── dub-api.tsx
│   │   │   │   ├── dub-crafted-shield.tsx
│   │   │   │   ├── dub-links.tsx
│   │   │   │   ├── dub-partners.tsx
│   │   │   │   ├── dub-product-icon.tsx
│   │   │   │   ├── expanding-arrow.tsx
│   │   │   │   ├── facebook.tsx
│   │   │   │   ├── file-pen.tsx
│   │   │   │   ├── file-send.tsx
│   │   │   │   ├── github.tsx
│   │   │   │   ├── go.tsx
│   │   │   │   ├── google.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   ├── instagram.tsx
│   │   │   │   ├── ios-app-store.tsx
│   │   │   │   ├── linkedin.tsx
│   │   │   │   ├── loading-circle.tsx
│   │   │   │   ├── loading-dots.tsx
│   │   │   │   ├── loading-spinner.tsx
│   │   │   │   ├── lock-small.tsx
│   │   │   │   ├── magic.tsx
│   │   │   │   ├── markdown-icon.tsx
│   │   │   │   ├── matrix-lines.tsx
│   │   │   │   ├── nucleo/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── android-logo.tsx
│   │   │   │   │   ├── apple-logo.tsx
│   │   │   │   │   ├── apple.tsx
│   │   │   │   │   ├── arrow-bold-up.tsx
│   │   │   │   │   ├── arrow-right.tsx
│   │   │   │   │   ├── arrow-trend-up.tsx
│   │   │   │   │   ├── arrow-turn-left.tsx
│   │   │   │   │   ├── arrow-turn-right2.tsx
│   │   │   │   │   ├── arrow-up-right.tsx
│   │   │   │   │   ├── arrows-opposite-direction-x.tsx
│   │   │   │   │   ├── arrows-opposite-direction-y.tsx
│   │   │   │   │   ├── at-sign.tsx
│   │   │   │   │   ├── badge-check.tsx
│   │   │   │   │   ├── badge-check2-fill.tsx
│   │   │   │   │   ├── bell.tsx
│   │   │   │   │   ├── blog.tsx
│   │   │   │   │   ├── bolt-fill.tsx
│   │   │   │   │   ├── bolt.tsx
│   │   │   │   │   ├── book-open.tsx
│   │   │   │   │   ├── book2-fill.tsx
│   │   │   │   │   ├── book2-small.tsx
│   │   │   │   │   ├── book2.tsx
│   │   │   │   │   ├── books2.tsx
│   │   │   │   │   ├── box-archive.tsx
│   │   │   │   │   ├── brackets-curly.tsx
│   │   │   │   │   ├── briefcase-fill.tsx
│   │   │   │   │   ├── brush.tsx
│   │   │   │   │   ├── bullet-list-fill.tsx
│   │   │   │   │   ├── bullet-list.tsx
│   │   │   │   │   ├── calculator.tsx
│   │   │   │   │   ├── calendar-days.tsx
│   │   │   │   │   ├── calendar-refresh.tsx
│   │   │   │   │   ├── calendar.tsx
│   │   │   │   │   ├── calendar6.tsx
│   │   │   │   │   ├── cards.tsx
│   │   │   │   │   ├── caret-up-fill.tsx
│   │   │   │   │   ├── chart-activity2.tsx
│   │   │   │   │   ├── chart-area2.tsx
│   │   │   │   │   ├── chart-line.tsx
│   │   │   │   │   ├── check.tsx
│   │   │   │   │   ├── check2.tsx
│   │   │   │   │   ├── checkbox-checked-fill.tsx
│   │   │   │   │   ├── checkbox-unchecked.tsx
│   │   │   │   │   ├── chevron-left.tsx
│   │   │   │   │   ├── chevron-right.tsx
│   │   │   │   │   ├── chevron-up.tsx
│   │   │   │   │   ├── circle-arrow-right.tsx
│   │   │   │   │   ├── circle-check-fill.tsx
│   │   │   │   │   ├── circle-check.tsx
│   │   │   │   │   ├── circle-dollar-out.tsx
│   │   │   │   │   ├── circle-dollar.tsx
│   │   │   │   │   ├── circle-dollar3.tsx
│   │   │   │   │   ├── circle-dotted.tsx
│   │   │   │   │   ├── circle-half-dotted-check.tsx
│   │   │   │   │   ├── circle-half-dotted-clock.tsx
│   │   │   │   │   ├── circle-info.tsx
│   │   │   │   │   ├── circle-percentage.tsx
│   │   │   │   │   ├── circle-play-fill.tsx
│   │   │   │   │   ├── circle-play.tsx
│   │   │   │   │   ├── circle-question.tsx
│   │   │   │   │   ├── circle-user.tsx
│   │   │   │   │   ├── circle-warning.tsx
│   │   │   │   │   ├── circle-xmark.tsx
│   │   │   │   │   ├── cir

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/apply-issue-labels-to-pr.yml
================================================
name: "Apply issue labels to PR"

on:
  pull_request_target:
    types:
      - opened

jobs:
  label_on_pr:
    runs-on: ubuntu-latest

    permissions:
      contents: none
      issues: read
      pull-requests: write

    steps:
      - name: Apply labels from linked issue to PR
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            async function getLinkedIssues(owner, repo, prNumber) {
              const query = `query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
                repository(owner: $owner, name: $repo) {
                  pullRequest(number: $prNumber) {
                    closingIssuesReferences(first: 10) {
                      nodes {
                        number
                        labels(first: 10) {
                          nodes {
                            name
                          }
                        }
                      }
                    }
                  }
                }
              }`;

              const variables = {
                owner: owner,
                repo: repo,
                prNumber: prNumber,
              };

              const result = await github.graphql(query, variables);
              return result.repository.pullRequest.closingIssuesReferences.nodes;
            }

            const pr = context.payload.pull_request;
            const linkedIssues = await getLinkedIssues(
              context.repo.owner,
              context.repo.repo,
              pr.number
            );

            const labelsToAdd = new Set();
            for (const issue of linkedIssues) {
              if (issue.labels && issue.labels.nodes) {
                for (const label of issue.labels.nodes) {
                  labelsToAdd.add(label.name);
                }
              }
            }

            if (labelsToAdd.size) {
              await github.rest.issues.addLabels({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                labels: Array.from(labelsToAdd),
              });
            }


================================================
FILE: .github/workflows/deploy-embed-script.yml
================================================
name: "Deploy embed script"

on:
  push:
    branches:
      - main
    paths:
      - "packages/embeds/core/**"
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: 8
      - name: Install dependencies & build
        run: pnpm --filter @dub/embed-core build

      # - name: Deploy to Cloudflare Pages (https://www.dubcdn.com/embed/script.js)
      #   uses: cloudflare/wrangler-action@v3
      #   with:
      #     apiToken: ${{ secrets.CLOUDFLARE_PAGES_API_KEY }}
      #     accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
      #     command: pages deploy dist/embed/script.js --project-name=dub-cdn --commit-dirty=true
      #     workingDirectory: packages/embeds/core
      #     packageManager: pnpm


================================================
FILE: .github/workflows/e2e.yaml
================================================
name: Public API Tests

on:
  deployment_status:

jobs:
  api-tests:
    timeout-minutes: 30
    if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success'
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v2

      - name: Setup pnpm
        uses: pnpm/action-setup@v3

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Build utils
        working-directory: packages/utils
        run: pnpm build

      - name: Run tests
        working-directory: apps/web
        env:
          E2E_BASE_URL: ${{ github.event.deployment_status.environment_url }}
          E2E_TOKEN: ${{ secrets.E2E_TOKEN }}
          E2E_TOKEN_MEMBER: ${{ secrets.E2E_TOKEN_MEMBER }}
          E2E_TOKEN_OLD: ${{ secrets.E2E_TOKEN_OLD }}
          E2E_PUBLISHABLE_KEY: ${{ secrets.E2E_PUBLISHABLE_KEY }}
          QSTASH_TOKEN: ${{ secrets.QSTASH_TOKEN }}
          QSTASH_CURRENT_SIGNING_KEY: ${{ secrets.QSTASH_CURRENT_SIGNING_KEY }}
          NEXT_PUBLIC_NGROK_URL: ${{ github.event.deployment_status.environment_url }}
        run: pnpm test


================================================
FILE: .github/workflows/playwright.yaml
================================================
name: Playwright E2E Tests

on:
  pull_request:
    branches: [main]
    paths:
      - "apps/web/**"
      - "packages/**"
      - ".github/workflows/playwright.yaml"

concurrency:
  group: e2e-${{ github.head_ref }}
  cancel-in-progress: true

jobs:
  e2e:
    permissions:
      contents: read
    timeout-minutes: 20
    runs-on: ubuntu-latest

    env:
      CI: "true"
      NODE_OPTIONS: "--max-old-space-size=8192"
      DATABASE_URL: "mysql://root:@localhost:3306/planetscale"
      PLANETSCALE_DATABASE_URL: "http://root:unused@localhost:3900/planetscale"

      NEXTAUTH_SECRET: "e2e-test-secret-at-least-32-chars-long"
      NEXTAUTH_URL: "http://partners.localhost:8888"

      NEXT_PUBLIC_APP_NAME: "Dub"
      NEXT_PUBLIC_APP_DOMAIN: "dub.co"
      NEXT_PUBLIC_APP_SHORT_DOMAIN: "dub.sh"

      E2E_PARTNER_EMAIL: "partner1@dub-internal-test.com"
      E2E_PARTNER_PASSWORD: "password"

      TINYBIRD_API_KEY: "xx"
      TINYBIRD_API_URL: "xx"

      UPSTASH_REDIS_REST_URL: "https://sensible-camel-xxxx.upstash.io"
      UPSTASH_REDIS_REST_TOKEN: "xx"
      UPSTASH_VECTOR_REST_URL: "https://sensible-camel-xxxx.upstash.io"
      UPSTASH_VECTOR_REST_TOKEN: "xx"
      QSTASH_TOKEN: "xx"
      QSTASH_CURRENT_SIGNING_KEY: "xx"
      QSTASH_NEXT_SIGNING_KEY: "xx"

      AXIOM_TOKEN: ""
      AXIOM_DATASET: ""

      RESEND_API_KEY: "xx"

      EMBEDDING_SYNC_SECRET: "xx"
      ANTHROPIC_API_KEY: "xx"

      STRIPE_SECRET_KEY: "xx"
      STRIPE_WEBHOOK_SECRET: "xx"
      STRIPE_CONNECT_WEBHOOK_SECRET: "xx"
      STRIPE_APP_WEBHOOK_SECRET_TEST: "xx"
      STRIPE_APP_SECRET_KEY_TEST: "xx"
      STRIPE_CONNECT_V2_WEBHOOK_SECRET: "xx"
      STRIPE_APP_SECRET_KEY_SANDBOX: "xx"

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_DATABASE: planetscale
          MYSQL_ROOT_HOST: "%"
          MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
        options: >-
          --health-cmd="mysqladmin ping -h 127.0.0.1"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5
        ports:
          - 3306:3306

    steps:
      - name: Check out code
        uses: actions/checkout@v4

      - name: Start PlanetScale simulator
        run: |
          docker run -d --name ps-http-sim \
            --network host \
            ghcr.io/mattrobenolt/ps-http-sim:latest \
            -listen-addr=0.0.0.0 \
            -listen-port=3900 \
            -mysql-dbname=planetscale \
            -mysql-no-pass \
            -mysql-addr=127.0.0.1

      - name: Setup pnpm
        uses: pnpm/action-setup@v3

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Cache Playwright browsers
        id: playwright-cache
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ runner.os }}-${{ hashFiles('apps/web/package.json') }}

      - name: Install Playwright Chromium
        if: steps.playwright-cache.outputs.cache-hit != 'true'
        run: pnpm --filter web exec playwright install chromium

      - name: Generate Prisma client
        working-directory: apps/web
        run: pnpm prisma:generate

      - name: Push database schema
        working-directory: apps/web
        run: pnpm prisma:push

      - name: Seed test data
        working-directory: apps/web
        run: pnpm tsx playwright/seed.ts

      # - name: Cache Next.js build
      #   uses: actions/cache@v4
      #   with:
      #     path: apps/web/.next/cache
      #     key: nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('apps/web/**/*.ts', 'apps/web/**/*.tsx') }}
      #     restore-keys: |
      #       nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-
      #       nextjs-${{ runner.os }}-

      # - name: Cache Turbo
      #   uses: actions/cache@v4
      #   with:
      #     path: .turbo
      #     key: turbo-${{ runner.os }}-${{ github.sha }}
      #     restore-keys: |
      #       turbo-${{ runner.os }}-

      - name: Build application
        run: pnpm turbo build --filter=web

      - name: Run Playwright tests
        working-directory: apps/web
        run: pnpm test:e2e


================================================
FILE: .github/workflows/prettier.yaml
================================================
name: Prettier Check

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v3

      - name: Install dependencies
        run: pnpm install

      - name: Fix prettier issues
        run: pnpm run format

      - name: Check prettier format
        run: pnpm run prettier-check


================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
dist/

# next.js
.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
.pnpm-debug.log*

# local env files
.env*.local
.env

# vercel
.vercel

# tinybird
.venv
.tinyb

# turbo
.turbo

# typescript
*.tsbuildinfo
next-env.d.ts

# miscellaneous
/pages/api/scripts*
packages/stripe-app/.build/*
.react-email
.contentlayer
.vscode
*.csv
*.ndjson
.vitest

# playwright
playwright-report/
**/playwright/.auth/
test-results/
blob-report/

================================================
FILE: .prettierignore
================================================
node_modules
pnpm-lock.yaml
.next
.turbo
dist

================================================
FILE: LICENSE.md
================================================
Copyright (c) 2024-present Dub Technologies, Inc.

Portions of this software – namely all files that reside under the following directories of this repository – are licensed under the license defined in "[ee/LICENSE.md](<https://github.com/dubinc/dub/tree/main/apps/web/app/(ee)/LICENSE.md>)".

- [apps/web/app/(ee)](<https://github.com/dubinc/dub/tree/main/apps/web/app/(ee)>)
- [apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)](<https://github.com/dubinc/dub/tree/main/apps/web/app/app.dub.co/(dashboard)/%5Bslug%5D/(ee)>)

All third-party components incorporated into the Dub Software are licensed under the original license provided by the owner of the applicable component.

Content outside of the above mentioned directories or restrictions above is available under the "AGPLv3" license as defined below.

---

                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

                            Preamble

The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

0. Definitions.

"This License" refers to version 3 of the GNU Affero General Public License.

"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.

To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

A "covered work" means either the unmodified Program or a work based
on the Program.

To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

1. Source Code.

The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.

A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

The Corresponding Source for a work in source code form is that
same work.

2. Basic Permissions.

All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

4. Conveying Verbatim Copies.

You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

5. Conveying Modified Source Versions.

You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

6. Conveying Non-Source Forms.

You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

7. Additional Terms.

"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

8. Termination.

You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

9. Acceptance Not Required for Having Copies.

You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

10. Automatic Licensing of Downstream Recipients.

Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.

An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

11. Patents.

A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".

A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

12. No Surrender of Others' Freedom.

If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

13. Remote Network Interaction; Use with the GNU General Public License.

Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

14. Revised Versions of this License.

The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

15. Disclaimer of Warranty.

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

17. Interpretation of Sections 15 and 16.

If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.


================================================
FILE: README.md
================================================
<a href="https://dub.co">
  <img alt="Dub is the modern, open-source link attribution platform for short links, conversion tracking, and affiliate programs." src="https://github.com/user-attachments/assets/42cf0705-f5a2-4200-bc4a-c5acf0ba9e15">
</a>

<h3 align="center">Dub</h3>

<p align="center">
    The open-source link attribution platform.
    <br />
    <a href="https://dub.co"><strong>Learn more »</strong></a>
    <br />
    <br />
    <a href="#introduction"><strong>Introduction</strong></a> ·
    <a href="#tech-stack"><strong>Tech Stack</strong></a> ·
    <a href="#self-hosting"><strong>Self-hosting</strong></a> ·
    <a href="#contributing"><strong>Contributing</strong></a>
</p>

<p align="center">
  <a href="https://twitter.com/dubdotco">
    <img src="https://img.shields.io/twitter/follow/dubdotco?style=flat&label=%40dubdotco&logo=twitter&color=0bf&logoColor=fff" alt="Twitter" />
  </a>
  <a href="https://news.ycombinator.com/item?id=32939407"><img src="https://img.shields.io/badge/Hacker%20News-255-%23FF6600" alt="Hacker News"></a>
  <a href="https://github.com/dubinc/dub/blob/main/LICENSE.md">
    <img src="https://img.shields.io/github/license/dubinc/dub?label=license&logo=github&color=f80&logoColor=fff" alt="License" />
  </a>
</p>

<br/>

## Introduction

Dub is the modern, open-source link attribution platform for [short links](https://dub.co/home), [conversion tracking](https://dub.co/analytics), and [affiliate programs](https://dub.co/partners).

Our platform powers 100M+ clicks and 2M+ links monthly, and is used by world-class marketing teams from companies like Twilio, Buffer, Framer, Perplexity, Vercel, Laravel, and [more](https://dub.co/customers).

## Tech Stack

- [Next.js](https://nextjs.org/) – framework
- [TypeScript](https://www.typescriptlang.org/) – language
- [Tailwind](https://tailwindcss.com/) – CSS
- [Prisma](https://www.prisma.io/) – ORM
- [Upstash](https://upstash.com/) – redis
- [Tinybird](https://tinybird.com/) – analytics
- [PlanetScale](https://planetscale.com/) – database
- [NextAuth.js](https://next-auth.js.org/) – auth
- [BoxyHQ](https://boxyhq.com/enterprise-sso) – SSO/SAML
- [Turborepo](https://turbo.build/repo) – monorepo
- [Stripe](https://stripe.com/) – payments
- [Resend](https://resend.com/) – emails
- [Vercel](https://vercel.com/) – deployments

## Self-Hosting

You can self-host Dub for greater control over your data and design. [Read this guide](https://dub.co/docs/self-hosting/guide) to learn more.

## Contributing

We love our contributors! Here's how you can contribute:

- [Open an issue](https://github.com/dubinc/dub/issues) if you believe you've encountered a bug.
- Follow the [local development guide](https://dub.co/docs/local-development) to get your local dev environment set up.
- Make a [pull request](https://github.com/dubinc/dub/pull) to add new features/make quality-of-life improvements/fix bugs.

### Recommended Versions

| Package | Version  |
| ------- | -------- |
| node    | v23.11.0 |
| pnpm    | 9.15.9   |

### Common Local Development Issues

- `The table <table-name> does not exist in the current database.` - Run `pnpm prisma:push` push the state of the Prisma schema file to the database without using migrations files.
- The project is not building correctly locally - verify your versions of `node` and `pnpm` match the recommended versions above. Delete all `node_modules`, `.next`, and `.turbo` directories in the `apps` and `packages` directory. You may now reinstall `node_modules` by running `pnpm install` and attempt to rebuild the project with `pnpm build`.

### Dev Seed Script

This script seeds the database with development data for testing and development purposes.

**Basic seeding (adds data without deleting existing data):**

```bash
cd apps/web
pnpm run script dev/seed
```

**Truncate database before seeding (deletes all existing data first):**

```bash
cd apps/web
pnpm run script dev/seed --truncate
```

When using `--truncate`, the script will ask for confirmation before deleting any data.

## Repo Activity

![Dub repo activity – generated by Axiom](https://repobeats.axiom.co/api/embed/6ac4c94a89ea20e2e10032b932a128b6d8442e66.svg "Repobeats analytics image")

## License

Dub Technologies, Inc. is a commercial open-source company, which means some parts of this open-source repository require a commercial license. The concept is called "Open Core" where the core technology (99%) is fully open source, licensed under [AGPLv3](https://opensource.org/license/agpl-v3) and the last 1% is covered under a commercial license (["/ee" Enterprise Edition](<https://github.com/dubinc/dub/tree/ee/apps/web/app/(ee)>)) which we believe is entirely relevant for larger organisations that require enterprise features. Enterprise features are built by the core engineering team of Dub Technologies, Inc., which is hired full-time.


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

All versions of Dub are currently being supported with security updates.

## Reporting a Vulnerability

To report a vulnerability, send an email to security@dub.co.

We will respond within 48 hours acknowledging your report with details about next steps and potential rewards/compensation for responsible disclosure.


================================================
FILE: apps/web/app/(ee)/LICENSE.md
================================================
The Dub.co Commercial License (the “Commercial License”)
Copyright (c) 2024-present Dub Technologies, Inc

With regard to the Dub.co Software:

This software and associated documentation files (the "Software") may only be
used in production, if you (and any entity that you represent) have agreed to,
and are in compliance with, the Dub.co Subscription Terms available
at https://dub.co/legal/terms, or other agreements governing
the use of the Software, as mutually agreed by you and Dub.co, Inc ("Dub.co"),
and otherwise have a valid Dub.co Enterprise Edition subscription ("Commercial Subscription")
for the correct number of hosts as defined in the "Commercial Terms ("Hosts"). Subject to the foregoing sentence,
you are free to modify this Software and publish patches to the Software. You agree
that Dub.co and/or its licensors (as applicable) retain all right, title and interest in
and to all such modifications and/or patches, and all such modifications and/or
patches may only be used, copied, modified, displayed, distributed, or otherwise
exploited with a valid Commercial Subscription for the correct number of hosts.
Notwithstanding the foregoing, you may copy and modify the Software for development
and testing purposes, without requiring a subscription. You agree that Dub.co and/or
its licensors (as applicable) retain all right, title and interest in and to all such
modifications. You are not granted any other rights beyond what is expressly stated herein.
Subject to the foregoing, it is forbidden to copy, merge, publish, distribute, sublicense,
and/or sell the Software.

This Commercial License applies only to the part of this Software that is not distributed under
the AGPLv3 license. Any part of this Software distributed under the MIT license or which
is served client-side as an image, font, cascading stylesheet (CSS), file which produces
or is compiled, arranged, augmented, or combined into client-side JavaScript, in whole or
in part, is copyrighted under the AGPLv3 license. The full text of this Commercial License shall
be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

For all third party components incorporated into the Dub.co Software, those
components are licensed under the original license provided by the owner of the
applicable component.


================================================
FILE: apps/web/app/(ee)/README.md
================================================
<!-- PROJECT LOGO -->
<div align="center">
  <a href="https://dub.co/enterprise">
    <img src="https://github.com/user-attachments/assets/42cf0705-f5a2-4200-bc4a-c5acf0ba9e15" alt="Logo">
  </a>
  
  <a href="https://dub.co/enterprise">Get an Enterprise License</a>
</div>

# Enterprise Edition

Welcome to the Enterprise Edition of Dub.co.

The [/(ee)](<https://github.com/dubinc/dub/tree/main/apps/web/app/(ee)>) subfolder is the place for all the **Enterprise Edition** features from our [hosted](https://dub.co/pricing) plan and enterprise-grade features for [Enterprise](https://dub.co/enterprise), included but not limited to the following:

- [Dub Conversions](https://dub.co/help/article/dub-conversions)
- [Dub Partners](https://dub.co/help/article/dub-partners)
- [SAML/SSO + SCIM Directory sync ](https://dub.co/help/category/saml-sso)

> _❗ WARNING: This repository is copyrighted (unlike our [main repo](https://github.com/dubinc/dub)). You are not allowed to use this code to host your own version of app.dub.co without obtaining a proper [license](https://dub.co/enterprise) first❗_


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(auth)/layout.tsx
================================================
import { Background } from "@dub/ui";

export default function AdminAuthLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <Background />
      <div className="relative z-10 flex flex-col items-center justify-center">
        {children}
      </div>
    </>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(auth)/login/page.tsx
================================================
export { default } from "../../../../app.dub.co/(auth)/login/page";


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/analytics/page.tsx
================================================
import Analytics from "@/ui/analytics";
import LayoutLoader from "@/ui/layout/layout-loader";
import { Suspense } from "react";

export default function AdminAnalytics() {
  return (
    <Suspense fallback={<LayoutLoader />}>
      <div className="w-full">
        <Analytics adminPage />
      </div>
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/commissions/client.tsx
================================================
"use client";

import { formatDateTooltip } from "@/lib/analytics/format-date-tooltip";
import { AnalyticsLoadingSpinner } from "@/ui/analytics/analytics-loading-spinner";
import { FilterButtonTableRow } from "@/ui/shared/filter-button-table-row";
import SimpleDateRangePicker from "@/ui/shared/simple-date-range-picker";
import {
  CrownSmall,
  Filter,
  Table,
  usePagination,
  useRouterStuff,
  useTable,
} from "@dub/ui";
import { Areas, TimeSeriesChart, XAxis, YAxis } from "@dub/ui/charts";
import { GridIcon } from "@dub/ui/icons";
import {
  cn,
  currencyFormatter,
  DUB_FOUNDING_DATE,
  fetcher,
  OG_AVATAR_URL,
} from "@dub/utils";
import NumberFlow from "@number-flow/react";
import { Fragment, useCallback, useMemo, useState } from "react";
import useSWR from "swr";

export default function CommissionsPageClient() {
  const { queryParams, getQueryString, searchParamsObj } = useRouterStuff();
  const { interval, start, end, programId } = searchParamsObj;

  const { data: { programs, timeseries } = {}, isLoading } = useSWR<{
    programs: {
      id: string;
      name: string;
      logo: string;
      commissions: number;
      fees: number;
    }[];
    timeseries: {
      start: Date;
      commissions: number;
    }[];
  }>(
    `/api/admin/commissions${getQueryString({
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    })}`,
    fetcher,
    {
      keepPreviousData: true,
    },
  );

  // Filter configuration
  const filters = useMemo(
    () => [
      {
        key: "programId",
        icon: GridIcon,
        label: "Program",
        options:
          programs?.map((program) => ({
            value: program.id,
            label: program.name,
            icon: (
              <img
                src={program.logo || `${OG_AVATAR_URL}${program.name}`}
                alt={`${program.name} image`}
                className="size-4 rounded-full"
              />
            ),
          })) ?? null,
      },
    ],
    [programs],
  );

  const activeFilters = useMemo(() => {
    return [...(programId ? [{ key: "programId", value: programId }] : [])];
  }, [programId]);

  const onSelect = useCallback(
    (key: string, value: any) =>
      queryParams({
        set: {
          [key]: value,
        },
        del: "page",
      }),
    [queryParams],
  );

  const onRemove = useCallback(
    (key: string) =>
      queryParams({
        del: [key, "page"],
      }),
    [queryParams],
  );

  const onRemoveAll = useCallback(
    () =>
      queryParams({
        del: ["programId"],
      }),
    [queryParams],
  );

  const [selectedFilter, setSelectedFilter] = useState<string | null>(null);
  const [search, setSearch] = useState("");

  const tabs: {
    id: string;
    label: string;
    colorClassName: string;
    disabled?: boolean;
  }[] = [
    {
      id: "commissions",
      label: "Commissions",
      colorClassName: "text-teal-500 bg-teal-500/50 border-teal-500",
    },
    {
      id: "fees",
      label: "Fees",
      colorClassName: "text-red-500 bg-red-500/50 border-red-500",
      disabled: true,
    },
  ];

  const tab = tabs[0];
  const selectedTab = tab.id;

  const chartData =
    timeseries?.map(({ start, commissions }) => ({
      date: start ? new Date(start) : new Date(),
      values: {
        commissions: commissions || 0,
      },
    })) ?? null;

  const totals = useMemo(() => {
    return {
      commissions:
        timeseries?.reduce(
          (acc, { commissions }) => acc + (commissions || 0),
          0,
        ) ?? 0,
      fees: programs?.reduce((acc, { fees }) => acc + (fees || 0), 0) ?? 0,
    };
  }, [timeseries, programs]);

  const { pagination, setPagination } = usePagination();

  const { table, ...tableProps } = useTable({
    data: programs ?? [],
    columns: [
      {
        id: "position",
        header: "Position",
        size: 12,
        minSize: 12,
        maxSize: 12,
        cell: ({ row }) => {
          return (
            <div className="flex w-28 items-center justify-start gap-2 tabular-nums">
              {row.index + 1}
              {row.index <= 2 && (
                <CrownSmall
                  className={cn("size-4", {
                    "text-amber-400": row.index === 0,
                    "text-neutral-400": row.index === 1,
                    "text-yellow-900": row.index === 2,
                  })}
                />
              )}
            </div>
          );
        },
      },
      {
        id: "program",
        header: "Program",
        cell: ({ row }) => (
          <div className="flex items-center gap-1.5">
            <img
              src={row.original.logo}
              alt={row.original.name}
              width={20}
              height={20}
              className="size-4 rounded-full"
            />
            <span className="text-sm font-medium">{row.original.name}</span>
          </div>
        ),
        meta: {
          filterParams: ({ row }) => ({
            programId: row.original.id,
          }),
        },
      },
      {
        id: "commissions",
        header: "Commissions",
        accessorKey: "commissions",
        cell: ({ row }) => currencyFormatter(row.original.commissions),
      },
      {
        id: "fees",
        header: "Fees",
        accessorKey: "fees",
        cell: ({ row }) => currencyFormatter(row.original.fees),
      },
    ],
    pagination,
    onPaginationChange: setPagination,
    resourceName: (plural) => `program${plural ? "s" : ""}`,
    rowCount: programs?.length ?? 0,
    loading: isLoading,
    cellRight: (cell) => {
      const meta = cell.column.columnDef.meta as
        | {
            filterParams?: any;
          }
        | undefined;

      return (
        meta?.filterParams && (
          <FilterButtonTableRow set={meta.filterParams(cell)} />
        )
      );
    },
  });

  return (
    <div className="mx-auto flex w-full max-w-screen-xl flex-col gap-3 p-6">
      <div className="flex flex-col gap-3 md:flex-row md:items-center">
        <Filter.Select
          className="w-full md:w-fit"
          filters={filters}
          activeFilters={activeFilters}
          onSelect={onSelect}
          onRemove={onRemove}
          onSearchChange={setSearch}
          onSelectedFilterChange={setSelectedFilter}
        />
        <SimpleDateRangePicker
          defaultInterval="mtd"
          className="w-full sm:min-w-[200px] md:w-fit"
        />
      </div>
      {activeFilters.length > 0 && (
        <div>
          <Filter.List
            filters={filters}
            activeFilters={activeFilters}
            onSelect={onSelect}
            onRemove={onRemove}
            onRemoveAll={onRemoveAll}
          />
        </div>
      )}
      <div className="flex flex-col divide-y divide-neutral-200 rounded-lg border border-neutral-200 bg-white">
        <div className="scrollbar-hide grid w-full grid-cols-2 divide-x overflow-y-hidden sm:grid-cols-3">
          {tabs.map(({ id, label, colorClassName, disabled }) => {
            return (
              <button
                key={id}
                disabled={disabled}
                onClick={() => {
                  queryParams({
                    set: { tab: id },
                  });
                }}
                className={cn(
                  "border-box relative block h-full w-full flex-none px-4 py-3 sm:px-8 sm:py-6",
                  "ring-inset ring-neutral-500 focus-visible:ring-1 sm:first:rounded-tl-xl",
                  disabled
                    ? "cursor-not-allowed"
                    : "transition-colors hover:bg-neutral-50 focus:outline-none active:bg-neutral-100",
                )}
              >
                {/* Active tab indicator */}
                <div
                  className={cn(
                    "absolute bottom-0 left-0 h-0.5 w-full bg-black transition-transform duration-100",
                    selectedTab !== id && "translate-y-[3px]",
                  )}
                />
                <div className="flex items-center gap-2.5 text-sm text-neutral-600">
                  <div
                    className={cn(
                      "h-2 w-2 rounded-sm bg-current shadow-[inset_0_0_0_1px_#00000019]",
                      colorClassName,
                    )}
                  />
                  <span>{label}</span>
                </div>
                <div className="mt-1 flex h-12 items-center">
                  {(totals[id] || totals[id] === 0) && !isLoading ? (
                    <NumberFlow
                      value={(totals[id] ?? 0) / 100}
                      className="text-xl font-medium sm:text-3xl"
                      format={{
                        style: "currency",
                        currency: "USD",
                        // @ts-ignore – trailingZeroDisplay is a valid option but TS is outdated
                        trailingZeroDisplay: "stripIfInteger",
                      }}
                    />
                  ) : (
                    <div className="h-10 w-24 animate-pulse rounded-md bg-neutral-200" />
                  )}
                </div>
              </button>
            );
          })}
        </div>
        <div className="p-5 sm:p-10">
          <div className="flex h-96 w-full items-center justify-center">
            {chartData ? (
              chartData.length > 0 ? (
                <TimeSeriesChart
                  data={chartData}
                  series={[
                    {
                      id: "commissions",
                      valueAccessor: (d) => d.values.commissions,
                      isActive: selectedTab === "commissions",
                      colorClassName: tab.colorClassName,
                    },
                  ]}
                  tooltipClassName="p-0"
                  tooltipContent={(d) => (
                    <>
                      <p className="border-b border-neutral-200 px-4 py-3 text-sm text-neutral-900">
                        {formatDateTooltip(d.date, {
                          interval,
                          start,
                          end,
                        })}
                      </p>
                      <div className="grid grid-cols-2 gap-x-6 gap-y-2 px-4 py-3 text-sm">
                        <Fragment>
                          <div className="flex items-center gap-2">
                            <div
                              className={cn(
                                "h-2 w-2 rounded-sm shadow-[inset_0_0_0_1px_#0003]",
                                tab.colorClassName,
                              )}
                            />
                            <p className="capitalize text-neutral-600">
                              {tab.label}
                            </p>
                          </div>
                          <p className="text-right font-medium text-neutral-900">
                            {currencyFormatter(d.values[tab.id])}
                          </p>
                        </Fragment>
                      </div>
                    </>
                  )}
                >
                  <Areas />
                  <XAxis
                    maxTicks={5}
                    tickFormat={(d) =>
                      formatDateTooltip(d, {
                        interval,
                        start,
                        end,
                        dataAvailableFrom: DUB_FOUNDING_DATE,
                      })
                    }
                  />
                  <YAxis
                    showGridLines
                    tickFormat={(value) => currencyFormatter(value)}
                  />
                </TimeSeriesChart>
              ) : (
                <div className="text-center text-sm text-neutral-600">
                  No data available.
                </div>
              )
            ) : (
              <AnalyticsLoadingSpinner />
            )}
          </div>
        </div>
      </div>
      <div className="w-full">
        <Table {...tableProps} table={table} />
      </div>
    </div>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/commissions/page.tsx
================================================
import { Suspense } from "react";
import CommissionsPageClient from "./client";

export default async function CommissionsPage() {
  return (
    <Suspense>
      <CommissionsPageClient />
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/ban-link.tsx
================================================
"use client";

import { LoadingSpinner } from "@dub/ui";
import { cn } from "@dub/utils";
import { useState } from "react";
import { toast } from "sonner";

export function BanLink() {
  const [pending, setPending] = useState(false);

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const form = e.currentTarget;
    const key = new FormData(form).get("key");
    if (!key || typeof key !== "string") return;

    if (!window.confirm("Are you sure you want to ban this link?")) return;

    setPending(true);
    try {
      const res = await fetch(
        `/api/admin/links/ban?domain=dub.sh&key=${encodeURIComponent(key)}`,
        { method: "DELETE" },
      ).then((r) => r.json());
      if (res.error) {
        toast.error(res.error);
      } else {
        toast.success("Link has been banned");
      }
    } finally {
      setPending(false);
    }
  };

  return (
    <div className="flex flex-col space-y-5">
      <form onSubmit={handleSubmit}>
        <Form pending={pending} />
      </form>
    </div>
  );
}

const Form = ({ pending }: { pending: boolean }) => {
  return (
    <div className="relative flex w-full rounded-md shadow-sm">
      <span className="inline-flex items-center rounded-l-md border border-r-0 border-neutral-300 bg-neutral-50 px-5 text-neutral-500 sm:text-sm">
        dub.sh
      </span>
      <input
        name="key"
        id="key"
        type="text"
        required
        disabled={pending}
        autoComplete="off"
        className={cn(
          "block w-full rounded-r-md border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm",
          pending && "bg-neutral-100",
        )}
        placeholder="IG47WZs"
        aria-invalid="true"
        onPaste={(e: React.ClipboardEvent<HTMLInputElement>) => {
          e.preventDefault();
          // if pasting in https://dub.sh/xxx or dub.sh/xxx, extract xxx
          const text = e.clipboardData.getData("text/plain");
          if (
            text.startsWith("https://dub.sh/") ||
            text.startsWith("dub.sh/")
          ) {
            e.currentTarget.value = text
              .replace("https://dub.sh/", "")
              .replace("dub.sh/", "");
          } else {
            e.currentTarget.value = text;
          }
        }}
      />
      {pending && (
        <LoadingSpinner className="absolute inset-y-0 right-2 my-auto h-full w-5 text-neutral-400" />
      )}
    </div>
  );
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/delete-partner-account.tsx
================================================
"use client";

import { LoadingSpinner } from "@dub/ui";
import { cn } from "@dub/utils";
import { useFormStatus } from "react-dom";
import { toast } from "sonner";

export function DeletePartnerAccount() {
  return (
    <div className="flex flex-col space-y-5">
      <form
        action={async (formData) => {
          const deletePartnerAccount =
            formData.get("deletePartnerAccount") === "on";
          const message = deletePartnerAccount
            ? "Are you sure you want to delete this partner account completely? This will also delete the partner account along with their Stripe express account. This action cannot be undone."
            : "Are you sure you want to delete this partner's Stripe express account? This action cannot be undone.";
          const confirmed = window.confirm(message);
          if (!confirmed) {
            return;
          }

          await fetch("/api/admin/delete-partner-account", {
            method: "POST",
            body: JSON.stringify({
              email: formData.get("email"),
              deletePartnerAccount:
                formData.get("deletePartnerAccount") === "on",
            }),
          }).then(async (res) => {
            if (res.ok) {
              toast.success(
                deletePartnerAccount
                  ? "Partner account deleted!"
                  : "Stripe express account deleted!",
              );
            } else {
              const error = await res.text();
              toast.error(error);
            }
          });
        }}
      >
        <Form />
      </form>
    </div>
  );
}

const Form = () => {
  const { pending } = useFormStatus();

  return (
    <div className="flex flex-col space-y-4">
      <div className="relative flex w-full rounded-md shadow-sm">
        <input
          name="email"
          id="email"
          type="email"
          required
          disabled={pending}
          autoComplete="off"
          className={cn(
            "block w-full rounded-md border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm",
            pending && "bg-neutral-100",
          )}
          onPaste={(e: React.ClipboardEvent<HTMLInputElement>) => {
            // remove mailto: on paste
            e.preventDefault();
            const text = e.clipboardData.getData("text/plain");
            if (text.startsWith("mailto:")) {
              e.currentTarget.value = text.replace("mailto:", "");
            } else {
              e.currentTarget.value = text;
            }
          }}
          placeholder="panic@thedis.co"
          aria-invalid="true"
        />
        {pending && (
          <LoadingSpinner className="absolute inset-y-0 right-2 my-auto h-full w-5 text-neutral-400" />
        )}
      </div>
      <div className="flex items-center space-x-2">
        <input
          name="deletePartnerAccount"
          id="deletePartnerAccount"
          type="checkbox"
          disabled={pending}
          className="h-4 w-4 rounded border-neutral-300 text-neutral-600 focus:ring-neutral-500"
        />
        <label
          htmlFor="deletePartnerAccount"
          className="text-sm text-neutral-700"
        >
          Delete partner account as well
        </label>
      </div>
    </div>
  );
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/impersonate-user.tsx
================================================
"use client";

import { Button, LoadingSpinner } from "@dub/ui";
import { cn } from "@dub/utils";
import { useState } from "react";
import { useFormStatus } from "react-dom";
import { toast } from "sonner";
import UserInfo, { UserInfoProps } from "./user-info";

export function ImpersonateUser() {
  const [data, setData] = useState<UserInfoProps | null>(null);

  return (
    <div className="flex flex-col space-y-5">
      <form
        action={async (formData) => {
          await fetch("/api/admin/impersonate", {
            method: "POST",
            body: JSON.stringify({
              email: formData.get("email"),
            }),
          }).then(async (res) => {
            if (res.ok) {
              setData(await res.json());
            } else {
              const error = await res.text();
              toast.error(error);
            }
          });
        }}
      >
        <Form />
      </form>
      {data && (
        <form
          action={async () => {
            if (
              !confirm(
                `This will ban the user ${data.email} and delete all their workspaces and links. Are you sure?`,
              )
            ) {
              return;
            }
            await fetch("/api/admin/ban", {
              method: "POST",
              body: JSON.stringify({
                email: data.email,
              }),
            }).then(async (res) => {
              if (res.ok) {
                toast.success("User has been banned");
              } else {
                const error = await res.text();
                toast.error(error);
              }
            });
          }}
        >
          <UserInfo data={data} />
          <div className="mt-4">
            <BanButton />
          </div>
        </form>
      )}
    </div>
  );
}

const Form = () => {
  const { pending } = useFormStatus();

  return (
    <div className="relative flex w-full rounded-md shadow-sm">
      <input
        name="email"
        id="email"
        type="email"
        required
        disabled={pending}
        autoComplete="off"
        className={cn(
          "block w-full rounded-md border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm",
          pending && "bg-neutral-100",
        )}
        onPaste={(e: React.ClipboardEvent<HTMLInputElement>) => {
          // remove mailto: on paste
          e.preventDefault();
          const text = e.clipboardData.getData("text/plain");
          if (text.startsWith("mailto:")) {
            e.currentTarget.value = text.replace("mailto:", "");
          } else {
            e.currentTarget.value = text;
          }
        }}
        placeholder="panic@thedis.co"
        aria-invalid="true"
      />
      {pending && (
        <LoadingSpinner className="absolute inset-y-0 right-2 my-auto h-full w-5 text-neutral-400" />
      )}
    </div>
  );
};

const BanButton = () => {
  const { pending } = useFormStatus();
  return <Button text="Confirm Ban" loading={pending} variant="danger" />;
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/impersonate-workspace.tsx
================================================
"use client";

import { LoadingSpinner } from "@dub/ui";
import { cn } from "@dub/utils";
import { useState } from "react";
import { useFormStatus } from "react-dom";
import { toast } from "sonner";
import UserInfo, { UserInfoProps } from "./user-info";

export function ImpersonateWorkspace() {
  const [data, setData] = useState<UserInfoProps | null>(null);

  return (
    <div className="flex flex-col space-y-5">
      <form
        action={async (formData) => {
          await fetch("/api/admin/impersonate", {
            method: "POST",
            body: JSON.stringify({
              slug: formData.get("slug"),
            }),
          }).then(async (res) => {
            if (res.ok) {
              setData(await res.json());
            } else {
              const error = await res.text();
              toast.error(error);
            }
          });
        }}
      >
        <Form />
      </form>
      {data && <UserInfo data={data} />}
    </div>
  );
}

const Form = () => {
  const { pending } = useFormStatus();

  return (
    <div className="relative flex w-full rounded-md shadow-sm">
      <span className="inline-flex items-center rounded-l-md border border-r-0 border-neutral-300 bg-neutral-50 px-5 text-neutral-500 sm:text-sm">
        app.dub.co
      </span>
      <input
        name="slug"
        id="slug"
        type="text"
        required
        disabled={pending}
        autoComplete="off"
        className={cn(
          "block w-full rounded-r-md border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm",
          pending && "bg-neutral-100",
        )}
        placeholder="owd"
        aria-invalid="true"
      />
      {pending && (
        <LoadingSpinner className="absolute inset-y-0 right-2 my-auto h-full w-5 text-neutral-400" />
      )}
    </div>
  );
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/refresh-domain.tsx
================================================
"use client";

import { LoadingSpinner } from "@dub/ui";
import { cn } from "@dub/utils";
import { useFormStatus } from "react-dom";
import { toast } from "sonner";

export function RefreshDomain() {
  return (
    <div className="flex flex-col space-y-5">
      <form
        action={async (data) =>
          await fetch("/api/admin/refresh-domain", {
            method: "POST",
            body: JSON.stringify({
              domain: data.get("domain"),
            }),
          })
            .then((res) => res.json())
            .then((res) => {
              if (res.error) {
                toast.error(res.error);
              } else {
                toast.success("Domain has been refreshed");
              }
            })
        }
      >
        <Form />
      </form>
    </div>
  );
}

const Form = () => {
  const { pending } = useFormStatus();

  return (
    <div className="relative flex w-full rounded-md shadow-sm">
      <input
        name="domain"
        id="domain"
        type="text"
        required
        disabled={pending}
        autoComplete="off"
        className={cn(
          "block w-full rounded-md border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm",
          pending && "bg-neutral-100",
        )}
        placeholder="acme.com"
        aria-invalid="true"
      />
      {pending && (
        <LoadingSpinner className="absolute inset-y-0 right-2 my-auto h-full w-5 text-neutral-400" />
      )}
    </div>
  );
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/reset-login-attempts.tsx
================================================
"use client";

import { LoadingSpinner } from "@dub/ui";
import { cn } from "@dub/utils";
import { useFormStatus } from "react-dom";
import { toast } from "sonner";

export function ResetLoginAttempts() {
  return (
    <div className="flex flex-col space-y-5">
      <form
        action={async (data) =>
          await fetch("/api/admin/reset-login-attempts", {
            method: "POST",
            body: JSON.stringify({
              email: data.get("email"),
            }),
          })
            .then((res) => res.json())
            .then((res) => {
              if (res.error) {
                toast.error(res.error);
              } else {
                toast.success("Login attempts have been reset");
              }
            })
        }
      >
        <Form />
      </form>
    </div>
  );
}

const Form = () => {
  const { pending } = useFormStatus();

  return (
    <div className="relative flex w-full rounded-md shadow-sm">
      <input
        name="email"
        id="email"
        type="email"
        required
        disabled={pending}
        autoComplete="off"
        className={cn(
          "block w-full rounded-md border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:outline-none focus:ring-neutral-500 sm:text-sm",
          pending && "bg-neutral-100",
        )}
        placeholder="user@example.com"
        aria-invalid="true"
      />
      {pending && (
        <LoadingSpinner className="absolute inset-y-0 right-2 my-auto h-full w-5 text-neutral-400" />
      )}
    </div>
  );
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/user-info.tsx
================================================
"use client";
import { PartnerStatusBadges } from "@/ui/partners/partner-status-badges";
import { Badge, Copy, StatusBadge, Tick, useCopyToClipboard } from "@dub/ui";
import { capitalize, currencyFormatter, nFormatter } from "@dub/utils";
import { toast } from "sonner";

export interface UserInfoProps {
  email: string;
  workspaces: {
    id: string;
    name: string;
    slug: string;
    plan: string;
    clicks: number;
    links: number;
    totalClicks: number;
    totalLinks: number;
  }[];
  programs: {
    id: string;
    name: string;
    slug: string;
    status: string;
    totalClicks: number;
    totalLeads: number;
    totalConversions: number;
    totalSaleAmount: number;
    totalCommissions: number;
  }[];
  impersonateUrl: {
    app: string;
    partners: string;
  };
}

const workspaceItems = [
  { id: "clicks", label: "Clicks" },
  { id: "links", label: "Links" },
  { id: "totalClicks", label: "Total Clicks" },
  { id: "totalLinks", label: "Total Links" },
];

const programItems = [
  { id: "totalClicks", label: "Total Clicks" },
  { id: "totalLeads", label: "Total Leads" },
  { id: "totalConversions", label: "Total Conversions" },
  { id: "totalSaleAmount", label: "Total Sales", isCurrency: true },
  { id: "totalCommissions", label: "Total Commissions", isCurrency: true },
];

export default function UserInfo({ data }: { data: UserInfoProps }) {
  return (
    <div className="grid gap-4">
      <LoginLinkCopyButton text={data.email} url={data.email} />
      <LoginLinkCopyButton
        text="app.dub.co login link"
        url={data.impersonateUrl.app}
      />
      <LoginLinkCopyButton
        text="partners.dub.co login link"
        url={data.impersonateUrl.partners}
      />

      {data.workspaces.length > 0 && (
        <div>
          <h3 className="mb-2 text-sm font-semibold text-neutral-900">
            Workspaces
          </h3>
          <div className="grid grid-cols-2 gap-4">
            {data.workspaces.map((workspace) => (
              <div
                key={workspace.slug}
                className="flex flex-col space-y-2 rounded-lg border border-neutral-200 p-2"
              >
                <div className="flex items-center space-x-2">
                  <p className="font-semibold">{workspace.name}</p>
                  <Badge className="lowercase">{workspace.slug}</Badge>
                </div>
                <div className="flex justify-between text-sm">
                  <span className="font-medium text-neutral-700">ID</span>
                  <span className="text-neutral-500">{workspace.id}</span>
                </div>
                <div className="flex justify-between text-sm">
                  <span className="font-medium text-neutral-700">Plan</span>
                  <span className="text-neutral-500">
                    {capitalize(workspace.plan)}
                  </span>
                </div>
                {workspaceItems.map((item) => (
                  <div key={item.id} className="flex justify-between text-sm">
                    <span className="font-medium text-neutral-700">
                      {item.label}
                    </span>
                    <span className="text-neutral-500">
                      {nFormatter(workspace[item.id], { full: true })}
                    </span>
                  </div>
                ))}
              </div>
            ))}
          </div>
        </div>
      )}

      {data.workspaces.length > 0 && data.programs.length > 0 && (
        <div className="my-2 border-b border-neutral-200" />
      )}

      {data.programs.length > 0 && (
        <div>
          <h3 className="mb-2 text-sm font-semibold text-neutral-900">
            Programs
          </h3>
          <div className="grid grid-cols-2 gap-4">
            {data.programs.map((program) => (
              <div
                key={program.id}
                className="flex flex-col space-y-2 rounded-lg border border-neutral-200 p-2"
              >
                <div className="flex items-center space-x-2">
                  <p className="font-semibold">{program.name}</p>
                  <Badge className="lowercase">{program.slug}</Badge>
                </div>
                <div className="flex justify-between text-sm">
                  <span className="font-medium text-neutral-700">ID</span>
                  <span className="text-neutral-500">{program.id}</span>
                </div>
                <div className="flex justify-between text-sm">
                  <span className="font-medium text-neutral-700">Status</span>
                  <StatusBadge
                    variant={PartnerStatusBadges[program.status].variant}
                  >
                    {PartnerStatusBadges[program.status].label}
                  </StatusBadge>
                </div>
                {programItems.map((item) => (
                  <div key={item.id} className="flex justify-between text-sm">
                    <span className="font-medium text-neutral-700">
                      {item.label}
                    </span>
                    <span className="text-neutral-500">
                      {item.isCurrency
                        ? currencyFormatter(program[item.id])
                        : nFormatter(program[item.id], { full: true })}
                    </span>
                  </div>
                ))}
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

const LoginLinkCopyButton = ({ text, url }: { text: string; url: string }) => {
  const [copied, copyToClipboard] = useCopyToClipboard();

  return (
    <div className="flex w-full items-center space-x-3">
      <div className="w-full rounded-md border border-neutral-300 px-4 py-2 text-sm text-neutral-900">
        {text}
      </div>
      <button
        type="button"
        onClick={() =>
          toast.promise(copyToClipboard(url), {
            success: "Copied to clipboard",
          })
        }
        className="rounded-md border border-neutral-300 p-2"
      >
        {copied ? (
          <Tick className="h-5 w-5 text-neutral-500" />
        ) : (
          <Copy className="h-5 w-5 text-neutral-500" />
        )}
      </button>
    </div>
  );
};


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/events/page.tsx
================================================
import Events from "@/ui/analytics/events";
import { EventsProvider } from "@/ui/analytics/events/events-provider";
import LayoutLoader from "@/ui/layout/layout-loader";
import AnalyticsClient from "app/app.dub.co/(dashboard)/[slug]/analytics/client";
import { Suspense } from "react";

export default function AdminEvents() {
  return (
    <Suspense fallback={<LayoutLoader />}>
      <AnalyticsClient eventsPage>
        <EventsProvider>
          <Events adminPage />
        </EventsProvider>
      </AnalyticsClient>
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/layout-nav-client.tsx
================================================
"use client";

import {
  ClientOnly,
  MaxWidthWrapper,
  NavWordmark,
  Popover,
  useMediaQuery,
} from "@dub/ui";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";

const tabs = [
  {
    href: "/links",
    label: "Links",
  },
  {
    href: "/analytics",
    label: "Analytics",
  },
  {
    href: "/commissions",
    label: "Commissions",
  },
  {
    href: "/payouts",
    label: "Payouts",
  },
  {
    href: "/revenue",
    label: "Revenue",
  },
];

export function AdminNav() {
  const [openPopover, setOpenPopover] = useState(false);
  const { isMobile } = useMediaQuery();
  const pathname = usePathname();

  const NavContent = () => (
    <div className="flex w-full flex-col gap-1 p-2">
      {tabs.map((tab) => {
        const isActive =
          pathname === tab.href || pathname?.startsWith(`${tab.href}/`);
        return (
          <Link
            href={tab.href}
            key={tab.href}
            className={`block w-full rounded-md px-4 py-2 text-left text-sm text-neutral-700 transition-colors hover:bg-neutral-100 active:bg-neutral-200 ${
              isActive ? "bg-neutral-100" : ""
            }`}
            onClick={() => setOpenPopover(false)}
          >
            {tab.label}
          </Link>
        );
      })}
    </div>
  );

  return (
    <div className="sticky left-0 right-0 top-0 z-20 border-b border-neutral-200 bg-white">
      <MaxWidthWrapper>
        <div className="flex h-16 w-full items-center justify-between sm:justify-start sm:gap-12">
          <Link href="/">
            <NavWordmark className="h-6" />
          </Link>
          <ClientOnly>
            {isMobile ? (
              <div className="ml-auto">
                <Popover
                  content={<NavContent />}
                  openPopover={openPopover}
                  setOpenPopover={setOpenPopover}
                  mobileOnly
                >
                  <button className="text-neutral-500">
                    <svg
                      width="24"
                      height="24"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                    >
                      <line x1="3" y1="12" x2="21" y2="12" />
                      <line x1="3" y1="6" x2="21" y2="6" />
                      <line x1="3" y1="18" x2="21" y2="18" />
                    </svg>
                  </button>
                </Popover>
              </div>
            ) : (
              <div className="flex items-center gap-4">
                {tabs.map((tab) => {
                  const isActive =
                    pathname === tab.href ||
                    pathname?.startsWith(`${tab.href}/`);
                  return (
                    <Link
                      href={tab.href}
                      key={tab.href}
                      className={`rounded-md px-3 py-1.5 text-sm transition-colors ${
                        isActive
                          ? "bg-neutral-100 text-neutral-900"
                          : "text-neutral-500 hover:text-neutral-700"
                      }`}
                    >
                      {tab.label}
                    </Link>
                  );
                })}
              </div>
            )}
          </ClientOnly>
        </div>
      </MaxWidthWrapper>
    </div>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/layout.tsx
================================================
import { constructMetadata } from "@dub/utils";
import { ReactNode } from "react";
import { AdminNav } from "./layout-nav-client";

export const metadata = constructMetadata({ noIndex: true });

export default function AdminLayout({ children }: { children: ReactNode }) {
  return (
    <>
      <div className="min-h-screen w-full bg-neutral-50">
        <AdminNav />
        {children}
      </div>
    </>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/links/page.tsx
================================================
import AdminLinksClient from "app/app.dub.co/(dashboard)/[slug]/links/page-client";
import { Suspense } from "react";

export default function AdminLinks() {
  return (
    <Suspense>
      <AdminLinksClient />
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/page.tsx
================================================
import { constructMetadata } from "@dub/utils";
import { BanLink } from "./components/ban-link";
import { DeletePartnerAccount } from "./components/delete-partner-account";
import { ImpersonateUser } from "./components/impersonate-user";
import { ImpersonateWorkspace } from "./components/impersonate-workspace";
import { RefreshDomain } from "./components/refresh-domain";
import { ResetLoginAttempts } from "./components/reset-login-attempts";

export const metadata = constructMetadata({
  title: "Dub Admin",
  noIndex: true,
});

export default function AdminPage() {
  return (
    <div className="mx-auto flex w-full max-w-screen-sm flex-col divide-y divide-neutral-200 overflow-auto bg-white">
      <div className="flex flex-col space-y-4 px-5 py-10">
        <h2 className="text-xl font-semibold">Impersonate User</h2>
        <p className="text-sm text-neutral-500">Get a login link for a user</p>
        <ImpersonateUser />
      </div>
      <div className="flex flex-col space-y-4 px-5 py-10">
        <h2 className="text-xl font-semibold">Impersonate Workspace</h2>
        <p className="text-sm text-neutral-500">
          Get a login link for the owner of a workspace
        </p>
        <ImpersonateWorkspace />
      </div>
      <div className="flex flex-col space-y-4 px-5 py-10">
        <h2 className="text-xl font-semibold">Ban Link</h2>
        <p className="text-sm text-neutral-500">Ban a dub.sh link</p>
        <BanLink />
      </div>
      <div className="flex flex-col space-y-4 px-5 py-10">
        <h2 className="text-xl font-semibold">Delete Stripe Express Account</h2>
        <p className="text-sm text-neutral-500">
          Delete a partner's Stripe express account (and potentially their
          partner account as well). <br />
          <br />
          Caveats:
          <br />- If the partner has already received payouts via Stripe, their
          Stripe Express account won't be deleted.
          <br />- If the partner has already received commissions or leads on
          Dub, their partner account won't be deleted.
        </p>
        <DeletePartnerAccount />
      </div>
      <div className="flex flex-col space-y-4 px-5 py-10">
        <h2 className="text-xl font-semibold">Refresh Domain</h2>
        <p className="text-sm text-neutral-500">
          Remove and re-add domain from Vercel
        </p>
        <RefreshDomain />
      </div>
      <div className="flex flex-col space-y-4 px-5 py-10">
        <h2 className="text-xl font-semibold">Reset Login Attempts</h2>
        <p className="text-sm text-neutral-500">
          Reset a user's invalidLoginAttempts and lockedAt fields
        </p>
        <ResetLoginAttempts />
      </div>
    </div>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/client.tsx
================================================
"use client";

import { formatDateTooltip } from "@/lib/analytics/format-date-tooltip";
import { AnalyticsLoadingSpinner } from "@/ui/analytics/analytics-loading-spinner";
import { PayoutStatusBadges } from "@/ui/partners/payout-status-badges";
import { FilterButtonTableRow } from "@/ui/shared/filter-button-table-row";
import SimpleDateRangePicker from "@/ui/shared/simple-date-range-picker";
import { InvoiceStatus } from "@dub/prisma/client";
import {
  Button,
  Filter,
  StatusBadge,
  Table,
  usePagination,
  useRouterStuff,
  useTable,
} from "@dub/ui";
import { Areas, TimeSeriesChart, XAxis, YAxis } from "@dub/ui/charts";
import { CircleDotted, GridIcon, Paypal } from "@dub/ui/icons";
import {
  cn,
  currencyFormatter,
  fetcher,
  formatDateTime,
  OG_AVATAR_URL,
} from "@dub/utils";
import NumberFlow from "@number-flow/react";
import Link from "next/link";
import { Fragment, useCallback, useMemo, useState } from "react";
import useSWR from "swr";

interface TimeseriesData {
  date: Date;
  payouts: number;
  fees: number;
  total: number;
}

interface InvoiceData {
  date: Date;
  programId: string;
  programName: string;
  programLogo: string;
  status: InvoiceStatus;
  amount: number;
  fee: number;
  total: number;
}

type Tab = {
  id: "payouts" | "fees" | "total";
  label: string;
  colorClassName: string;
};

export default function PayoutsPageClient() {
  const { queryParams, getQueryString, searchParamsObj } = useRouterStuff();
  const { interval, start, end, status, programId } = searchParamsObj;

  const { data: { invoices, timeseriesData } = {}, isLoading } = useSWR<{
    invoices: InvoiceData[];
    timeseriesData: TimeseriesData[];
  }>(`/api/admin/payouts${getQueryString()}`, fetcher, {
    keepPreviousData: true,
  });

  // Extract unique programs from invoices
  const programs = useMemo(() => {
    if (!invoices) return [];
    const programMap = new Map<
      string,
      { id: string; name: string; logo: string }
    >();
    invoices.forEach((invoice) => {
      if (!programMap.has(invoice.programId)) {
        programMap.set(invoice.programId, {
          id: invoice.programId,
          name: invoice.programName,
          logo: invoice.programLogo,
        });
      }
    });
    return Array.from(programMap.values()).sort((a, b) =>
      a.name.localeCompare(b.name),
    );
  }, [invoices]);

  // Filter configuration
  const filters = useMemo(
    () => [
      {
        key: "programId",
        icon: GridIcon,
        label: "Program",
        options:
          programs.map((program) => ({
            value: program.id,
            label: program.name,
            icon: (
              <img
                src={program.logo || `${OG_AVATAR_URL}${program.name}`}
                alt={`${program.name} image`}
                className="size-4 rounded-full"
              />
            ),
          })) ?? null,
      },
      {
        key: "status",
        icon: CircleDotted,
        label: "Status",
        options: Object.entries(PayoutStatusBadges)
          .filter(([key]) =>
            ["processing", "completed", "failed"].includes(key),
          )
          .map(([value, { label }]) => {
            const Icon =
              PayoutStatusBadges[value as keyof typeof PayoutStatusBadges].icon;
            return {
              value,
              label,
              icon: (
                <Icon
                  className={cn(
                    PayoutStatusBadges[value as keyof typeof PayoutStatusBadges]
                      .className,
                    "size-4 bg-transparent",
                  )}
                />
              ),
            };
          }),
      },
    ],
    [programs],
  );

  const activeFilters = useMemo(() => {
    return [
      ...(programId ? [{ key: "programId", value: programId }] : []),
      ...(status ? [{ key: "status", value: status }] : []),
    ];
  }, [programId, status]);

  const onSelect = useCallback(
    (key: string, value: any) =>
      queryParams({
        set: {
          [key]: value,
        },
        del: "page",
      }),
    [queryParams],
  );

  const onRemove = useCallback(
    (key: string) =>
      queryParams({
        del: [key, "page"],
      }),
    [queryParams],
  );

  const onRemoveAll = useCallback(
    () =>
      queryParams({
        del: ["status", "programId"],
      }),
    [queryParams],
  );

  const tabs: Tab[] = [
    {
      id: "payouts",
      label: "Payouts",
      colorClassName: "text-blue-500/50 bg-blue-500/50 border-blue-500",
    },
    {
      id: "fees",
      label: "Fees",
      colorClassName: "text-red-500/50 bg-red-500/50 border-red-500",
    },
    {
      id: "total",
      label: "Total",
      colorClassName: "text-green-500/50 bg-green-500/50 border-green-500",
    },
  ];

  const [selectedTab, setSelectedTab] = useState<"payouts" | "fees" | "total">(
    "payouts",
  );
  const tab = tabs.find(({ id }) => id === selectedTab) ?? tabs[0];

  // take the last 12 months
  const chartData =
    timeseriesData?.map(({ date, ...rest }) => ({
      date: new Date(date),
      values: {
        value: rest[selectedTab],
      },
    })) ?? null;

  const dateFormatter = (date: Date) =>
    date.toLocaleDateString("en-US", {
      month: "short",
      year: "numeric",
      timeZone: "UTC",
    });

  const totals = useMemo(() => {
    return {
      payouts:
        timeseriesData?.reduce((acc, { payouts }) => acc + payouts, 0) ?? 0,
      fees: timeseriesData?.reduce((acc, { fees }) => acc + fees, 0) ?? 0,
      total: timeseriesData?.reduce((acc, { total }) => acc + total, 0) ?? 0,
    };
  }, [timeseriesData]);

  const { pagination, setPagination } = usePagination();

  const { table, ...tableProps } = useTable({
    data: invoices ?? [],
    columns: [
      {
        id: "date",
        header: "Payment Date (UTC)",
        accessorKey: "date",
        cell: ({ row }) =>
          formatDateTime(row.original.date, {
            timeZone: "UTC",
          }),
      },
      {
        id: "program",
        header: "Program",
        cell: ({ row }) => (
          <div className="flex items-center gap-1.5">
            <img
              src={row.original.programLogo}
              alt={row.original.programName}
              width={20}
              height={20}
              className="size-4 rounded-full"
            />
            <span className="text-sm font-medium">
              {row.original.programName}
            </span>
          </div>
        ),
        meta: {
          filterParams: ({ row }) => ({
            programId: row.original.programId,
          }),
        },
      },
      {
        id: "status",
        header: "Status",
        cell: ({ row }) => {
          const badge = PayoutStatusBadges[row.original.status];

          return badge ? (
            <StatusBadge icon={badge.icon} variant={badge.variant}>
              {badge.label}
            </StatusBadge>
          ) : (
            "-"
          );
        },
        meta: {
          filterParams: ({ row }) => ({
            status: row.original.status,
          }),
        },
      },
      {
        id: "amount",
        header: "Amount",
        accessorKey: "amount",
        cell: ({ row }) => currencyFormatter(row.original.amount),
      },
      {
        id: "fee",
        header: "Fee",
        accessorKey: "fee",
        cell: ({ row }) => currencyFormatter(row.original.fee),
      },
      {
        id: "total",
        header: "Total",
        accessorKey: "total",
        cell: ({ row }) => currencyFormatter(row.original.total),
      },
    ],
    pagination,
    onPaginationChange: setPagination,
    resourceName: (plural) => `invoice${plural ? "s" : ""}`,
    rowCount: invoices?.length ?? 0,
    loading: isLoading,
    cellRight: (cell) => {
      const meta = cell.column.columnDef.meta as
        | {
            filterParams?: any;
          }
        | undefined;

      return (
        meta?.filterParams && (
          <FilterButtonTableRow set={meta.filterParams(cell)} />
        )
      );
    },
  });

  return (
    <div className="mx-auto flex w-full max-w-screen-xl flex-col gap-3 p-6">
      <div className="flex flex-col gap-3 md:flex-row md:items-center">
        <Filter.Select
          className="w-full md:w-fit"
          filters={filters}
          activeFilters={activeFilters}
          onSelect={onSelect}
          onRemove={onRemove}
        />
        <SimpleDateRangePicker
          defaultInterval="mtd"
          className="w-full sm:min-w-[200px] md:w-fit"
        />
        <Link href="/payouts/paypal">
          <Button
            variant="secondary"
            text="Paypal payouts"
            icon={<Paypal className="size-4" />}
          />
        </Link>
      </div>
      {activeFilters.length > 0 && (
        <div>
          <Filter.List
            filters={filters}
            activeFilters={activeFilters}
            onSelect={onSelect}
            onRemove={onRemove}
            onRemoveAll={onRemoveAll}
          />
        </div>
      )}
      <div className="flex flex-col divide-y divide-neutral-200 rounded-lg border border-neutral-200 bg-white">
        <div className="scrollbar-hide grid w-full grid-cols-1 divide-y overflow-y-hidden sm:grid-cols-3 sm:divide-x sm:divide-y-0">
          {tabs.map(({ id, label, colorClassName }) => {
            return (
              <button
                key={id}
                onClick={() => {
                  setSelectedTab(id);
                  queryParams({
                    set: { tab: id },
                  });
                }}
                className={cn(
                  "border-box relative block h-full w-full flex-none px-4 py-3 sm:px-8 sm:py-6",
                  "transition-colors hover:bg-neutral-50 focus:outline-none active:bg-neutral-100",
                  "ring-inset ring-neutral-500 focus-visible:ring-1 sm:first:rounded-tl-xl",
                )}
              >
                {/* Active tab indicator */}
                {selectedTab === id && (
                  <div className="absolute bottom-0 left-0 h-0.5 w-full bg-black" />
                )}
                <div className="flex items-center gap-2.5 text-sm text-neutral-600">
                  <div
                    className={cn(
                      "h-2 w-2 rounded-sm bg-current shadow-[inset_0_0_0_1px_#00000019]",
                      colorClassName,
                    )}
                  />
                  <span>{label}</span>
                </div>
                <div className="mt-1 flex h-12 items-center">
                  {(totals[id] || totals[id] === 0) && !isLoading ? (
                    <NumberFlow
                      value={(totals[id] ?? 0) / 100}
                      className="text-xl font-medium sm:text-3xl"
                      format={{
                        style: "currency",
                        currency: "USD",
                        // @ts-ignore – trailingZeroDisplay is a valid option but TS is outdated
                        trailingZeroDisplay: "stripIfInteger",
                      }}
                    />
                  ) : (
                    <div className="h-10 w-24 animate-pulse rounded-md bg-neutral-200" />
                  )}
                </div>
              </button>
            );
          })}
        </div>
        <div className="p-5 sm:p-10">
          <div className="flex h-96 w-full items-center justify-center">
            {chartData ? (
              chartData.length > 0 ? (
                <TimeSeriesChart
                  data={chartData}
                  series={[
                    {
                      id: "value",
                      valueAccessor: (d) => d.values.value,
                      isActive: true,
                      colorClassName: tab.colorClassName,
                    },
                  ]}
                  tooltipClassName="p-0"
                  tooltipContent={(d) => (
                    <>
                      <p className="border-b border-neutral-200 px-4 py-3 text-sm text-neutral-900">
                        {formatDateTooltip(d.date, {
                          interval,
                          start,
                          end,
                          timezone: "UTC",
                        })}
                      </p>
                      <div className="grid grid-cols-2 gap-x-6 gap-y-2 px-4 py-3 text-sm">
                        <Fragment>
                          <div className="flex items-center gap-2">
                            <div
                              className={cn(
                                "h-2 w-2 rounded-sm shadow-[inset_0_0_0_1px_#0003]",
                                tab.colorClassName,
                              )}
                            />
                            <p className="capitalize text-neutral-600">
                              {tab.label}
                            </p>
                          </div>
                          <p className="text-right font-medium text-neutral-900">
                            {currencyFormatter(d.values.value)}
                          </p>
                        </Fragment>
                      </div>
                    </>
                  )}
                >
                  <Areas />
                  <XAxis maxTicks={5} tickFormat={dateFormatter} />
                  <YAxis
                    showGridLines
                    tickFormat={(value) => currencyFormatter(value)}
                  />
                </TimeSeriesChart>
              ) : (
                <div className="text-center text-sm text-neutral-600">
                  No data available.
                </div>
              )
            ) : (
              <AnalyticsLoadingSpinner />
            )}
          </div>
        </div>
      </div>

      <div className="w-full">
        <Table {...tableProps} table={table} />
      </div>
    </div>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/page.tsx
================================================
import { Suspense } from "react";
import PayoutsPageClient from "./client";

export default async function PayoutsPage() {
  return (
    <Suspense>
      <PayoutsPageClient />
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/paypal/client.tsx
================================================
"use client";

import type { PaypalPayoutResponse } from "@/lib/paypal/get-pending-payouts";
import { PartnerAvatar } from "@/ui/partners/partner-avatar";
import { PayoutStatusBadges } from "@/ui/partners/payout-status-badges";
import { FilterButtonTableRow } from "@/ui/shared/filter-button-table-row";
import {
  Button,
  StatusBadge,
  Table,
  usePagination,
  useRouterStuff,
  useTable,
} from "@dub/ui";
import { Globe } from "@dub/ui/icons";
import {
  cn,
  COUNTRIES,
  currencyFormatter,
  fetcher,
  nFormatter,
  OG_AVATAR_URL,
} from "@dub/utils";
import NumberFlow from "@number-flow/react";
import { ChevronLeft } from "lucide-react";
import Link from "next/link";
import { useMemo } from "react";
import useSWR from "swr";

export default function PaypalPayoutsPageClient() {
  const { getQueryString } = useRouterStuff();

  const { data: payouts = [], isLoading } = useSWR<PaypalPayoutResponse[]>(
    `/api/admin/payouts/paypal${getQueryString()}`,
    fetcher,
    {
      keepPreviousData: true,
    },
  );

  const { pagination, setPagination } = usePagination(100);

  // Client-side pagination
  const paginatedPayouts = useMemo(() => {
    const start = (pagination.pageIndex - 1) * pagination.pageSize;
    const end = start + pagination.pageSize;
    return payouts.slice(start, end);
  }, [payouts, pagination.pageIndex, pagination.pageSize]);

  const { table, ...tableProps } = useTable({
    data: paginatedPayouts,
    columns: [
      {
        id: "partner",
        header: "Partner",
        cell: ({ row }) => (
          <div className="flex items-center gap-1.5">
            <PartnerAvatar partner={row.original.partner} className="size-4" />
            <span className="text-sm text-neutral-900">
              {row.original.partner.email || "-"}
            </span>
          </div>
        ),
      },
      {
        id: "country",
        header: "Country",
        accessorKey: "partner.country",
        meta: {
          filterParams: ({ getValue }) => ({ country: getValue() }),
        },
        cell: ({ row }) => {
          const country = row.original.partner.country;
          if (!country || country === "Unknown") {
            return (
              <div className="flex items-center gap-3">
                <Globe className="size-4 shrink-0" />
                <span className="text-sm text-neutral-900">Unknown</span>
              </div>
            );
          }
          return (
            <div
              className="flex items-center gap-3"
              title={COUNTRIES[country] ?? country}
            >
              <img
                alt={country}
                src={`https://hatscripts.github.io/circle-flags/flags/${country.toLowerCase()}.svg`}
                className="size-4 shrink-0"
              />
              <span className="truncate text-sm text-neutral-900">
                {COUNTRIES[country] ?? country}
              </span>
            </div>
          );
        },
      },
      {
        id: "program",
        header: "Program",
        accessorKey: "program.id",
        meta: {
          filterParams: ({ getValue }) => ({ programId: getValue() }),
        },
        cell: ({ row }) => (
          <div className="flex items-center gap-1.5">
            <img
              src={
                row.original.program.logo ||
                `${OG_AVATAR_URL}${row.original.program.name}`
              }
              alt={row.original.program.name}
              width={20}
              height={20}
              className="size-4 rounded-full"
            />
            <span className="text-sm font-medium">
              {row.original.program.name}
            </span>
          </div>
        ),
      },
      {
        id: "status",
        header: "Status",
        cell: ({ row }) => {
          const badge = PayoutStatusBadges[row.original.status];

          return badge ? (
            <StatusBadge icon={badge.icon} variant={badge.variant}>
              {badge.label}
            </StatusBadge>
          ) : (
            "-"
          );
        },
      },
      {
        id: "amount",
        header: "Amount",
        accessorKey: "amount",
        cell: ({ row }) => currencyFormatter(row.original.amount),
      },
    ],
    pagination,
    onPaginationChange: setPagination,
    resourceName: (plural) => `payout${plural ? "s" : ""}`,
    rowCount: payouts.length,
    loading: isLoading,
    cellRight: (cell) => {
      const meta = cell.column.columnDef.meta as
        | {
            filterParams?: any;
          }
        | undefined;

      return (
        meta?.filterParams && (
          <FilterButtonTableRow set={meta.filterParams(cell)} />
        )
      );
    },
  });

  const stats = useMemo(() => {
    const allPayouts = payouts;
    const processingPayouts = payouts.filter((p) => p.status === "processing");
    const pendingPayouts = payouts.filter((p) => p.status === "pending");

    return [
      {
        id: "all",
        label: "Total payouts",
        amount: allPayouts.reduce((acc, p) => acc + p.amount, 0),
        count: allPayouts.length,
        colorClassName: "bg-blue-500",
      },
      {
        id: "processing",
        label: "Processing payouts",
        amount: processingPayouts.reduce((acc, p) => acc + p.amount, 0),
        count: processingPayouts.length,
        colorClassName: "bg-purple-500",
      },
      {
        id: "pending",
        label: "Pending payouts",
        amount: pendingPayouts.reduce((acc, p) => acc + p.amount, 0),
        count: pendingPayouts.length,
        colorClassName: "bg-orange-500",
      },
    ];
  }, [payouts]);

  return (
    <div className="mx-auto flex w-full max-w-screen-xl flex-col gap-3 p-6">
      <div className="flex items-center justify-start">
        <Link href="/payouts">
          <Button
            variant="secondary"
            text="Back to all payouts"
            icon={<ChevronLeft className="size-4" />}
          />
        </Link>
      </div>
      <div className="grid grid-cols-1 divide-y divide-neutral-200 rounded-lg border border-neutral-200 bg-white sm:grid-cols-3 sm:flex-row sm:divide-x sm:divide-y-0">
        {stats.map(({ id, label, amount, count, colorClassName }) => (
          <div key={id} className="flex-none px-4 py-3 sm:px-8 sm:py-6">
            <div className="flex items-center gap-2.5 text-sm text-neutral-600">
              <div
                className={cn(
                  "h-2 w-2 rounded-sm shadow-[inset_0_0_0_1px_#00000019]",
                  colorClassName,
                )}
              />
              <span>{label}</span>
            </div>
            <div className="mt-1 flex h-12 items-center">
              {!isLoading ? (
                <div className="flex items-baseline gap-2">
                  <NumberFlow
                    value={amount / 100}
                    className="text-xl font-medium sm:text-3xl"
                    format={{
                      style: "currency",
                      currency: "USD",
                    }}
                  />
                  <span className="text-sm text-neutral-500">
                    ({nFormatter(count, { full: true })})
                  </span>
                </div>
              ) : (
                <div className="h-10 w-24 animate-pulse rounded-md bg-neutral-200" />
              )}
            </div>
          </div>
        ))}
      </div>
      <div className="w-full">
        <Table {...tableProps} table={table} />
      </div>
    </div>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/paypal/page.tsx
================================================
import { Suspense } from "react";
import PaypalPayoutsPageClient from "./client";

export default async function PaypalPayoutsPage() {
  return (
    <Suspense>
      <PaypalPayoutsPageClient />
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/revenue/client.tsx
================================================
"use client";

import SimpleDateRangePicker from "@/ui/shared/simple-date-range-picker";
import {
  CrownSmall,
  Table,
  usePagination,
  useRouterStuff,
  useTable,
} from "@dub/ui";
import { cn, currencyFormatter, fetcher, nFormatter } from "@dub/utils";
import NumberFlow from "@number-flow/react";
import { useMemo } from "react";
import useSWR from "swr";

export default function RevenuePageClient() {
  const { getQueryString } = useRouterStuff();

  const { data: { programs } = {}, isLoading } = useSWR<{
    programs: {
      id: string;
      name: string;
      logo: string;
      partners: number;
      sales: number;
      saleAmount: number;
    }[];
  }>(`/api/admin/revenue${getQueryString()}`, fetcher, {
    keepPreviousData: true,
  });

  const { pagination, setPagination } = usePagination();

  const { table, ...tableProps } = useTable({
    data: programs ?? [],
    columns: [
      {
        id: "position",
        header: "Position",
        size: 12,
        minSize: 12,
        maxSize: 12,
        cell: ({ row }) => {
          return (
            <div className="flex w-28 items-center justify-start gap-2 tabular-nums">
              {row.index + 1}
              {row.index <= 2 && (
                <CrownSmall
                  className={cn("size-4", {
                    "text-amber-400": row.index === 0,
                    "text-neutral-400": row.index === 1,
                    "text-yellow-900": row.index === 2,
                  })}
                />
              )}
            </div>
          );
        },
      },
      {
        id: "program",
        header: "Program",
        cell: ({ row }) => (
          <div className="flex items-center gap-1.5">
            <img
              src={row.original.logo}
              alt={row.original.name}
              width={20}
              height={20}
              className="size-4 rounded-full"
            />
            <span className="text-sm font-medium">{row.original.name}</span>
          </div>
        ),
      },
      {
        id: "partners",
        header: "Active Partners",
        accessorKey: "partners",
        cell: ({ row }) => nFormatter(row.original.partners, { full: true }),
      },
      {
        id: "sales",
        header: "Total Sales",
        accessorKey: "sales",
        cell: ({ row }) => nFormatter(row.original.sales, { full: true }),
      },
      {
        id: "revenue",
        header: "Affiliate Revenue",
        accessorKey: "revenue",
        cell: ({ row }) => currencyFormatter(row.original.saleAmount),
      },
    ],
    pagination,
    onPaginationChange: setPagination,
    resourceName: (plural) => `program${plural ? "s" : ""}`,
    rowCount: programs?.length ?? 0,
    loading: isLoading,
  });

  const stats = useMemo(
    () => [
      {
        id: "partners",
        label: "Active Partners",
        value: programs?.reduce(
          (acc, { partners }) => acc + (partners || 0),
          0,
        ),
        colorClassName: "bg-blue-500",
      },
      {
        id: "sales",
        label: "Total Sales",
        value: programs?.reduce((acc, { sales }) => acc + (sales || 0), 0),
        colorClassName: "bg-green-500",
      },
      {
        id: "revenue",
        label: "Affiliate Revenue",
        value: programs?.reduce(
          (acc, { saleAmount }) => acc + (saleAmount || 0),
          0,
        ),
        colorClassName: "bg-purple-500",
      },
    ],
    [programs],
  );

  return (
    <div className="mx-auto flex w-full max-w-screen-xl flex-col space-y-6 p-6">
      <SimpleDateRangePicker defaultInterval="mtd" className="w-fit" />
      <div className="flex flex-col divide-y divide-neutral-200 rounded-lg border border-neutral-200 bg-white">
        <div className="grid w-full grid-cols-1 divide-x sm:grid-cols-3">
          {stats.map(({ id, label, value, colorClassName }) => (
            <div key={id} className="flex-none px-4 py-3 sm:px-8 sm:py-6">
              <div className="flex items-center gap-2.5 text-sm text-neutral-600">
                <div
                  className={cn(
                    "h-2 w-2 rounded-sm shadow-[inset_0_0_0_1px_#00000019]",
                    colorClassName,
                  )}
                />
                <span>{label}</span>
              </div>
              <div className="mt-1 flex h-12 items-center">
                {value !== undefined ? (
                  id === "revenue" ? (
                    <NumberFlow
                      value={value / 100}
                      className="text-xl font-medium sm:text-3xl"
                      format={{
                        style: "currency",
                        currency: "USD",
                        // @ts-ignore – trailingZeroDisplay is a valid option but TS is outdated
                        trailingZeroDisplay: "stripIfInteger",
                      }}
                    />
                  ) : (
                    <NumberFlow
                      value={value}
                      className="text-xl font-medium sm:text-3xl"
                    />
                  )
                ) : (
                  <div className="h-10 w-24 animate-pulse rounded-md bg-neutral-200" />
                )}
              </div>
            </div>
          ))}
        </div>
      </div>
      <div className="w-full">
        <Table {...tableProps} table={table} />
      </div>
    </div>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/revenue/page.tsx
================================================
import { Suspense } from "react";
import RevenuePageClient from "./client";

export default async function RevenuePage() {
  return (
    <Suspense>
      <RevenuePageClient />
    </Suspense>
  );
}


================================================
FILE: apps/web/app/(ee)/admin.dub.co/layout.tsx
================================================
"use client";

import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";

export default function AdminLayout({ children }: { children: ReactNode }) {
  return <SessionProvider>{children}</SessionProvider>;
}


================================================
FILE: apps/web/app/(ee)/api/admin/analytics/route.ts
================================================
import { getAnalytics } from "@/lib/analytics/get-analytics";
import { withAdmin } from "@/lib/auth";
import { parseAnalyticsQuery } from "@/lib/zod/schemas/analytics";
import { NextResponse } from "next/server";

// GET /api/admin/analytics – get analytics for admin
export const GET = withAdmin(async ({ searchParams }) => {
  const parsedParams = parseAnalyticsQuery(searchParams);

  const response = await getAnalytics(parsedParams);

  return NextResponse.json(response);
});


================================================
FILE: apps/web/app/(ee)/api/admin/ban/route.ts
================================================
import { deleteWorkspaceAdmin } from "@/lib/api/workspaces/delete-workspace";
import { withAdmin } from "@/lib/auth";
import { updateConfig } from "@/lib/edge-config";
import { isStored, storage } from "@/lib/storage";
import { prisma } from "@dub/prisma";
import { R2_URL } from "@dub/utils";
import { waitUntil } from "@vercel/functions";
import { NextResponse } from "next/server";

// POST /api/admin/ban
export const POST = withAdmin(async ({ req }) => {
  const { email } = await req.json();

  const user = await prisma.user.findUniqueOrThrow({
    where: {
      email,
    },
    select: {
      id: true,
      email: true,
      image: true,
      projects: {
        where: {
          role: "owner",
        },
        select: {
          project: {
            select: {
              id: true,
              slug: true,
              logo: true,
              stripeId: true,
            },
          },
        },
      },
    },
  });

  console.log(
    `Found user ${user.email} with ${user.projects.length} workspaces`,
  );

  waitUntil(
    Promise.all(
      user.projects.map(({ project }) => deleteWorkspaceAdmin(project)),
    ).then(async () => {
      await Promise.all([
        user.image &&
          isStored(user.image) &&
          storage.delete({ key: user.image.replace(`${R2_URL}/`, "") }),
        updateConfig({
          key: "emails",
          value: email,
        }),
      ]);

      // delete user
      await prisma.user.delete({
        where: {
          id: user.id,
        },
      });
    }),
  );

  return NextResponse.json({ success: true });
});


================================================
FILE: apps/web/app/(ee)/api/admin/commissions/get-commissions-timeseries.ts
================================================
import { sqlGranularityMap } from "@/lib/planetscale/granularity";
import { TZDate } from "@date-fns/tz";
import { prisma } from "@dub/prisma";
import { Prisma } from "@dub/prisma/client";
import { ACME_PROGRAM_ID } from "@dub/utils";
import { format } from "date-fns";

interface Commission {
  start: string;
  commissions: number;
}

export async function getCommissionsTimeseries({
  programId,
  startDate,
  endDate,
  granularity,
  timezone,
}: {
  programId?: string;
  startDate: Date;
  endDate: Date;
  granularity: string;
  timezone: string;
}) {
  const { dateFormat, dateIncrement, startFunction, formatString } =
    sqlGranularityMap[granularity];

  const commissions = await prisma.$queryRaw<Commission[]>`
        SELECT 
          DATE_FORMAT(CONVERT_TZ(createdAt, "UTC", ${timezone || "UTC"}), ${dateFormat}) AS start, 
          SUM(earnings) AS commissions
        FROM Commission
        WHERE 
          createdAt >= ${startDate}
          AND createdAt < ${endDate}
          AND status IN ("pending", "processed", "paid")
          AND ${programId ? Prisma.sql`programId = ${programId}` : Prisma.sql`programId != ${ACME_PROGRAM_ID}`}
        GROUP BY start
        ORDER BY start ASC;`;

  // Convert dates to TZDate with the specified timezone
  const tzStartDate = new TZDate(startDate, timezone || "UTC");
  const tzEndDate = new TZDate(endDate, timezone || "UTC");

  let currentDate = startFunction(tzStartDate);

  const commissionsLookup = Object.fromEntries(
    commissions.map((item) => [
      item.start,
      {
        commissions: Number(item.commissions),
      },
    ]),
  );

  const timeseries: Commission[] = [];

  while (currentDate < tzEndDate) {
    const periodKey = format(currentDate, formatString);

    timeseries.push({
      start: currentDate.toISOString(),
      ...(commissionsLookup[periodKey] || {
        commissions: 0,
      }),
    });

    currentDate = dateIncrement(currentDate);
  }
  return timeseries;
}


================================================
FILE: apps/web/app/(ee)/api/admin/commissions/get-top-program-by-commissions.ts
================================================
import { prisma } from "@dub/prisma";
import { ACME_PROGRAM_ID } from "@dub/utils";

export async function getTopProgramsByCommissions({
  programId,
  startDate,
  endDate,
}: {
  programId?: string;
  startDate: Date;
  endDate: Date;
}) {
  const programCommissions = await prisma.commission.groupBy({
    by: ["programId"],
    _sum: {
      earnings: true,
    },
    where: {
      createdAt: {
        gte: startDate,
        lte: endDate,
      },
      status: {
        in: ["pending", "processed", "paid"],
      },
      programId: programId || {
        not: ACME_PROGRAM_ID,
      },
    },
    orderBy: {
      _sum: {
        earnings: "desc",
      },
    },
    take: 50,
  });

  const topPrograms = await prisma.program.findMany({
    where: {
      id: {
        in: programCommissions.map(({ programId }) => programId),
      },
    },
    include: {
      workspace: {
        select: {
          payoutFee: true,
        },
      },
    },
  });

  const programIdMap = Object.fromEntries(
    topPrograms.map((program) => [program.id, program]),
  );

  const topProgramsWithCommissions = programCommissions
    .map(({ programId, _sum }) => {
      const program = programIdMap[programId];
      if (!program) return null;
      const commissions = _sum.earnings || 0;
      const payoutFee = program.workspace?.payoutFee || 0;
      return {
        ...program,
        commissions,
        fees: commissions * payoutFee,
      };
    })
    .filter(Boolean);

  return topProgramsWithCommissions;
}


================================================
FILE: apps/web/app/(ee)/api/admin/commissions/route.ts
================================================
import { getStartEndDates } from "@/lib/analytics/utils/get-start-end-dates";
import { withAdmin } from "@/lib/auth";
import { analyticsQuerySchema } from "@/lib/zod/schemas/analytics";
import { DUB_FOUNDING_DATE } from "@dub/utils";
import { endOfDay, startOfDay } from "date-fns";
import { NextResponse } from "next/server";
import * as z from "zod/v4";
import { getCommissionsTimeseries } from "./get-commissions-timeseries";
import { getTopProgramsByCommissions } from "./get-top-program-by-commissions";

const adminCommissionsQuerySchema = z
  .object({
    programId: z.string().optional(),
    timezone: z.string().optional().default("UTC"),
  })
  .extend(
    analyticsQuerySchema.pick({ interval: true, start: true, end: true }).shape,
  );

export const GET = withAdmin(async ({ searchParams }) => {
  const {
    programId,
    interval = "mtd",
    start,
    end,
    timezone = "UTC",
  } = adminCommissionsQuerySchema.parse(searchParams);

  const { startDate, endDate, granularity } = getStartEndDates({
    interval,
    start: start ? startOfDay(new Date(start)) : undefined,
    end: end ? endOfDay(new Date(end)) : undefined,
    dataAvailableFrom: DUB_FOUNDING_DATE,
    timezone,
  });

  const [programs, timeseries] = await Promise.all([
    getTopProgramsByCommissions({ programId, startDate, endDate }),
    getCommissionsTimeseries({
      programId,
      startDate,
      endDate,
      granularity,
      timezone,
    }),
  ]);

  return NextResponse.json({
    programs,
    timeseries,
  });
});


================================================
FILE: apps/web/app/(ee)/api/admin/delete-partner-account/route.ts
================================================
import { withAdmin } from "@/lib/auth";
import { conn } from "@/lib/planetscale";
import { stripe } from "@/lib/stripe";
import { recordLink } from "@/lib/tinybird";
import { prisma } from "@dub/prisma";
import { prettyPrint } from "@dub/utils";
import { NextResponse } from "next/server";

// POST /api/admin/delete-partner-account
export const POST = withAdmin(async ({ req }) => {
  const { email, deletePartnerAccount } = await req.json();

  const partner = await prisma.partner.findUnique({
    where: {
      email,
    },
    include: {
      commissions: true,
      programs: {
        select: {
          program: true,
          links: true,
          groupId: true,
        },
      },
    },
  });

  if (!partner) {
    return new Response("Partner not found", { status: 404 });
  }

  if (partner.stripeConnectId) {
    try {
      // check if stripe express account has received payouts before
      const transfers = await stripe.transfers.list({
        destination: partner.stripeConnectId,
        limit: 1,
      });

      if (transfers.data.length > 0) {
        return new Response(
          "Stripe express account has received payouts before and cannot be deleted.",
          {
            status: 400,
          },
        );
      }

      const res = await stripe.accounts.del(partner.stripeConnectId);
      console.log(
        `Deleted Stripe express account for partner ${partner.email}: `,
        prettyPrint(res),
      );
    } catch (error) {
      console.log(
        "Error deleting Stripe express account (probably already deleted): ",
        error,
      );
    }

    await prisma.partner.update({
      where: {
        id: partner.id,
      },
      data: {
        stripeConnectId: null,
        payoutsEnabledAt: null,
        payoutMethodHash: null,
      },
    });
    console.log(`Updated partner ${partner.email} with stripeConnectId null`);
  }

  if (deletePartnerAccount) {
    if (partner.commissions.length > 0) {
      return new Response(
        "Partner has already received commissions and cannot be deleted.",
        {
          status: 400,
        },
      );
    }
    if (
      partner.programs.some(({ links }) => links.some((link) => link.leads > 0))
    ) {
      return new Response(
        "Partner has already received leads and cannot be deleted.",
        {
          status: 400,
        },
      );
    }

    if (partner.programs.length > 0) {
      for (const { program, links, groupId } of partner.programs) {
        if (links.length > 0) {
          await Promise.allSettled([
            prisma.link.deleteMany({
              where: {
                id: {
                  in: links.map((link) => link.id),
                },
              },
            }),
            recordLink(
              links.map((link) => ({
                ...link,
                programEnrollment: { groupId },
              })),
              { deleted: true },
            ),
          ]);
          console.log(
            `Deleted ${links.length} links for program ${program.name} (${program.slug})`,
          );
        }
      }

      await prisma.programEnrollment.deleteMany({
        where: {
          partnerId: partner.id,
          programId: {
            in: partner.programs.map(({ program }) => program.id),
          },
        },
      });
      console.log(
        `Deleted ${partner.programs.length} program enrollments for partner ${partner.email} (${partner.id})`,
      );
    }

    await conn.execute(`DELETE FROM Partner WHERE id = ?`, [partner.id]);
    console.log(`Deleted partner ${partner.email} (${partner.id})`);
  }

  return NextResponse.json({ success: true });
});


================================================
FILE: apps/web/app/(ee)/api/admin/events/route.ts
================================================
import { getEvents } from "@/lib/analytics/get-events";
import { withAdmin } from "@/lib/auth";
import { eventsQuerySchema } from "@/lib/zod/schemas/analytics";
import { NextResponse } from "next/server";

// GET /api/admin/events – get events for admin
export const GET = withAdmin(async ({ searchParams }) => {
  const parsedParams = eventsQuerySchema.parse(searchParams);

  const response = await getEvents(parsedParams);

  return NextResponse.json(response);
});


================================================
FILE: apps/web/app/(ee)/api/admin/impersonate/route.ts
================================================
import { hashToken, withAdmin } from "@/lib/auth";
import { prisma } from "@dub/prisma";
import { APP_DOMAIN, PARTNERS_DOMAIN } from "@dub/utils";
import { randomBytes } from "crypto";
import { NextResponse } from "next/server";

// POST /api/admin/impersonate
export const POST = withAdmin(async ({ req }) => {
  const { email, slug } = await req.json();

  const response = await prisma.user.findFirst({
    where: email
      ? { email }
      : {
          projects: {
            some: {
              project: {
                slug,
              },
              role: "owner",
            },
          },
        },
    select: {
      email: true,
      projects: {
        select: {
          project: {
            select: {
              id: true,
              name: true,
              slug: true,
              plan: true,
              usage: true,
              linksUsage: true,
              totalClicks: true,
              totalLinks: true,
            },
          },
        },
        orderBy: {
          project: {
            totalClicks: "desc",
          },
        },
      },
      partners: {
        select: {
          partner: {
            select: {
              programs: {
                select: {
                  program: {
                    select: {
                      id: true,
                      name: true,
                      slug: true,
                    },
                  },
                  status: true,
                  totalClicks: true,
                  totalLeads: true,
                  totalConversions: true,
                  totalSaleAmount: true,
                  totalCommissions: true,
                },
                orderBy: {
                  totalCommissions: "desc",
                },
              },
            },
          },
        },
      },
    },
  });

  if (!response?.email) {
    return new Response("User not found", { status: 404 });
  }

  const data = {
    email: response.email,
    workspaces: response.projects.map(({ project }) => ({
      ...project,
      clicks: project.usage,
      links: project.linksUsage,
      totalClicks: project.totalClicks,
      totalLinks: project.totalLinks,
    })),
    programs:
      response.partners.length > 0
        ? response.partners[0].partner.programs.map(({ program, ...rest }) => ({
            ...program,
            ...rest,
          }))
        : [],
    impersonateUrl: await getImpersonateUrl(response.email),
  };

  return NextResponse.json(data);
});

async function getImpersonateUrl(email: string) {
  const token = randomBytes(32).toString("hex");

  await prisma.verificationToken.create({
    data: {
      identifier: email,
      token: await hashToken(token, { secret: true }),
      expires: new Date(Date.now() + 60000),
    },
  });

  return {
    app: `${APP_DOMAIN}/api/auth/callback/email?${new URLSearchParams({
      callbackUrl: APP_DOMAIN,
      email,
      token,
    })}`,
    partners: `${PARTNERS_DOMAIN}/api/auth/callback/email?${new URLSearchParams(
      {
        callbackUrl: PARTNERS_DOMAIN,
        email,
        token,
      },
    )}`,
  };
}


================================================
FILE: apps/web/app/(ee)/api/admin/links/[linkId]/route.ts
================================================
import { transformLink } from "@/lib/api/links";
import { withAdmin } from "@/lib/auth";
import { prisma } from "@dub/prisma";
import { NextResponse } from "next/server";

// GET /api/admin/links/[linkId] – get a link as an admin
export const GET = withAdmin(async ({ params }) => {
  const { linkId } = params;

  const link = await prisma.link.findUnique({
    where: {
      id: linkId,
    },
  });

  if (!link) {
    return NextResponse.json({ error: "Link not found" }, { status: 404 });
  }

  return NextResponse.json(transformLink(link));
});


================================================
FILE: apps/web/app/(ee)/api/admin/links/ban/route.ts
================================================
import { linkCache } from "@/lib/api/links/cache";
import { withAdmin } from "@/lib/auth";
import { updateConfig } from "@/lib/edge-config";
import { domainKeySchema } from "@/lib/zod/schemas/links";
import { prisma } from "@dub/prisma";
import {
  LEGAL_USER_ID,
  LEGAL_WORKSPACE_ID,
  getDomainWithoutWWW,
} from "@dub/utils";
import { NextResponse } from "next/server";

// DELETE /api/admin/links/ban – ban a dub.sh link by key
export const DELETE = withAdmin(async ({ searchParams }) => {
  const { domain, key } = domainKeySchema.parse(searchParams);

  const link = await prisma.link.findUnique({
    where: { domain_key: { domain, key } },
  });

  if (!link) {
    return NextResponse.json({ error: "Link not found" }, { status: 404 });
  }

  const urlDomain = getDomainWithoutWWW(link.url);

  const response = await Promise.all([
    prisma.link.update({
      where: {
        id: link.id,
      },
      data: {
        userId: LEGAL_USER_ID,
        projectId: LEGAL_WORKSPACE_ID,
      },
    }),

    linkCache.set({ ...link, projectId: LEGAL_WORKSPACE_ID }),

    urlDomain &&
      updateConfig({
        key: "domains",
        value: urlDomain,
      }),
  ]);

  return NextResponse.json(response);
});


================================================
FILE: apps/web/app/(ee)/api/admin/links/count/route.ts
================================================
import { withAdmin } from "@/lib/auth";
import { prisma } from "@dub/prisma";
import { DUB_DOMAINS_ARRAY, LEGAL_USER_ID } from "@dub/utils";
import { NextResponse } from "next/server";

// GET /api/admin/links/count
export const GET = withAdmin(async ({ searchParams }) => {
  let { groupBy, search, domain, tagId } = searchParams as {
    groupBy?: "domain" | "tagId" | "userId";
    search?: string;
    domain?: string;
    tagId?: string;
  };

  let response;

  const tagIds = tagId ? tagId.split(",") : [];

  const linksWhere = {
    // when filtering by domain, only filter by domain if the filter group is not "Domains"
    ...(domain && groupBy !== "domain"
      ? {
          domain,
        }
      : {
          domain: {
            in: DUB_DOMAINS_ARRAY,
          },
        }),
    userId: {
      not: LEGAL_USER_ID,
    },
    ...(search && {
      OR: [
        {
          shortLink: { contains: search },
        },
        {
          url: { contains: search },
        },
      ],
    }),
  };

  if (groupBy === "tagId") {
    response = await prisma.linkTag.groupBy({
      by: ["tagId"],
      where: {
        link: linksWhere,
      },
      _count: true,
      orderBy: {
        _count: {
          tagId: "desc",
        },
      },
    });
  } else {
    const where = {
      ...linksWhere,
      ...(tagIds.length > 0 && {
        tags: {
          some: {
            tagId: {
              in: tagIds,
            },
          },
        },
      }),
    };

    if (groupBy) {
      response = await prisma.link.groupBy({
        by: [groupBy],
        where,
        _count: true,
        orderBy: {
          _count: {
            [groupBy]: "desc",
          },
        },
        take: 500,
      });
    } else {
      response = await prisma.link.count({
        where,
      });
    }
  }
  return NextResponse.json(response);
});


================================================
FILE: apps/web/app/(ee)/api/admin/links/route.ts
================================================
import { transformLink } from "@/lib/api/links";
import { withAdmin } from "@/lib/auth";
import { prisma } from "@dub/prisma";
import { DUB_DOMAINS_ARRAY, LEGAL_USER_ID } from "@dub/utils";
import { NextResponse } from "next/server";

// GET /api/admin/links
export const GET = withAdmin(async ({ searchParams }) => {
  const {
    domain,
    search,
    sort = "createdAt",
    page,
  } = searchParams as {
    domain?: string;
    search?: string;
    sort?: "createdAt" | "clicks" | "lastClicked";
    page?: string;
  };

  const response = await prisma.link.findMany({
    where: {
      ...(domain
        ? { domain }
        : {
            domain: {
              in: DUB_DOMAINS_ARRAY,
            },
          }),
      ...(!search && {
        createdAt: {
          gte: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30), // 30 days ago
        },
      }),
      OR: [
        {
          userId: {
            not: LEGAL_USER_ID,
          },
        },
        {
          userId: null,
        },
      ],
      ...(search &&
        (search.startsWith("https://")
          ? {
              shortLink: search,
            }
          : {
              OR: [
                {
                  shortLink: { contains: search },
                },
                {
                  url: { contains: search },
                },
              ],
            })),
    },
    include: {
      user: true,
      tags: {
        include: {
          tag: {
            select: {
              id: true,
              name: true,
              color: true,
            },
          },
        },
      },
    },
    orderBy: {
      [sort]: "desc",
    },
    take: 100,
    ...(page && {
      skip: (parseInt(page) - 1) * 100,
    }),
  });

  return NextResponse.json(response.map((link) => transformLink(link)));
});


================================================
FILE: apps/web/app/(ee)/api/admin/payouts/paypal/route.ts
================================================
import { withAdmin } from "@/lib/auth/admin";
import { getPendingPaypalPayouts } from "@/lib/paypal/get-pending-payouts";
import { NextResponse } from "next/server";

export const GET = withAdmin(async ({ searchParams }) => {
  const { country, programId } = searchParams;
  const pendingPaypalPayouts = await getPendingPaypalPayouts({
    country,
    programId,
  });
  return NextResponse.json(pendingPaypalPayouts);
});


================================================
FILE: apps/web/app/(ee)/api/admin/payouts/route.ts
================================================
import { getStartEndDates } from "@/lib/analytics/utils/get-start-end-dates";
import { withAdmin } from "@/lib/auth";
import { sqlGranularityMap } from "@/lib/planetscale/granularity";
import { analyticsQuerySchema } from "@/lib/zod/schemas/analytics";
import { prisma } from "@dub/prisma";
import { InvoiceStatus, Prisma } from "@dub/prisma/client";
import { ACME_PROGRAM_ID } from "@dub/utils";
import { format } from "date-fns";
import { NextResponse } from "next/server";
import * as z from "zod/v4";

interface TimeseriesPoint {
  payouts: number;
  fees: number;
  total: number;
}

interface FormattedTimeseriesPoint extends TimeseriesPoint {
  date: Date;
}

const adminPayoutsQuerySchema = z
  .object({
    programId: z.string().optional(),
    status: z.enum(InvoiceStatus).optional(),
  })
  .extend(
    analyticsQuerySchema.pick({ interval: true, start: true, end: true }).shape,
  );

export const GET = withAdmin(async ({ searchParams }) => {
  const {
    programId,
    status,
    interval = "mtd",
    start,
    end,
  } = adminPayoutsQuerySchema.parse(searchParams);

  const timezone = "UTC";
  const { startDate, endDate, granularity } = getStartEndDates({
    interval,
    start,
    end,
    timezone,
  });

  // Fetch invoices
  const invoices = await prisma.invoice.findMany({
    where: {
      ...(programId
        ? { programId }
        : {
            AND: [
              {
                programId: {
                  not: ACME_PROGRAM_ID,
                },
              },
              {
                program: {
                  isNot: null,
                },
              },
            ],
          }),
      status: status || {
        not: "failed",
      },
      createdAt: {
        gte: startDate,
        lte: endDate,
      },
    },
    include: {
      program: {
        select: {
          name: true,
          logo: true,
        },
      },
    },
    orderBy: {
      createdAt: "desc",
    },
  });

  const { dateFormat, dateIncrement, startFunction, formatString } =
    sqlGranularityMap[granularity];

  // Calculate timeseries data for payouts and fees
  const timeseriesData = await prisma.$queryRaw<
    { date: Date; payouts: number; fees: number; total: number }[]
  >`
    SELECT 
      DATE_FORMAT(CONVERT_TZ(createdAt, "UTC", ${timezone}), ${dateFormat}) as date,
      SUM(amount) as payouts,
      SUM(fee) as fees,
      SUM(total) as total
    FROM Invoice
    WHERE 
      ${programId ? Prisma.sql`programId = ${programId}` : Prisma.sql`programId != ${ACME_PROGRAM_ID}`}
      AND ${status ? Prisma.sql`status = ${status}` : Prisma.sql`status != 'failed'`}
      AND createdAt >= ${startDate}
      AND createdAt <= ${endDate}
    GROUP BY DATE_FORMAT(CONVERT_TZ(createdAt, "UTC", ${timezone}), ${dateFormat})
    ORDER BY date ASC;
  `;

  const formattedInvoices = invoices.map((invoice) => ({
    date: invoice.createdAt,
    // we're coercing this cause we've filtered out invoices without a programId above
    programId: invoice.programId!,
    programName: invoice.program!.name,
    programLogo: invoice.program!.logo,
    status: invoice.status,
    amount: invoice.amount,
    fee: invoice.fee,
    total: invoice.total,
  }));

  // Create a lookup object for the timeseries data
  const timeseriesLookup: Record<string, TimeseriesPoint> = Object.fromEntries(
    timeseriesData.map((item) => [
      item.date,
      {
        payouts: Number(item.payouts),
        fees: Number(item.fees),
        total: Number(item.total),
      },
    ]),
  );

  // Backfill missing dates with 0 values
  let currentDate = startFunction(startDate);

  const formattedTimeseriesData: FormattedTimeseriesPoint[] = [];

  while (currentDate < endDate) {
    const periodKey = format(currentDate, formatString);

    formattedTimeseriesData.push({
      date: currentDate,
      ...(timeseriesLookup[periodKey] || {
        payouts: 0,
        fees: 0,
        total: 0,
      }),
    });

    currentDate = dateIncrement(currentDate);
  }

  return NextResponse.json({
    invoices: formattedInvoices,
    timeseriesData: formattedTimeseriesData,
  });
});


================================================
FILE: apps/web/app/(ee)/api/admin/refresh-domain/route.ts
================================================
import { addDomainToVercel } from "@/lib/api/domains/add-domain-vercel";
import { withAdmin } from "@/lib/auth";
import { NextResponse } from "next/server";

// POST /api/admin/refresh-domain
export const POST = withAdmin(async ({ req }) => {
  const { domain } = await req.json();

  const remove = await fetch(
    `https://api.vercel.com/v9/projects/${process.env.PROJECT_ID_VERCEL}/domains/${domain}?teamId=${process.env.TEAM_ID_VERCEL}`,
    {
      headers: {
        Authorization: `Bearer ${process.env.AUTH_BEARER_TOKEN}`,
      },
      method: "DELETE",
    },
  ).then((res) => res.json());
  const add = await addDomainToVercel(domain);

  console.log({ remove, add });

  return NextResponse.json({ success: true });
});


================================================
FILE: apps/web/app/(ee)/api/admin/reset-login-attempts/route.ts
================================================
import { withAdmin } from "@/lib/auth";
import { prisma } from "@dub/prisma";
import { NextResponse } from "next/server";

// POST /api/admin/reset-login-attempts
export const POST = withAdmin(async ({ req }) => {
  const { email } = await req.json();

  if (!email) {
    return NextResponse.json({ error: "Email is required" }, { status: 400 });
  }

  const user = await prisma.user.findUnique({
    where: { email },
    select: {
      id: true,
      email: true,
      invalidLoginAttempts: true,
      lockedAt: true,
    },
  });

  if (!user) {
    return NextResponse.json({ error: "User not found" }, { status: 404 });
  }

  const updatedUser = await prisma.user.update({
    where: { email },
    data: {
      invalidLoginAttempts: 0,
      lockedAt: null,
    },
    select: {
      id: true,
      email: true,
      invalidLoginAttempts: true,
      lockedAt: true,
    },
  });

  return NextResponse.json({
    success: true,
    user: updatedUser,
  });
});


================================================
FILE: apps/web/app/(ee)/api/admin/revenue/get-top-programs-by-sales.ts
================================================
import { formatUTCDateTimeClickhouse } from "@/lib/analytics/utils/format-utc-datetime-clickhouse";
import { tb } from "@/lib/tinybird";
import { prisma } from "@dub/prisma";
import { ACME_PROGRAM_ID } from "@dub/utils";
import * as z from "zod/v4";

export async function getTopProgramsBySales({
  startDate,
  endDate,
}: {
  startDate: Date;
  endDate: Date;
}) {
  const pipe = tb.buildPipe({
    pipe: "v2_top_programs",
    parameters: z.any(),
    data: z.any(),
  });

  const response = await pipe({
    eventType: "sales",
    start: formatUTCDateTimeClickhouse(startDate),
    end: formatUTCDateTimeClickhouse(endDate),
  });

  const topProgramsData = response.data as {
    programId: string;
  }[];

  const programIds = topProgramsData
    .map((item) => item.programId)
    .filter((id) => id !== ACME_PROGRAM_ID);

  const programs = await prisma.program.findMany({
    where: {
      id: {
        in: programIds,
      },
    },
    select: {
      id: true,
      name: true,
      logo: true,
      _count: {
        select: {
          partners: {
            where: {
              totalCommissions: {
                gt: 0,
              },
            },
          },
        },
      },
    },
  });

  return topProgramsData
    .map((item) => {
      const program = programs.find((program) => program.id === item.programId);
      if (!program) return null;
      const { _count, ...rest } = program;
      return {
        ...rest,
        ...item,
        partners: _count.partners,
      };
    })
    .filter(Boolean);
}


================================================
FILE: apps/web/app/(ee)/api/admin/revenue/route.ts
================================================
import { getStartEndDates } from "@/lib/analytics/utils/get-start-end-dates";
import { withAdmin } from "@/lib/auth";
import { DUB_FOUNDING_DATE } from "@dub/utils";
import { endOfDay, startOfDay } from "date-fns";
import { NextResponse } from "next/server";
import { getTopProgramsBySales } from "./get-top-programs-by-sales";

export const GET = withAdmin(async ({ searchParams }) => {
  const { interval = "mtd", start, end } = searchParams;

  const { startDate, endDate } = getStartEndDates({
    interval,
    start: start ? startOfDay(new Date(start)) : undefined,
    end: end ? endOfDay(new Date(end)) : undefined,
    dataAvailableFrom: DUB_FOUNDING_DATE,
  });

  const programs = await getTopProgramsBySales({
    startDate,
    endDate,
  });

  return NextResponse.json({
    programs,
  });
});


================================================
FILE: apps/web/app/(ee)/api/audit-logs/export/route.ts
================================================
import { convertToCSV } from "@/lib/analytics/utils";
import { getAuditLogs } from "@/lib/api/audit-logs/get-audit-logs";
import { DubApiError } from "@/lib/api/errors";
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import * as z from "zod/v4";

const auditLogExportQuerySchema = z.object({
  start: z.string(),
  end: z.string(),
});

// POST /api/audit-logs/export – export audit logs to CSV
export const POST = withWorkspace(
  async ({ req, workspace }) => {
    const { start, end } = auditLogExportQuerySchema.parse(
      await parseRequestBody(req),
    );

    if (!start || !end) {
      throw new DubApiError({
        code: "bad_request",
        message: "Must provide start and end dates.",
      });
    }

    const { canExportAuditLogs } = getPlanCapabilities(workspace.plan);

    if (!canExportAuditLogs) {
      throw new DubApiError({
        code: "forbidden",
        message: "You are not authorized to export audit logs.",
      });
    }

    const programId = getDefaultProgramIdOrThrow(workspace);

    const auditLogs = await getAuditLogs({
      workspaceId: workspace.id,
      programId,
      start: new Date(start),
      end: new Date(end),
    });

    const csvData = convertToCSV(auditLogs);

    return new Response(csvData, {
      headers: {
        "Content-Type": "application/csv",
        "Content-Disposition": `attachment;`,
      },
    });
  },
  {
    requiredRoles: ["owner", "member"],
    requiredPlan: ["enterprise"],
  },
);


================================================
FILE: apps/web/app/(ee)/api/auth/saml/authorize/route.ts
================================================
import { jackson } from "@/lib/jackson";
import { getSearchParams } from "@dub/utils";
import { NextResponse } from "next/server";

const handler = async (req: Request) => {
  const { oauthController } = await jackson();

  const requestParams =
    req.method === "GET" ? getSearchParams(req.url) : await req.json();

  const { redirect_url, authorize_form } =
    await oauthController.authorize(requestParams);

  if (redirect_url) {
    return NextResponse.redirect(redirect_url, {
      status: 302,
    });
  } else {
    return new Response(authorize_form, {
      headers: {
        "Content-Type": "text/html; charset=utf-8",
      },
    });
  }
};

export { handler as GET, handler as POST };


================================================
FILE: apps/web/app/(ee)/api/auth/saml/callback/route.ts
================================================
import { jackson } from "@/lib/jackson";
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  const { oauthController } = await jackson();

  const formData = await req.formData();

  const RelayState = formData.get("RelayState") || "";
  const SAMLResponse = formData.get("SAMLResponse") || "";

  const { redirect_url } = await oauthController.samlResponse({
    RelayState: RelayState as string,
    SAMLResponse: SAMLResponse as string,
  });

  if (!redirect_url) {
    return new Response("No redirect URL found.", {
      status: 400,
    });
  }

  return NextResponse.redirect(redirect_url, {
    status: 302,
  });
}


================================================
FILE: apps/web/app/(ee)/api/auth/saml/token/route.ts
================================================
import { jackson } from "@/lib/jackson";
import * as jose from "jose";
import { NextResponse } from "next/server";
import * as dummy from "openid-client";

export async function POST(req: Request) {
  console.log("token route");

  // Need these imports to fix import errors with jackson
  // https://github.com/ory/polis/blob/main/pages/api/import-hack.ts
  const unused = dummy; // eslint-disable-line @typescript-eslint/no-unused-vars
  const unused2 = jose; // eslint-disable-line @typescript-eslint/no-unused-vars

  const { oauthController } = await jackson();

  const formData = await req.formData();
  const body = Object.fromEntries(formData.entries());

  const token = await oauthController.token(body as any);

  return NextResponse.json(token);
}


================================================
FILE: apps/web/app/(ee)/api/auth/saml/userinfo/route.ts
================================================
import { jackson } from "@/lib/jackson";
import { NextResponse } from "next/server";

export async function GET(req: Request) {
  const { oauthController } = await jackson();

  const authHeader = req.headers.get("Authorization");

  if (!authHeader) {
    return new Response("Unauthorized", {
      status: 401,
    });
  }

  const token = authHeader.split(" ")[1];

  const user = await oauthController.userInfo(token);

  return NextResponse.json(user);
}


================================================
FILE: apps/web/app/(ee)/api/auth/saml/verify/route.tsx
================================================
import { jackson } from "@/lib/jackson";
import { prisma } from "@dub/prisma";
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  const { apiController } = await jackson();

  const { slug } = await req.json();

  if (!slug) {
    return NextResponse.json(
      { error: "No workspace slug provided." },
      { status: 400 },
    );
  }

  const workspace = await prisma.project.findUnique({
    where: { slug },
    select: { id: true },
  });

  if (!workspace) {
    return NextResponse.json(
      { error: "Workspace not found." },
      { status: 404 },
    );
  }

  const connections = await apiController.getConnections({
    tenant: workspace.id,
    product: "Dub",
  });

  if (!connections || connections.length === 0) {
    return NextResponse.json(
      { error: "No SSO connections found for this workspace." },
      { status: 404 },
    );
  }

  const data = {
    workspaceId: workspace.id,
  };

  return NextResponse.json({ data });
}


================================================
FILE: apps/web/app/(ee)/api/bounties/[bountyId]/route.ts
================================================
import { recordAuditLog } from "@/lib/api/audit-logs/record-audit-log";
import { DubApiError } from "@/lib/api/errors";
import { throwIfInvalidGroupIds } from "@/lib/api/groups/throw-if-invalid-group-ids";
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { generatePerformanceBountyName } from "@/lib/bounty/api/generate-performance-bounty-name";
import { getBountyWithDetails } from "@/lib/bounty/api/get-bounty-with-details";
import { PERFORMANCE_BOUNTY_SCOPE_ATTRIBUTES } from "@/lib/bounty/api/performance-bounty-scope-attributes";
import { validateBounty } from "@/lib/bounty/api/validate-bounty";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import { WorkflowCondition } from "@/lib/types";
import { sendWorkspaceWebhook } from "@/lib/webhook/publish";
import {
  BountySchema,
  submissionRequirementsSchema,
  updateBountySchema,
} from "@/lib/zod/schemas/bounties";
import { prisma } from "@dub/prisma";
import { PartnerGroup, Prisma } from "@dub/prisma/client";
import { arrayEqual, deepEqual } from "@dub/utils";
import { waitUntil } from "@vercel/functions";
import { NextResponse } from "next/server";

// GET /api/bounties/[bountyId] - get a bounty
export const GET = withWorkspace(
  async ({ workspace, params }) => {
    const { bountyId } = params;

    const programId = getDefaultProgramIdOrThrow(workspace);

    console.time("getBountyWithDetails");
    const bounty = await getBountyWithDetails({
      bountyId,
      programId,
    });
    console.timeEnd("getBountyWithDetails");

    return NextResponse.json(BountySchema.parse(bounty));
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
  },
);

// PATCH /api/bounties/[bountyId] - update a bounty
export const PATCH = withWorkspace(
  async ({ workspace, params, req, session }) => {
    const { bountyId } = params;
    const programId = getDefaultProgramIdOrThrow(workspace);

    const {
      name,
      description,
      startsAt,
      endsAt,
      submissionsOpenAt,
      submissionFrequency,
      maxSubmissions,
      rewardAmount,
      rewardDescription,
      submissionRequirements,
      performanceCondition,
      groupIds,
    } = updateBountySchema.parse(await parseRequestBody(req));

    const bounty = await prisma.bounty.findUniqueOrThrow({
      where: {
        id: bountyId,
        programId,
      },
      include: {
        groups: true,
        workflow: true,
        _count: {
          select: {
            submissions: true,
          },
        },
      },
    });

    validateBounty({
      type: bounty.type,
      startsAt,
      endsAt: endsAt !== undefined ? endsAt : bounty.endsAt,
      submissionsOpenAt,
      submissionFrequency:
        submissionFrequency !== undefined
          ? submissionFrequency
          : bounty.submissionFrequency,
      maxSubmissions:
        maxSubmissions !== undefined ? maxSubmissions : bounty.maxSubmissions,
      submissionRequirements,
      rewardAmount,
      rewardDescription,
      performanceScope: bounty.performanceScope,
    });

    if (
      submissionRequirements !== undefined &&
      submissionRequirements?.socialMetrics &&
      !getPlanCapabilities(workspace.plan).canUseBountySocialMetrics
    ) {
      throw new DubApiError({
        code: "forbidden",
        message: "Social metrics criteria require Advanced plan or above.",
      });
    }

    // TODO:
    // When we do archive, make sure it disables the workflow

    // if groupIds is provided and is different from the current groupIds, update the groups
    let updatedPartnerGroups: PartnerGroup[] | undefined = undefined;
    if (
      groupIds &&
      !arrayEqual(
        bounty.groups.map((group) => group.groupId),
        groupIds,
      )
    ) {
      updatedPartnerGroups = await throwIfInvalidGroupIds({
        programId,
        groupIds,
      });
    }

    // Prevent updates if `performanceCondition.attribute` differs from the current value if there are existing submissions
    if (performanceCondition && bounty.workflow) {
      const submissionCount = bounty._count.submissions;
      const currentCondition = bounty.workflow
        .triggerConditions?.[0] as WorkflowCondition;

      if (
        currentCondition &&
        currentCondition.attribute !== performanceCondition.attribute &&
        submissionCount > 0
      ) {
        throw new DubApiError({
          code: "bad_request",
          message: `You cannot change the performance condition from "${PERFORMANCE_BOUNTY_SCOPE_ATTRIBUTES[currentCondition.attribute].toLowerCase()}" to "${PERFORMANCE_BOUNTY_SCOPE_ATTRIBUTES[performanceCondition.attribute].toLowerCase()}" because the bounty has submissions.`,
        });
      }
    }

    // Prevent update if `submissionRequirements.socialMetrics` differs from the current value if there are existing submissions
    if (submissionRequirements) {
      const submissionCount = bounty._count.submissions;

      const currentSocialMetrics = bounty.submissionRequirements
        ? submissionRequirementsSchema.parse(bounty.submissionRequirements)
            .socialMetrics ?? {}
        : {};

      const incomingSocialMetrics =
        submissionRequirementsSchema.parse(submissionRequirements)
          .socialMetrics ?? {};

      if (
        !deepEqual(currentSocialMetrics, incomingSocialMetrics) &&
        submissionCount > 0
      ) {
        throw new DubApiError({
          code: "bad_request",
          message:
            "You cannot change the social metrics criteria because the bounty has submissions.",
        });
      }
    }

    // Bounty name
    let bountyName = name;

    if (bounty.type === "performance" && performanceCondition) {
      bountyName = generatePerformanceBountyName({
        rewardAmount: rewardAmount ?? 0, // this shouldn't happen since we return early if rewardAmount is null
        condition: performanceCondition,
      });
    }

    const data = await prisma.$transaction(async (tx) => {
      const updatedBounty = await tx.bounty.update({
        where: {
          id: bounty.id,
        },
        data: {
          name: bountyName ?? undefined,
          description,
          startsAt: startsAt!, // Can remove the ! when we're on a newer TS version (currently 5.4.4)
          endsAt,
          submissionsOpenAt:
            bounty.type === "submission" ? submissionsOpenAt : null,
          ...(bounty.type === "submission" &&
            submissionFrequency !== undefined && { submissionFrequency }),
          ...(bounty.type === "submission" &&
            maxSubmissions !== undefined && {
              maxSubmissions: maxSubmissions ?? 1,
            }),
          rewardAmount:
            rewardAmount !== undefined ? rewardAmount : bounty.rewardAmount,
          rewardDescription,
          ...(bounty.type === "submission" &&
            submissionRequirements !== undefined && {
              submissionRequirements: submissionRequirements ?? Prisma.DbNull,
            }),
          ...(updatedPartnerGroups && {
            groups: {
              deleteMany: {},
              create: updatedPartnerGroups.map((group) => ({
                groupId: group.id,
              })),
            },
          }),
        },
        include: {
          workflow: true,
          groups: true,
        },
      });

      if (updatedBounty.workflowId && performanceCondition) {
        await tx.workflow.update({
          where: {
            id: updatedBounty.workflowId,
          },
          data: {
            triggerConditions: [performanceCondition],
          },
        });
      }

      return {
        ...updatedBounty,
        performanceCondition,
      };
    });

    const updatedBounty = BountySchema.parse({
      ...data,
      groups: data.groups.map(({ groupId }) => ({ id: groupId })),
      performanceCondition: data.workflow?.triggerConditions?.[0],
    });

    waitUntil(
      Promise.allSettled([
        recordAuditLog({
          workspaceId: workspace.id,
          programId,
          action: "bounty.updated",
          description: `Bounty ${bounty.id} updated`,
          actor: session?.user,
          targets: [
            {
              type: "bounty",
              id: bounty.id,
              metadata: updatedBounty,
            },
          ],
        }),

        sendWorkspaceWebhook({
          workspace,
          trigger: "bounty.updated",
          data: updatedBounty,
        }),
      ]),
    );

    return NextResponse.json(updatedBounty);
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
    requiredRoles: ["owner", "member"],
  },
);

// DELETE /api/bounties/[bountyId] - delete a bounty
export const DELETE = withWorkspace(
  async ({ workspace, params, session }) => {
    const { bountyId } = params;
    const programId = getDefaultProgramIdOrThrow(workspace);

    const bounty = await prisma.bounty.findUniqueOrThrow({
      where: {
        id: bountyId,
        programId,
      },
      include: {
        groups: true,
        workflow: true,
        _count: {
          select: {
            submissions: true,
          },
        },
      },
    });

    if (bounty._count.submissions > 0) {
      throw new DubApiError({
        message:
          "Bounties with submissions cannot be deleted. You can archive them instead.",
        code: "bad_request",
      });
    }

    await prisma.$transaction(async (tx) => {
      const bounty = await tx.bounty.delete({
        where: {
          id: bountyId,
        },
      });

      if (bounty.workflowId) {
        await tx.workflow.delete({
          where: {
            id: bounty.workflowId,
          },
        });
      }
    });

    const deletedBounty = BountySchema.parse({
      ...bounty,
      groups: bounty.groups.map(({ groupId }) => ({ id: groupId })),
      performanceCondition: bounty.workflow?.triggerConditions?.[0],
    });

    waitUntil(
      recordAuditLog({
        workspaceId: workspace.id,
        programId,
        action: "bounty.deleted",
        description: `Bounty ${bountyId} deleted`,
        actor: session?.user,
        targets: [
          {
            type: "bounty",
            id: bountyId,
            metadata: deletedBounty,
          },
        ],
      }),
    );

    return NextResponse.json({ id: bountyId });
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
    requiredRoles: ["owner", "member"],
  },
);


================================================
FILE: apps/web/app/(ee)/api/bounties/[bountyId]/submissions/[submissionId]/approve/route.ts
================================================
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { approveBountySubmission } from "@/lib/bounty/api/approve-bounty-submission";
import { getBountyOrThrow } from "@/lib/bounty/api/get-bounty-or-throw";
import { approveBountySubmissionBodySchema } from "@/lib/zod/schemas/bounties";
import { NextResponse } from "next/server";

// POST /api/bounties/[bountyId]/submissions/[submissionId]/approve - approve a submission
export const POST = withWorkspace(
  async ({ workspace, params, req, session }) => {
    const { bountyId, submissionId } = params;
    const programId = getDefaultProgramIdOrThrow(workspace);

    let body;
    try {
      body = await parseRequestBody(req);
    } catch (e) {
      // If body is empty or invalid, use empty object since body is optional
      body = {};
    }

    const { rewardAmount } = approveBountySubmissionBodySchema.parse(body);

    await getBountyOrThrow({
      bountyId,
      programId,
    });

    const approvedSubmission = await approveBountySubmission({
      programId,
      bountyId,
      submissionId,
      rewardAmount,
      user: session.user,
    });

    return NextResponse.json(approvedSubmission);
  },
  {
    requiredPlan: ["advanced", "enterprise"],
    requiredRoles: ["owner", "member"],
  },
);


================================================
FILE: apps/web/app/(ee)/api/bounties/[bountyId]/submissions/[submissionId]/reject/route.ts
================================================
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { getBountyOrThrow } from "@/lib/bounty/api/get-bounty-or-throw";
import { rejectBountySubmission } from "@/lib/bounty/api/reject-bounty-submission";
import { rejectBountySubmissionBodySchema } from "@/lib/zod/schemas/bounties";
import { NextResponse } from "next/server";

// POST /api/bounties/[bountyId]/submissions/[submissionId]/reject - reject a submission
export const POST = withWorkspace(
  async ({ workspace, params, req, session }) => {
    const { bountyId, submissionId } = params;
    const programId = getDefaultProgramIdOrThrow(workspace);

    let body;
    try {
      body = await parseRequestBody(req);
    } catch (e) {
      // If body is empty or invalid, use empty object since body is optional
      body = {};
    }

    const { rejectionReason, rejectionNote } =
      rejectBountySubmissionBodySchema.parse(body);

    await getBountyOrThrow({
      bountyId,
      programId,
    });

    const rejectedSubmission = await rejectBountySubmission({
      programId,
      bountyId,
      submissionId,
      rejectionReason,
      rejectionNote,
      user: session.user,
    });

    return NextResponse.json(rejectedSubmission);
  },
  {
    requiredPlan: ["advanced", "enterprise"],
    requiredRoles: ["owner", "member"],
  },
);


================================================
FILE: apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts
================================================
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { withWorkspace } from "@/lib/auth";
import { getBountyOrThrow } from "@/lib/bounty/api/get-bounty-or-throw";
import {
  BountySubmissionExtendedSchema,
  getBountySubmissionsQuerySchema,
} from "@/lib/zod/schemas/bounties";
import { prisma } from "@dub/prisma";
import { NextResponse } from "next/server";

// GET /api/bounties/[bountyId]/submissions - get all submissions for a bounty
export const GET = withWorkspace(
  async ({ workspace, params, searchParams }) => {
    const { bountyId } = params;
    const programId = getDefaultProgramIdOrThrow(workspace);

    await getBountyOrThrow({
      bountyId,
      programId,
      include: {
        groups: true,
      },
    });

    const {
      status,
      groupId,
      partnerId,
      sortOrder,
      sortBy,
      page = 1,
      pageSize,
    } = getBountySubmissionsQuerySchema.parse(searchParams);

    const submissions = await prisma.bountySubmission.findMany({
      where: {
        bountyId,
        status: status ?? {
          in: ["draft", "submitted", "approved"],
        },
        ...(groupId && {
          programEnrollment: {
            groupId,
          },
        }),
        ...(partnerId && {
          partnerId,
        }),
      },
      include: {
        user: true,
        commission: true,
        partner: true,
        programEnrollment: true,
      },
      orderBy: {
        [sortBy]: sortOrder,
      },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    const bountySubmissions = submissions.map(
      ({ partner, programEnrollment, commission, user, ...submissionData }) =>
        BountySubmissionExtendedSchema.parse({
          ...submissionData,
          partner: {
            ...partner,
            ...(programEnrollment || {}),
            id: partner.id,
            status: programEnrollment?.status ?? null,
          },
          commission,
          user,
        }),
    );

    return NextResponse.json(bountySubmissions);
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
  },
);


================================================
FILE: apps/web/app/(ee)/api/bounties/[bountyId]/sync-social-metrics/route.ts
================================================
import { DubApiError } from "@/lib/api/errors";
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { getBountyOrThrow } from "@/lib/bounty/api/get-bounty-or-throw";
import { getSocialMetricsUpdates } from "@/lib/bounty/api/get-social-metrics-updates";
import { resolveBountyDetails } from "@/lib/bounty/utils";
import { qstash } from "@/lib/cron";
import { sendEmail } from "@dub/email";
import BountyCompleted from "@dub/email/templates/bounty-completed";
import { prisma } from "@dub/prisma";
import { Prisma } from "@dub/prisma/client";
import { APP_DOMAIN_WITH_NGROK } from "@dub/utils";
import { NextResponse } from "next/server";
import * as z from "zod/v4";

const inputSchema = z.object({
  submissionId: z
    .string()
    .optional()
    .describe(
      "The ID of the submission to sync social metrics for. If not provided, all submissions will be synced.",
    ),
});

// POST /api/bounties/[bountyId]/sync-social-metrics - sync social metrics for a bounty
export const POST = withWorkspace(
  async ({ workspace, params, req }) => {
    const { bountyId } = params;
    const programId = getDefaultProgramIdOrThrow(workspace);

    const { submissionId } = inputSchema.parse(await parseRequestBody(req));

    const bounty = await getBountyOrThrow({
      bountyId,
      programId,
      include: submissionId
        ? {
            program: {
              select: {
                name: true,
                slug: true,
                supportEmail: true,
              },
            },
            submissions: {
              where: {
                id: submissionId,
              },
              select: {
                id: true,
                urls: true,
                status: true,
                partner: true,
              },
            },
          }
        : undefined,
    });

    const bountyInfo = resolveBountyDetails(bounty);

    if (!bountyInfo?.socialMetrics) {
      throw new DubApiError({
        code: "bad_request",
        message: "This bounty does not have social metrics requirements.",
      });
    }

    const submission = submissionId ? bounty.submissions?.[0] : undefined;

    if (submissionId) {
      if (!submission) {
        throw new DubApiError({
          code: "not_found",
          message: `Submission ${submissionId} not found.`,
        });
      }

      if (submission.status === "approved") {
        throw new DubApiError({
          code: "bad_request",
          message: "Social metrics can't be synced for an approved submission.",
        });
      }
    }

    const now = new Date();

    if (bounty.startsAt && bounty.startsAt > now) {
      throw new DubApiError({
        code: "bad_request",
        message: "Social metrics can only be synced after the bounty starts.",
      });
    }

    if (bounty.endsAt && bounty.endsAt < now) {
      throw new DubApiError({
        code: "bad_request",
        message: "Social metrics can't be synced after the bounty ends.",
      });
    }

    // Do the sync in a background job if no submissionId is provided
    if (!submissionId) {
      const response = await qstash.publishJSON({
        url: `${APP_DOMAIN_WITH_NGROK}/api/cron/bounties/sync-social-metrics`,
        method: "POST",
        body: {
          bountyId,
        },
      });

      if (!response.messageId) {
        throw new DubApiError({
          code: "bad_request",
          message: "Could not sync social metrics for this bounty now.",
        });
      }

      return NextResponse.json({});
    }

    // Otherwise, do the sync for the specific submission
    const toUpdate = await getSocialMetricsUpdates({
      bounty,
      submissions: bounty.submissions![0],
    });

    if (toUpdate.length > 0) {
      const update = toUpdate.find((s) => s.id === submissionId);

      if (!update) {
        return NextResponse.json({});
      }

      const { socialMetricCount, socialMetricsLastSyncedAt } = update;
      const submission = bounty.submissions![0];

      const updateData: Prisma.BountySubmissionUpdateInput = {
        socialMetricCount,
        socialMetricsLastSyncedAt,
      };

      const hasMetCriteria =
        socialMetricCount != null &&
        bountyInfo.socialMetrics?.minCount != null &&
        socialMetricCount >= bountyInfo.socialMetrics.minCount;

      const shouldTransitionToSubmitted =
        submission.status === "draft" && hasMetCriteria;

      if (shouldTransitionToSubmitted) {
        updateData.status = "submitted";
        updateData.completedAt = new Date();
      }

      await prisma.bountySubmission.update({
        where: {
          id: submissionId,
        },
        data: {
          ...updateData,
        },
      });

      const { partner } = submission;

      if (shouldTransitionToSubmitted && partner.email) {
        await sendEmail({
          subject: "Bounty completed!",
          to: partner.email,
          variant: "notifications",
          replyTo: bounty.program.supportEmail || "noreply",
          react: BountyCompleted({
            email: partner.email,
            bounty: {
              name: bounty.name,
              type: bounty.type,
            },
            program: {
              name: bounty.program.name,
              slug: bounty.program.slug,
            },
          }),
          headers: {
            "Idempotency-Key": `bounty-completed-${submissionId}`,
          },
        });
      }
    }

    return NextResponse.json({});
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
  },
);


================================================
FILE: apps/web/app/(ee)/api/bounties/count/submissions/route.ts
================================================
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { withWorkspace } from "@/lib/auth";
import { prisma } from "@dub/prisma";
import { BountySubmissionStatus } from "@dub/prisma/client";
import { NextResponse } from "next/server";
import * as z from "zod/v4";

const bountiesSubmissionsCountQuerySchema = z.object({
  bountyId: z.string().optional(),
  groupId: z.string().optional(),
  partnerId: z.string().optional(),
});

const statuses = Object.values(BountySubmissionStatus);

// GET /api/bounties/count/submissions – get the total bounty submissions count by status (potentially filtered by bountyId)
export const GET = withWorkspace(
  async ({ workspace, searchParams }) => {
    const programId = getDefaultProgramIdOrThrow(workspace);
    const { bountyId, groupId, partnerId } =
      bountiesSubmissionsCountQuerySchema.parse(searchParams);

    const count = await prisma.bountySubmission.groupBy({
      by: ["status"],
      where: {
        programId,
        bountyId,
        ...(groupId && {
          programEnrollment: {
            groupId,
          },
        }),
        ...(partnerId && {
          partnerId,
        }),
      },
      _count: true,
    });

    const counts = count.map((c) => ({
      status: c.status,
      count: c._count,
    }));

    statuses.forEach((status) => {
      if (!counts.some((c) => c.status === status)) {
        counts.push({
          status,
          count: 0,
        });
      }
    });

    return NextResponse.json(counts);
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
  },
);


================================================
FILE: apps/web/app/(ee)/api/bounties/route.ts
================================================
import { recordAuditLog } from "@/lib/api/audit-logs/record-audit-log";
import { createId } from "@/lib/api/create-id";
import { DubApiError } from "@/lib/api/errors";
import { throwIfInvalidGroupIds } from "@/lib/api/groups/throw-if-invalid-group-ids";
import { getDefaultProgramIdOrThrow } from "@/lib/api/programs/get-default-program-id-or-throw";
import { getProgramEnrollmentOrThrow } from "@/lib/api/programs/get-program-enrollment-or-throw";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { generatePerformanceBountyName } from "@/lib/bounty/api/generate-performance-bounty-name";
import { validateBounty } from "@/lib/bounty/api/validate-bounty";
import { qstash } from "@/lib/cron";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import { WorkflowAction } from "@/lib/types";
import { sendWorkspaceWebhook } from "@/lib/webhook/publish";
import {
  BountyListSchema,
  BountySchema,
  createBountySchema,
  getBountiesQuerySchema,
} from "@/lib/zod/schemas/bounties";
import {
  WORKFLOW_ACTION_TYPES,
  WORKFLOW_ATTRIBUTE_TRIGGER,
} from "@/lib/zod/schemas/workflows";
import { prisma } from "@dub/prisma";
import { Workflow } from "@dub/prisma/client";
import { APP_DOMAIN_WITH_NGROK } from "@dub/utils";
import { waitUntil } from "@vercel/functions";
import { NextResponse } from "next/server";

// GET /api/bounties - get all bounties for a program
export const GET = withWorkspace(
  async ({ workspace, searchParams }) => {
    const programId = getDefaultProgramIdOrThrow(workspace);

    const { partnerId, includeSubmissionsCount } =
      getBountiesQuerySchema.parse(searchParams);

    const programEnrollment = partnerId
      ? await getProgramEnrollmentOrThrow({
          partnerId,
          programId,
          include: {
            program: true,
          },
        })
      : null;

    const [bounties, allBountiesSubmissionsCount] = await Promise.all([
      prisma.bounty.findMany({
        where: {
          programId,
          // Filter only bounties the specified partner is eligible for
          ...(programEnrollment && {
            AND: [
              // Filter out expired bounties
              {
                OR: [{ endsAt: null }, { endsAt: { gt: new Date() } }],
              },
              // Filter by partner's group eligibility
              {
                OR: [
                  {
                    groups: {
                      none: {},
                    },
                  },
                  {
                    groups: {
                      some: {
                        groupId:
                          programEnrollment.groupId ||
                          programEnrollment.program.defaultGroupId,
                      },
                    },
                  },
                ],
              },
            ],
          }),
        },
        include: {
          groups: {
            select: {
              groupId: true,
            },
          },
        },
      }),
      includeSubmissionsCount
        ? prisma.bountySubmission.groupBy({
            by: ["bountyId", "status"],
            where: {
              programId,
              status: {
                in: ["submitted", "approved"],
              },
            },
            _count: {
              status: true,
            },
          })
        : null,
    ]);

    const aggregateSubmissionsCountForBounty = (bountyId: string) => {
      if (!allBountiesSubmissionsCount) {
        return null;
      }
      const bountySubmissions = allBountiesSubmissionsCount.filter(
        (s) => s.bountyId === bountyId,
      );
      const total = bountySubmissions.reduce(
        (sum, s) => sum + s._count.status,
        0,
      );
      const submitted =
        bountySubmissions.find((s) => s.status === "submitted")?._count
          .status ?? 0;
      const approved =
        bountySubmissions.find((s) => s.status === "approved")?._count.status ??
        0;
      return {
        total,
        submitted,
        approved,
      };
    };

    const data = bounties.map((bounty) => {
      return BountyListSchema.parse({
        ...bounty,
        groups: bounty.groups.map(({ groupId }) => ({ id: groupId })),
        ...(allBountiesSubmissionsCount && {
          submissionsCountData: aggregateSubmissionsCountForBounty(bounty.id),
        }),
      });
    });

    return NextResponse.json(data);
  },
  {
    requiredPlan: [
      "business",
      "business plus",
      "business extra",
      "business max",
      "advanced",
      "enterprise",
    ],
  },
);

// POST /api/bounties - create a bounty
export const POST = withWorkspace(
  async ({ workspace, req, session }) => {
    const programId = getDefaultProgramIdOrThrow(workspace);

    const parsedBody = createBountySchema.parse(await parseRequestBody(req));

    let {
      name,
      description,
      type,
      rewardAmount,
      rewardDescription,
      startsAt,
      endsAt,
      submissionsOpenAt,
      submissionFrequency,
      maxSubmissions,
      submissionRequirements,
      groupIds,
      performanceCondition,
      performanceScope,
      sendNotificationEmails,
    } = parsedBody;

    // Use current date as default if startsAt is not provided
    startsAt = startsAt || new Date();

    validateBounty(parsedBody);

    const { canUseBountySocialMetrics, canSendEmailCampaigns } =
      getPlanCapabilities(workspace.plan);

    if (submissionRequirements?.socialMetrics && !canUseBountySocialMetrics) {
      throw new DubApiError({
        code: "forbidden",
        message: "Social metrics criteria require Advanced plan or above.",
      });
    }

    const partnerGroups = await throwIfInvalidGroupIds({
      programId,
      groupIds,
    });

    // Bounty name
    let bountyName = name;

    if (type === "performance" && performanceCondition) {
      bountyName = generatePerformanceBountyName({
        rewardAmount: rewardAmount ?? 0, // this shouldn't happen since we return early if rewardAmount is null
        condition: performanceCondition,
      });
    }

    if (!bountyName) {
      throw new DubApiError({
        code: "bad_request",
        message: "Bounty name is required.",
      });
    }

    const bounty = await prisma.$transaction(async (tx) => {
      let workflow: Workflow | null = null;
      const bountyId = createId({ prefix: "bnty_" });

      // Create a workflow if there is a performance condition
      if (performanceCondition && type === "performance") {
        const action: WorkflowAction = {
          type: WORKFLOW_ACTION_TYPES.AwardBounty,
          data: {
            bountyId,
          },
        };

        workflow = await tx.workflow.create({
          data: {
            id: createId({ prefix: "wf_" }),
            programId,
            trigger: WORKFLOW_ATTRIBUTE_TRIGGER[performanceCondition.attribute],
            triggerConditions: [performanceCondition],
            actions: [action],
          },
        });
      }

      // Create a bounty
      return await tx.bounty.create({
        data: {
          id: bountyId,
          programId,
          workflowId: workflow?.id,
          name: bountyName,
          description,
          type,
          startsAt,
          endsAt,
          submissionsOpenAt: type === "submission" ? submissionsOpenAt : null,
          submissionFrequency:
            type === "submission" ? submissionFrequency : null,
          maxSubmissions: type === "submission" ? maxSubmissions ?? 1 : 1,
          rewardAmount,
          rewardDescription,
          performanceScope: type === "performance" ? performanceScope : null,
          ...(submissionRequirements &&
            type === "submission" && {
              submissionRequirements,
            }),
          ...(partnerGroups.length && {
            groups: {
              createMany: {
                data: partnerGroups.map(({ id }) => ({
                  groupId: id,
                })),
              },
            },
          }),
        },
        include: {
          workflow: true,
          groups: true,
        },
      });
    });

    const createdBounty = BountySchema.parse({
      ...bounty,
      groups: bounty.groups.map(({ groupId }) => ({ id: groupId })),
      performanceCondition: bounty.workflow?.triggerConditions?.[0],
    });

    const shouldScheduleDraftSubmissions =
      bounty.type === "performance" && bounty.performanceScope === "lifetime";

    waitUntil(
      Promise.allSettled([
        recordAuditLog({
          workspaceId: workspace.id,
          programId,
          action: "bounty.created",
          description: `Bounty ${bounty.id} created`,
          actor: session?.user,
          targets: [
            {
              type: "bounty",
              id: bounty.id,
              metadata: createdBounty,
            },
          ],
        }),

        sendWorkspaceWebhook({
          workspace,
          trigger: "bounty.created",
          data: createdBounty,
        }),

        sendNotificationEmails &&
          canSendEmailCampaigns &&
          qstash.publishJSON({
            url: `${APP_DOMAIN_WITH_NGROK}/api/cron/bounties/notify-partners`,
            body: {
              bountyId: bounty.id,
            },
            notBef
Download .txt
Showing preview only (214K chars total). Download the full file or copy to clipboard to get everything.
gitextract_j4v7jeo4/

├── .github/
│   └── workflows/
│       ├── apply-issue-labels-to-pr.yml
│       ├── deploy-embed-script.yml
│       ├── e2e.yaml
│       ├── playwright.yaml
│       └── prettier.yaml
├── .gitignore
├── .prettierignore
├── LICENSE.md
├── README.md
├── SECURITY.md
├── apps/
│   └── web/
│       ├── app/
│       │   ├── (ee)/
│       │   │   ├── LICENSE.md
│       │   │   ├── README.md
│       │   │   ├── admin.dub.co/
│       │   │   │   ├── (auth)/
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   └── login/
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── (dashboard)/
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── commissions/
│       │   │   │   │   │   ├── client.tsx
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── components/
│       │   │   │   │   │   ├── ban-link.tsx
│       │   │   │   │   │   ├── delete-partner-account.tsx
│       │   │   │   │   │   ├── impersonate-user.tsx
│       │   │   │   │   │   ├── impersonate-workspace.tsx
│       │   │   │   │   │   ├── refresh-domain.tsx
│       │   │   │   │   │   ├── reset-login-attempts.tsx
│       │   │   │   │   │   └── user-info.tsx
│       │   │   │   │   ├── events/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── layout-nav-client.tsx
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   ├── links/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── page.tsx
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── client.tsx
│       │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   └── paypal/
│       │   │   │   │   │       ├── client.tsx
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   └── revenue/
│       │   │   │   │       ├── client.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   └── layout.tsx
│       │   │   ├── api/
│       │   │   │   ├── admin/
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── ban/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── commissions/
│       │   │   │   │   │   ├── get-commissions-timeseries.ts
│       │   │   │   │   │   ├── get-top-program-by-commissions.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── delete-partner-account/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── events/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── impersonate/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── links/
│       │   │   │   │   │   ├── [linkId]/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── ban/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── paypal/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── refresh-domain/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── reset-login-attempts/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── revenue/
│       │   │   │   │       ├── get-top-programs-by-sales.ts
│       │   │   │   │       └── route.ts
│       │   │   │   ├── audit-logs/
│       │   │   │   │   └── export/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── auth/
│       │   │   │   │   └── saml/
│       │   │   │   │       ├── authorize/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── callback/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── token/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── userinfo/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── verify/
│       │   │   │   │           └── route.tsx
│       │   │   │   ├── bounties/
│       │   │   │   │   ├── [bountyId]/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   ├── submissions/
│       │   │   │   │   │   │   ├── [submissionId]/
│       │   │   │   │   │   │   │   ├── approve/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── reject/
│       │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── sync-social-metrics/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── submissions/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── campaigns/
│       │   │   │   │   ├── [campaignId]/
│       │   │   │   │   │   ├── duplicate/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── preview/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── summary/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── commissions/
│       │   │   │   │   ├── [commissionId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── timeseries/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── cron/
│       │   │   │   │   ├── aggregate-clicks/
│       │   │   │   │   │   ├── resolve-click-reward-amount.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── bounties/
│       │   │   │   │   │   ├── create-draft-submissions/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── notify-partners/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── queue-sync-social-metrics/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── sync-social-metrics/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── campaigns/
│       │   │   │   │   │   └── broadcast/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── cleanup/
│       │   │   │   │   │   ├── demo-embed-partners/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── e2e-tests/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── expired-tokens/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── link-retention/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── rejected-applications/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── unenrolled-partners/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── discount-codes/
│       │   │   │   │   │   ├── create/
│       │   │   │   │   │   │   ├── queue-batches/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── delete/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── disposable-emails/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── domains/
│       │   │   │   │   │   ├── delete/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── renewal-payments/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── renewal-reminders/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── transfer/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── update/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── verify/
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       └── utils.ts
│       │   │   │   │   ├── email-domains/
│       │   │   │   │   │   ├── update/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── verify/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   ├── commissions/
│       │   │   │   │   │   │   ├── fetch-commissions-batch.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   ├── fetch-events-batch.ts
│       │   │   │   │   │   │   ├── partner/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── workspace/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   ├── fetch-links-batch.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── partners/
│       │   │   │   │   │       ├── fetch-partners-batch.ts
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── folders/
│       │   │   │   │   │   └── delete/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── framer/
│       │   │   │   │   │   └── backfill-leads-batch/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── fraud/
│       │   │   │   │   │   └── summary/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── fx-rates/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── groups/
│       │   │   │   │   │   ├── create-default-links/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── remap-default-links/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── remap-discount-codes/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── sync-utm/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── update-default-links/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── import/
│       │   │   │   │   │   ├── bitly/
│       │   │   │   │   │   │   ├── fetch-utils.ts
│       │   │   │   │   │   │   ├── queue-import.ts
│       │   │   │   │   │   │   ├── rate-limit.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   ├── sanitize-json.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── csv/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── firstpromoter/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── partnerstack/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── rebrandly/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── rewardful/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── short/
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   └── tolt/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── invoices/
│       │   │   │   │   │   └── retry-failed/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── links/
│       │   │   │   │   │   ├── [linkId]/
│       │   │   │   │   │   │   └── complete-tests/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── delete/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── invalidate-for-discounts/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── invalidate-for-partners/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── messages/
│       │   │   │   │   │   ├── notify-partner/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── notify-program/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── network/
│       │   │   │   │   │   ├── calculate-program-similarities/
│       │   │   │   │   │   │   ├── calculate-category-similarity.ts
│       │   │   │   │   │   │   ├── calculate-partner-similarity.ts
│       │   │   │   │   │   │   ├── calculate-performance-similarity.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── update-partner-discoverability/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── partner-platforms/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── youtube/
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       └── youtube-channel-schema.ts
│       │   │   │   │   ├── partner-program-summary/
│       │   │   │   │   │   ├── process/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── partners/
│       │   │   │   │   │   ├── auto-approve/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── auto-reject/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── ban/
│       │   │   │   │   │   │   ├── cancel-commissions.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── deactivate/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── merge-accounts/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── aggregate-due-commissions/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── balance-available/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── charge-succeeded/
│       │   │   │   │   │   │   ├── queue-external-payouts.ts
│       │   │   │   │   │   │   ├── queue-stripe-payouts.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   ├── send-paypal-payouts.ts
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── force-withdrawals/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── payout-failed/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── payout-paid/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── process/
│       │   │   │   │   │   │   ├── process-payouts.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   ├── split-payouts.ts
│       │   │   │   │   │   │   └── updates/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── reminders/
│       │   │   │   │   │   │   ├── partners/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── program-owners/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   └── send-stripe-payout/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── pending-applications-summary/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── program-application-reminder/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── programs/
│       │   │   │   │   │   └── deactivate/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── send-batch-email/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── shopify/
│       │   │   │   │   │   └── order-paid/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── streams/
│       │   │   │   │   │   ├── update-partner-stats/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── update-workspace-clicks/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── trigger-withdrawal/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── usage/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── utils.ts
│       │   │   │   │   ├── utils.ts
│       │   │   │   │   ├── welcome-user/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── workflows/
│       │   │   │   │   │   └── [workflowId]/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── workspaces/
│       │   │   │   │       └── delete/
│       │   │   │   │           ├── delete-workspace-customers.ts
│       │   │   │   │           ├── delete-workspace-domains.ts
│       │   │   │   │           ├── delete-workspace-folders.ts
│       │   │   │   │           ├── delete-workspace-links.ts
│       │   │   │   │           ├── delete-workspace.ts
│       │   │   │   │           ├── route.ts
│       │   │   │   │           └── utils.ts
│       │   │   │   ├── customers/
│       │   │   │   │   ├── [id]/
│       │   │   │   │   │   ├── activity/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── stripe-invoices/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── search-stripe/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── discount-codes/
│       │   │   │   │   ├── [discountCodeId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── domains/
│       │   │   │   │   ├── register/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── status/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── e2e/
│       │   │   │   │   ├── bounties/
│       │   │   │   │   │   └── [bountyId]/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── enrollments/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── guard.ts
│       │   │   │   │   ├── notification-emails/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── trigger-workflow/
│       │   │   │   │   │   └── [workflowId]/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── workflows/
│       │   │   │   │       ├── [workflowId]/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── route.ts
│       │   │   │   ├── email-domains/
│       │   │   │   │   ├── [domain]/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── verify/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── embed/
│       │   │   │   │   └── referrals/
│       │   │   │   │       ├── analytics/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── earnings/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── leaderboard/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── links/
│       │   │   │   │       │   ├── [linkId]/
│       │   │   │   │       │   │   └── route.ts
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── token/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── events/
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── fraud/
│       │   │   │   │   ├── events/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── groups/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── rules/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── groups/
│       │   │   │   │   ├── [groupIdOrSlug]/
│       │   │   │   │   │   ├── default/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── default-links/
│       │   │   │   │   │   │   ├── [defaultLinkId]/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── partners/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── rules/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── hubspot/
│       │   │   │   │   ├── callback/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── webhook/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── messages/
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── mock/
│       │   │   │   │   └── rewardful/
│       │   │   │   │       ├── affiliates/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── campaigns/
│       │   │   │   │       │   ├── [campaignId]/
│       │   │   │   │       │   │   └── route.ts
│       │   │   │   │       │   ├── campaigns.ts
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       ├── commissions/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── referrals/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── network/
│       │   │   │   │   ├── partners/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── invites-usage/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── programs/
│       │   │   │   │       ├── count/
│       │   │   │   │       │   └── route.ts
│       │   │   │   │       └── route.ts
│       │   │   │   ├── partner-profile/
│       │   │   │   │   ├── invites/
│       │   │   │   │   │   ├── accept/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── messages/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── notification-preferences/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── payouts/
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── settings/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── postbacks/
│       │   │   │   │   │   ├── [postbackId]/
│       │   │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── rotate-secret/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   └── send-test/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── programs/
│       │   │   │   │   │   ├── [programId]/
│       │   │   │   │   │   │   ├── activity-logs/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── analytics/
│       │   │   │   │   │   │   │   ├── export/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── bounties/
│       │   │   │   │   │   │   │   ├── [bountyId]/
│       │   │   │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   │   │   └── social-content-stats/
│       │   │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   │   ├── [customerId]/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── earnings/
│       │   │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   │   │   └── timeseries/
│       │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   │   ├── export/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── groups/
│       │   │   │   │   │   │   │   └── [groupIdOrSlug]/
│       │   │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   │   ├── [linkId]/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── referrals/
│       │   │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   ├── resources/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── rewind/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── users/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── partners/
│       │   │   │   │   ├── [partnerId]/
│       │   │   │   │   │   ├── application-risks/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── comments/
│       │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── cross-program-summary/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── ban/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── deactivate/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── export/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── links/
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── upsert/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── platforms/
│       │   │   │   │   │   └── callback/
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── payouts/
│       │   │   │   │   ├── [payoutId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── count/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── paypal/
│       │   │   │   │   ├── callback/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── webhook/
│       │   │   │   │       ├── payouts-item-failed.ts
│       │   │   │   │       ├── payouts-item-succeeded.ts
│       │   │   │   │       ├── route.ts
│       │   │   │   │       ├── utils.ts
│       │   │   │   │       └── verify-signature.ts
│       │   │   │   ├── programs/
│       │   │   │   │   ├── [programId]/
│       │   │   │   │   │   ├── applications/
│       │   │   │   │   │   │   ├── [applicationId]/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── export/
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── discounts/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── payouts/
│       │   │   │   │   │   │   └── eligible/
│       │   │   │   │   │   │       ├── count/
│       │   │   │   │   │   │       │   └── route.ts
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   ├── referrals/
│       │   │   │   │   │   │   ├── count/
│       │   │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── resources/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── rewardful/
│       │   │   │   │       └── campaigns/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── rewards/
│       │   │   │   │   ├── [rewardId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── scim/
│       │   │   │   │   └── v2.0/
│       │   │   │   │       └── [...directory]/
│       │   │   │   │           └── route.ts
│       │   │   │   ├── shopify/
│       │   │   │   │   ├── integration/
│       │   │   │   │   │   ├── callback/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── webhook/
│       │   │   │   │   │       ├── app-uninstalled.ts
│       │   │   │   │   │       ├── customers-data-request.ts
│       │   │   │   │   │       ├── customers-redact.ts
│       │   │   │   │   │       ├── orders-paid.ts
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       └── shop-redact.ts
│       │   │   │   │   └── pixel/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── singular/
│       │   │   │   │   └── webhook/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── stripe/
│       │   │   │   │   ├── connect/
│       │   │   │   │   │   ├── v2/
│       │   │   │   │   │   │   └── webhook/
│       │   │   │   │   │   │       ├── outbound-payment-failed.ts
│       │   │   │   │   │   │       ├── outbound-payment-posted.ts
│       │   │   │   │   │   │       ├── outbound-payment-returned.ts
│       │   │   │   │   │   │       ├── recipient-account-closed.ts
│       │   │   │   │   │   │       ├── recipient-configuration-updated.ts
│       │   │   │   │   │   │       └── route.ts
│       │   │   │   │   │   └── webhook/
│       │   │   │   │   │       ├── account-application-deauthorized.ts
│       │   │   │   │   │       ├── account-updated.ts
│       │   │   │   │   │       ├── balance-available.ts
│       │   │   │   │   │       ├── payout-failed.ts
│       │   │   │   │   │       ├── payout-paid.ts
│       │   │   │   │   │       └── route.ts
│       │   │   │   │   ├── integration/
│       │   │   │   │   │   ├── callback/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   ├── route.ts
│       │   │   │   │   │   └── webhook/
│       │   │   │   │   │       ├── account-application-deauthorized.ts
│       │   │   │   │   │       ├── charge-refunded.ts
│       │   │   │   │   │       ├── checkout-session-completed.ts
│       │   │   │   │   │       ├── coupon-deleted.ts
│       │   │   │   │   │       ├── customer-created.ts
│       │   │   │   │   │       ├── customer-subscription-created.ts
│       │   │   │   │   │       ├── customer-subscription-deleted.ts
│       │   │   │   │   │       ├── customer-updated.ts
│       │   │   │   │   │       ├── invoice-paid.ts
│       │   │   │   │   │       ├── promotion-code-updated.ts
│       │   │   │   │   │       ├── route.ts
│       │   │   │   │   │       ├── sandbox/
│       │   │   │   │   │       │   └── route.ts
│       │   │   │   │   │       ├── test/
│       │   │   │   │   │       │   └── route.ts
│       │   │   │   │   │       └── utils/
│       │   │   │   │   │           ├── create-new-customer.ts
│       │   │   │   │   │           ├── get-connected-customer.ts
│       │   │   │   │   │           ├── get-promotion-code.ts
│       │   │   │   │   │           ├── get-subscription-product-id.ts
│       │   │   │   │   │           └── update-customer-with-stripe-customer-id.ts
│       │   │   │   │   └── webhook/
│       │   │   │   │       ├── charge-failed.ts
│       │   │   │   │       ├── charge-refunded.ts
│       │   │   │   │       ├── charge-succeeded.ts
│       │   │   │   │       ├── checkout-session-completed.ts
│       │   │   │   │       ├── customer-subscription-deleted.ts
│       │   │   │   │       ├── customer-subscription-updated.ts
│       │   │   │   │       ├── invoice-payment-failed.tsx
│       │   │   │   │       ├── payment-intent-requires-action.ts
│       │   │   │   │       ├── route.ts
│       │   │   │   │       ├── transfer-reversed.ts
│       │   │   │   │       └── utils/
│       │   │   │   │           ├── process-domain-renewal-failure.ts
│       │   │   │   │           ├── process-payout-invoice-failure.ts
│       │   │   │   │           ├── send-cancellation-feedback.ts
│       │   │   │   │           └── update-workspace-plan.ts
│       │   │   │   ├── track/
│       │   │   │   │   ├── click/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── lead/
│       │   │   │   │   │   ├── client/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── open/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── sale/
│       │   │   │   │   │   ├── client/
│       │   │   │   │   │   │   └── route.ts
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── visit/
│       │   │   │   │       └── route.ts
│       │   │   │   └── workflows/
│       │   │   │       └── partner-approved/
│       │   │   │           └── route.ts
│       │   │   ├── app.dub.co/
│       │   │   │   ├── (new-program)/
│       │   │   │   │   ├── [slug]/
│       │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   └── program/
│       │   │   │   │   │       └── new/
│       │   │   │   │   │           ├── form.tsx
│       │   │   │   │   │           ├── overview/
│       │   │   │   │   │           │   ├── page-client.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── page.tsx
│       │   │   │   │   │           ├── partners/
│       │   │   │   │   │           │   ├── form.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── rewards/
│       │   │   │   │   │           │   ├── form.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── step-page.tsx
│       │   │   │   │   │           └── support/
│       │   │   │   │   │               ├── form.tsx
│       │   │   │   │   │               └── page.tsx
│       │   │   │   │   ├── header.tsx
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   ├── sidebar-context.tsx
│       │   │   │   │   └── steps.tsx
│       │   │   │   ├── embed/
│       │   │   │   │   ├── referrals/
│       │   │   │   │   │   ├── activity.tsx
│       │   │   │   │   │   ├── add-edit-link.tsx
│       │   │   │   │   │   ├── dynamic-height-messenger.tsx
│       │   │   │   │   │   ├── earnings-summary.tsx
│       │   │   │   │   │   ├── earnings.tsx
│       │   │   │   │   │   ├── faq.tsx
│       │   │   │   │   │   ├── leaderboard.tsx
│       │   │   │   │   │   ├── links-list.tsx
│       │   │   │   │   │   ├── links.tsx
│       │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   ├── quickstart.tsx
│       │   │   │   │   │   ├── resources.tsx
│       │   │   │   │   │   ├── theme-options.ts
│       │   │   │   │   │   ├── token.tsx
│       │   │   │   │   │   ├── types.ts
│       │   │   │   │   │   └── utils.ts
│       │   │   │   │   └── use-embed-token.ts
│       │   │   │   ├── invoices/
│       │   │   │   │   └── [invoiceId]/
│       │   │   │   │       ├── domain-renewal-invoice.tsx
│       │   │   │   │       ├── partner-payout-invoice.tsx
│       │   │   │   │       └── route.tsx
│       │   │   │   └── layout.tsx
│       │   │   └── partners.dub.co/
│       │   │       ├── (apply)/
│       │   │       │   └── [programSlug]/
│       │   │       │       ├── (default)/
│       │   │       │       │   ├── apply/
│       │   │       │       │   │   ├── page.tsx
│       │   │       │       │   │   └── success/
│       │   │       │       │   │       ├── cta-buttons.tsx
│       │   │       │       │   │       ├── page.tsx
│       │   │       │       │   │       ├── pixel-conversion.tsx
│       │   │       │       │   │       └── screenshot.tsx
│       │   │       │       │   ├── apply-button.tsx
│       │   │       │       │   ├── header.tsx
│       │   │       │       │   ├── layout.tsx
│       │   │       │       │   └── page.tsx
│       │   │       │       └── (group-level)/
│       │   │       │           └── [groupSlug]/
│       │   │       │               ├── apply/
│       │   │       │               │   ├── page.tsx
│       │   │       │               │   └── success/
│       │   │       │               │       └── page.tsx
│       │   │       │               ├── layout.tsx
│       │   │       │               └── page.tsx
│       │   │       ├── (auth-login-register)/
│       │   │       │   ├── (generic)/
│       │   │       │   │   ├── layout.tsx
│       │   │       │   │   ├── login/
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   └── register/
│       │   │       │   │       ├── page-client.tsx
│       │   │       │   │       └── page.tsx
│       │   │       │   ├── (program)/
│       │   │       │   │   └── [programSlug]/
│       │   │       │   │       ├── layout.tsx
│       │   │       │   │       ├── login/
│       │   │       │   │       │   └── page.tsx
│       │   │       │   │       └── register/
│       │   │       │   │           └── page.tsx
│       │   │       │   ├── partner-banner.tsx
│       │   │       │   ├── program-logos.tsx
│       │   │       │   └── side-panel.tsx
│       │   │       ├── (auth-other)/
│       │   │       │   ├── auth/
│       │   │       │   │   ├── confirm-email-change/
│       │   │       │   │   │   └── [token]/
│       │   │       │   │   │       └── page.tsx
│       │   │       │   │   └── reset-password/
│       │   │       │   │       └── [token]/
│       │   │       │   │           └── page.tsx
│       │   │       │   ├── forgot-password/
│       │   │       │   │   └── page.tsx
│       │   │       │   ├── invite/
│       │   │       │   │   └── page.tsx
│       │   │       │   ├── layout.tsx
│       │   │       │   ├── logo.tsx
│       │   │       │   └── unsubscribe/
│       │   │       │       └── [token]/
│       │   │       │           └── page.tsx
│       │   │       ├── (dashboard)/
│       │   │       │   ├── account/
│       │   │       │   │   └── settings/
│       │   │       │   │       ├── page.tsx
│       │   │       │   │       └── security/
│       │   │       │   │           └── page.tsx
│       │   │       │   ├── auth.tsx
│       │   │       │   ├── layout.tsx
│       │   │       │   ├── messages/
│       │   │       │   │   ├── [programSlug]/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── layout.tsx
│       │   │       │   │   ├── page-client.tsx
│       │   │       │   │   └── page.tsx
│       │   │       │   ├── payouts/
│       │   │       │   │   ├── page.tsx
│       │   │       │   │   ├── partner-payout-details-sheet.tsx
│       │   │       │   │   ├── partner-payout-settings-button.tsx
│       │   │       │   │   ├── partner-payout-settings-sheet.tsx
│       │   │       │   │   ├── payout-stats.tsx
│       │   │       │   │   ├── payout-table.tsx
│       │   │       │   │   └── use-payout-filters.tsx
│       │   │       │   ├── profile/
│       │   │       │   │   ├── about-you-form.tsx
│       │   │       │   │   ├── how-you-work-form.tsx
│       │   │       │   │   ├── industry-interests-modal.tsx
│       │   │       │   │   ├── members/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── notifications/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── page-client.tsx
│       │   │       │   │   ├── page.tsx
│       │   │       │   │   ├── postbacks/
│       │   │       │   │   │   ├── [id]/
│       │   │       │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   └── page.tsx
│       │   │       │   │   │   ├── add-postback-button.tsx
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── profile-details-form.tsx
│       │   │       │   │   ├── profile-discovery-guide.tsx
│       │   │       │   │   ├── settings-row.tsx
│       │   │       │   │   └── use-partner-discovery-requirements.ts
│       │   │       │   ├── programs/
│       │   │       │   │   ├── [programSlug]/
│       │   │       │   │   │   ├── (enrolled)/
│       │   │       │   │   │   │   ├── analytics/
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── auth.tsx
│       │   │       │   │   │   │   ├── bounties/
│       │   │       │   │   │   │   │   ├── [bountyId]/
│       │   │       │   │   │   │   │   │   ├── bounty-performance-section.tsx
│       │   │       │   │   │   │   │   │   ├── bounty-submissions-table.tsx
│       │   │       │   │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   │   ├── bounty-card.tsx
│       │   │       │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── customers/
│       │   │       │   │   │   │   │   ├── (index)/
│       │   │       │   │   │   │   │   │   ├── layout.tsx
│       │   │       │   │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   │   │   ├── referrals/
│       │   │       │   │   │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   │   │   └── use-partner-customer-filters.tsx
│       │   │       │   │   │   │   │   └── [customerId]/
│       │   │       │   │   │   │   │       ├── page-client.tsx
│       │   │       │   │   │   │   │       └── page.tsx
│       │   │       │   │   │   │   ├── earnings/
│       │   │       │   │   │   │   │   ├── earnings-composite-chart.tsx
│       │   │       │   │   │   │   │   ├── earnings-table.tsx
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── events/
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── hide-program-details-button.tsx
│       │   │       │   │   │   │   ├── layout.tsx
│       │   │       │   │   │   │   ├── links/
│       │   │       │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   │   ├── partner-link-card.tsx
│       │   │       │   │   │   │   │   └── partner-link-controls.tsx
│       │   │       │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   ├── payouts-card.tsx
│       │   │       │   │   │   │   ├── resources/
│       │   │       │   │   │   │   │   ├── page-client.tsx
│       │   │       │   │   │   │   │   └── page.tsx
│       │   │       │   │   │   │   ├── share-earnings-modal.tsx
│       │   │       │   │   │   │   └── unapproved-program-page.tsx
│       │   │       │   │   │   ├── apply/
│       │   │       │   │   │   │   ├── page.tsx
│       │   │       │   │   │   │   └── program-sidebar.tsx
│       │   │       │   │   │   └── invite/
│       │   │       │   │   │       ├── accept-program-invite-button.tsx
│       │   │       │   │   │       ├── page.tsx
│       │   │       │   │   │       └── program-invite-confetti.tsx
│       │   │       │   │   ├── invitations/
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   └── page.tsx
│       │   │       │   │   ├── marketplace/
│       │   │       │   │   │   ├── [programSlug]/
│       │   │       │   │   │   │   ├── header-controls.tsx
│       │   │       │   │   │   │   ├── loading.tsx
│       │   │       │   │   │   │   └── page.tsx
│       │   │       │   │   │   ├── featured-program-card.tsx
│       │   │       │   │   │   ├── featured-programs.tsx
│       │   │       │   │   │   ├── layout.tsx
│       │   │       │   │   │   ├── marketplace-empty-state.tsx
│       │   │       │   │   │   ├── page-client.tsx
│       │   │       │   │   │   ├── page.tsx
│       │   │       │   │   │   ├── program-card.tsx
│       │   │       │   │   │   ├── program-sort.tsx
│       │   │       │   │   │   ├── program-status-badge.tsx
│       │   │       │   │   │   └── use-program-network-filters.tsx
│       │   │       │   │   ├── page-client.tsx
│       │   │       │   │   └── page.tsx
│       │   │       │   └── rewind/
│       │   │       │       └── 2025/
│       │   │       │           ├── conclusion.tsx
│       │   │       │           ├── intro.tsx
│       │   │       │           ├── page-client.tsx
│       │   │       │           ├── page.tsx
│       │   │       │           ├── rewind.tsx
│       │   │       │           └── share-rewind-modal.tsx
│       │   │       ├── (onboarding)/
│       │   │       │   ├── layout.tsx
│       │   │       │   └── onboarding/
│       │   │       │       ├── onboarding-form.tsx
│       │   │       │       ├── page.tsx
│       │   │       │       ├── payouts/
│       │   │       │       │   ├── page.tsx
│       │   │       │       │   └── payout-provider.tsx
│       │   │       │       └── platforms/
│       │   │       │           ├── page-client.tsx
│       │   │       │           └── page.tsx
│       │   │       ├── (redirects)/
│       │   │       │   └── apply/
│       │   │       │       └── [programSlug]/
│       │   │       │           └── [[...slug]]/
│       │   │       │               └── page.tsx
│       │   │       ├── invoices/
│       │   │       │   └── [payoutId]/
│       │   │       │       └── route.tsx
│       │   │       └── layout.tsx
│       │   ├── [domain]/
│       │   │   ├── browser-graphic.tsx
│       │   │   ├── layout.tsx
│       │   │   ├── not-found/
│       │   │   │   └── page.tsx
│       │   │   ├── page.tsx
│       │   │   ├── placeholder.tsx
│       │   │   └── stats/
│       │   │       └── [key]/
│       │   │           └── page.tsx
│       │   ├── api/
│       │   │   ├── (old)/
│       │   │   │   └── projects/
│       │   │   │       ├── [slug]/
│       │   │   │       │   ├── domains/
│       │   │   │       │   │   ├── [domain]/
│       │   │   │       │   │   │   ├── route.ts
│       │   │   │       │   │   │   └── verify/
│       │   │   │       │   │   │       └── route.ts
│       │   │   │       │   │   ├── default/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   └── route.ts
│       │   │   │       │   ├── links/
│       │   │   │       │   │   ├── [linkId]/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── bulk/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── count/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── info/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   ├── random/
│       │   │   │       │   │   │   └── route.ts
│       │   │   │       │   │   └── route.ts
│       │   │   │       │   ├── route.ts
│       │   │   │       │   └── tags/
│       │   │   │       │       ├── [id]/
│       │   │   │       │       │   └── route.ts
│       │   │   │       │       └── route.ts
│       │   │   │       └── route.ts
│       │   │   ├── activity-logs/
│       │   │   │   └── route.ts
│       │   │   ├── ai/
│       │   │   │   ├── completion/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── support-chat/
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── upload/
│       │   │   │   │       └── route.ts
│       │   │   │   └── sync-embeddings/
│       │   │   │       ├── fetch-plausible-pageviews.ts
│       │   │   │       └── route.ts
│       │   │   ├── analytics/
│       │   │   │   ├── [eventType]/
│       │   │   │   │   ├── [endpoint]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── dashboard/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── export/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── auth/
│       │   │   │   ├── [...nextauth]/
│       │   │   │   │   └── route.tsx
│       │   │   │   └── reset-password/
│       │   │   │       └── route.ts
│       │   │   ├── callback/
│       │   │   │   ├── bitly/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── plain/
│       │   │   │   │   ├── partner/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── utils.ts
│       │   │   │   │   └── workspace/
│       │   │   │   │       └── route.ts
│       │   │   │   └── stripe/
│       │   │   │       └── route.ts
│       │   │   ├── dashboards/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── docs/
│       │   │   │   └── guides/
│       │   │   │       └── [guide]/
│       │   │   │           └── route.ts
│       │   │   ├── domains/
│       │   │   │   ├── [domain]/
│       │   │   │   │   ├── primary/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   ├── transfer/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── validate/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── verify/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── client/
│       │   │   │   │   ├── register/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── saved/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── default/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── route.ts
│       │   │   │   └── search-availability/
│       │   │   │       └── route.ts
│       │   │   ├── dub/
│       │   │   │   └── webhook/
│       │   │   │       ├── lead-created.ts
│       │   │   │       ├── route.ts
│       │   │   │       └── sale-created.ts
│       │   │   ├── folders/
│       │   │   │   ├── [folderId]/
│       │   │   │   │   ├── dashboard/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── users/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── access-requests/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── permissions/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── integrations/
│       │   │   │   ├── route.ts
│       │   │   │   └── uninstall/
│       │   │   │       └── route.ts
│       │   │   ├── links/
│       │   │   │   ├── [linkId]/
│       │   │   │   │   ├── dashboard/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── transfer/
│       │   │   │   │       └── route.ts
│       │   │   │   ├── bulk/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── exists/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── export/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── iframeable/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── info/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── metatags/
│       │   │   │   │   ├── route.ts
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── random/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── route.ts
│       │   │   │   ├── sync/
│       │   │   │   │   └── route.ts
│       │   │   │   └── upsert/
│       │   │   │       └── route.ts
│       │   │   ├── me/
│       │   │   │   └── route.ts
│       │   │   ├── misc/
│       │   │   │   ├── check-favicon/
│       │   │   │   │   └── route.ts
│       │   │   │   └── check-workspace-slug/
│       │   │   │       └── route.ts
│       │   │   ├── oauth/
│       │   │   │   ├── apps/
│       │   │   │   │   ├── [appId]/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── authorize/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── token/
│       │   │   │   │   ├── exchange-code-for-token.ts
│       │   │   │   │   ├── refresh-access-token.ts
│       │   │   │   │   └── route.ts
│       │   │   │   └── userinfo/
│       │   │   │       └── route.ts
│       │   │   ├── og/
│       │   │   │   ├── analytics/
│       │   │   │   │   └── route.tsx
│       │   │   │   ├── avatar/
│       │   │   │   │   └── [[...seed]]/
│       │   │   │   │       └── route.tsx
│       │   │   │   ├── load-google-font.ts
│       │   │   │   ├── partner-earnings/
│       │   │   │   │   └── route.tsx
│       │   │   │   ├── partner-rewind/
│       │   │   │   │   └── route.tsx
│       │   │   │   └── program/
│       │   │   │       └── route.tsx
│       │   │   ├── postbacks/
│       │   │   │   └── callback/
│       │   │   │       └── route.ts
│       │   │   ├── providers/
│       │   │   │   └── route.ts
│       │   │   ├── qr/
│       │   │   │   └── route.tsx
│       │   │   ├── resend/
│       │   │   │   └── webhook/
│       │   │   │       ├── email-bounced.ts
│       │   │   │       ├── email-delivered.ts
│       │   │   │       ├── email-opened.ts
│       │   │   │       └── route.ts
│       │   │   ├── resumes/
│       │   │   │   └── upload-url/
│       │   │   │       └── route.ts
│       │   │   ├── route.ts
│       │   │   ├── slack/
│       │   │   │   ├── callback/
│       │   │   │   │   └── route.ts
│       │   │   │   └── slash-commands/
│       │   │   │       └── route.ts
│       │   │   ├── supported-countries/
│       │   │   │   └── route.ts
│       │   │   ├── tags/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── count/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── tokens/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── embed/
│       │   │   │   │   └── referrals/
│       │   │   │   │       └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── unsplash/
│       │   │   │   ├── download/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── search/
│       │   │   │   │   └── route.ts
│       │   │   │   └── utils.ts
│       │   │   ├── user/
│       │   │   │   ├── notification-preferences/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── password/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── referrals-token/
│       │   │   │   │   └── route.ts
│       │   │   │   ├── route.ts
│       │   │   │   ├── set-password/
│       │   │   │   │   └── route.ts
│       │   │   │   └── tokens/
│       │   │   │       └── route.ts
│       │   │   ├── utm/
│       │   │   │   ├── [id]/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   ├── webhooks/
│       │   │   │   ├── [webhookId]/
│       │   │   │   │   ├── events/
│       │   │   │   │   │   └── route.ts
│       │   │   │   │   └── route.ts
│       │   │   │   ├── callback/
│       │   │   │   │   └── route.ts
│       │   │   │   └── route.ts
│       │   │   └── workspaces/
│       │   │       ├── [idOrSlug]/
│       │   │       │   ├── billing/
│       │   │       │   │   ├── cancel/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── invoices/
│       │   │       │   │   │   ├── [invoiceId]/
│       │   │       │   │   │   │   └── route.ts
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── manage/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── payment-methods/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── upgrade/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   └── usage/
│       │   │       │   │       └── route.ts
│       │   │       │   ├── import/
│       │   │       │   │   ├── [importId]/
│       │   │       │   │   │   └── download/
│       │   │       │   │   │       └── route.ts
│       │   │       │   │   ├── bitly/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── csv/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── rebrandly/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   └── short/
│       │   │       │   │       └── route.ts
│       │   │       │   ├── invites/
│       │   │       │   │   ├── accept/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── decline/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   ├── reset/
│       │   │       │   │   │   └── route.ts
│       │   │       │   │   └── route.ts
│       │   │       │   ├── notification-preferences/
│       │   │       │   │   └── route.ts
│       │   │       │   ├── route.ts
│       │   │       │   ├── saml/
│       │   │       │   │   └── route.ts
│       │   │       │   ├── scim/
│       │   │       │   │   └── route.ts
│       │   │       │   ├── stats/
│       │   │       │   │   └── [endpoint]/
│       │   │       │   │       └── route.ts
│       │   │       │   ├── upload-url/
│       │   │       │   │   └── route.ts
│       │   │       │   └── users/
│       │   │       │       └── route.ts
│       │   │       └── route.ts
│       │   ├── app.dub.co/
│       │   │   ├── (auth)/
│       │   │   │   ├── auth/
│       │   │   │   │   ├── confirm-email-change/
│       │   │   │   │   │   └── [token]/
│       │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   ├── reset-password/
│       │   │   │   │   │   └── [token]/
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   └── saml/
│       │   │   │   │       ├── form.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── customer-logos.tsx
│       │   │   │   ├── forgot-password/
│       │   │   │   │   └── page.tsx
│       │   │   │   ├── invites/
│       │   │   │   │   └── [code]/
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── login/
│       │   │   │   │   └── page.tsx
│       │   │   │   ├── oauth/
│       │   │   │   │   └── authorize/
│       │   │   │   │       ├── authorize-form.tsx
│       │   │   │   │       ├── loading.tsx
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       └── scopes-requested.tsx
│       │   │   │   ├── register/
│       │   │   │   │   ├── page-client.tsx
│       │   │   │   │   └── page.tsx
│       │   │   │   ├── side-panel.tsx
│       │   │   │   └── unsubscribe/
│       │   │   │       └── [token]/
│       │   │   │           ├── page.tsx
│       │   │   │           └── unsubscribe-form.tsx
│       │   │   ├── (dashboard)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   ├── (ee)/
│       │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   ├── [customerId]/
│       │   │   │   │   │   │   │   ├── earnings/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   └── sales/
│       │   │   │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   ├── events/
│       │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   ├── program/
│       │   │   │   │   │   │   ├── analytics/
│       │   │   │   │   │   │   │   ├── analytics-chart.tsx
│       │   │   │   │   │   │   │   ├── analytics-partners-table.tsx
│       │   │   │   │   │   │   │   ├── analytics-timeseries-chart.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   └── partner-analytics-filter-cell.tsx
│       │   │   │   │   │   │   ├── auth.tsx
│       │   │   │   │   │   │   ├── bounties/
│       │   │   │   │   │   │   │   ├── [bountyId]/
│       │   │   │   │   │   │   │   │   ├── bounty-header.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-info.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-submission-details-sheet.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-submission-row-menu.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-submissions-table.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── use-bounty-submission-filters.tsx
│       │   │   │   │   │   │   │   ├── add-edit-bounty/
│       │   │   │   │   │   │   │   │   ├── add-edit-bounty-sheet.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-amount-input.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-criteria-manual-submission.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-criteria-social-metrics.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-criteria.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-form-context.tsx
│       │   │   │   │   │   │   │   │   ├── bounty-logic.tsx
│       │   │   │   │   │   │   │   │   ├── confirm-create-bounty-modal.tsx
│       │   │   │   │   │   │   │   │   └── use-add-edit-bounty-form.ts
│       │   │   │   │   │   │   │   ├── bounty-action-button.tsx
│       │   │   │   │   │   │   │   ├── bounty-card.tsx
│       │   │   │   │   │   │   │   ├── bounty-list.tsx
│       │   │   │   │   │   │   │   ├── create-bounty-button.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── campaigns/
│       │   │   │   │   │   │   │   ├── [campaignId]/
│       │   │   │   │   │   │   │   │   ├── campaign-action-bar.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-controls.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-editor-skeleton.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-editor.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-events-columns.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-events-modal.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-events.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-form-context.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-groups-selector.tsx
│       │   │   │   │   │   │   │   │   ├── campaign-metrics.tsx
│       │   │   │   │   │   │   │   │   ├── duplicate-logic-warning.tsx
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   ├── send-email-preview-modal.tsx
│       │   │   │   │   │   │   │   │   ├── transactional-campaign-logic.tsx
│       │   │   │   │   │   │   │   │   ├── use-campaign-confirmation-modals.tsx
│       │   │   │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   │   │   ├── campaign-stats.tsx
│       │   │   │   │   │   │   │   ├── campaign-status-badges.tsx
│       │   │   │   │   │   │   │   ├── campaign-type-badges.tsx
│       │   │   │   │   │   │   │   ├── campaign-type-icon.tsx
│       │   │   │   │   │   │   │   ├── campaigns-page-content.tsx
│       │   │   │   │   │   │   │   ├── campaigns-table.tsx
│       │   │   │   │   │   │   │   ├── campaigns-upsell.tsx
│       │   │   │   │   │   │   │   ├── create-campaign-button.tsx
│       │   │   │   │   │   │   │   ├── delete-campaign-modal.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── use-campaign.tsx
│       │   │   │   │   │   │   │   ├── use-campaigns-count.tsx
│       │   │   │   │   │   │   │   └── use-campaigns-filters.tsx
│       │   │   │   │   │   │   ├── coming-soon-page.tsx
│       │   │   │   │   │   │   ├── commissions/
│       │   │   │   │   │   │   │   ├── [commissionId]/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── commission-popover-buttons.tsx
│       │   │   │   │   │   │   │   ├── commissions-stats.tsx
│       │   │   │   │   │   │   │   ├── commissions-table.tsx
│       │   │   │   │   │   │   │   ├── create-clawback-sheet.tsx
│       │   │   │   │   │   │   │   ├── create-commission-button.tsx
│       │   │   │   │   │   │   │   ├── create-commission-sheet.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   └── use-commission-filters.tsx
│       │   │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   │   ├── (index)/
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── referrals/
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── [customerId]/
│       │   │   │   │   │   │   │   │   ├── earnings/
│       │   │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── sales/
│       │   │   │   │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   └── customers-dropdown-menu.tsx
│       │   │   │   │   │   │   ├── fraud/
│       │   │   │   │   │   │   │   ├── example-fraud-events.tsx
│       │   │   │   │   │   │   │   ├── fraud-group-table.tsx
│       │   │   │   │   │   │   │   ├── fraud-paid-traffic-settings.tsx
│       │   │   │   │   │   │   │   ├── fraud-referral-source-settings.tsx
│       │   │   │   │   │   │   │   ├── fraud-rule-toggle-settings.tsx
│       │   │   │   │   │   │   │   ├── fraud-upsell.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── program-fraud-actions-menu.tsx
│       │   │   │   │   │   │   │   ├── program-fraud-settings-button.tsx
│       │   │   │   │   │   │   │   ├── program-fraud-settings-sheet.tsx
│       │   │   │   │   │   │   │   ├── resolved/
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── resolved-fraud-group-table.tsx
│       │   │   │   │   │   │   │   └── use-fraud-group-filters.tsx
│       │   │   │   │   │   │   ├── groups/
│       │   │   │   │   │   │   │   ├── [groupSlug]/
│       │   │   │   │   │   │   │   │   ├── branding/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── discounts/
│       │   │   │   │   │   │   │   │   │   ├── group-discounts.tsx
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── group-header.tsx
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   │   │   │   ├── add-edit-group-additional-link-modal.tsx
│       │   │   │   │   │   │   │   │   │   ├── add-edit-group-default-link-sheet.tsx
│       │   │   │   │   │   │   │   │   │   ├── change-program-domain-modal.tsx
│       │   │   │   │   │   │   │   │   │   ├── group-additional-links.tsx
│       │   │   │   │   │   │   │   │   │   ├── group-default-links.tsx
│       │   │   │   │   │   │   │   │   │   ├── group-link-settings.tsx
│       │   │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   │   └── partner-link-preview.tsx
│       │   │   │   │   │   │   │   │   ├── rewards/
│       │   │   │   │   │   │   │   │   │   ├── group-rewards.tsx
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   └── settings/
│       │   │   │   │   │   │   │   │       ├── group-additional-settings.tsx
│       │   │   │   │   │   │   │   │       ├── group-move-rules.tsx
│       │   │   │   │   │   │   │   │       ├── group-settings.tsx
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── create-group-button.tsx
│       │   │   │   │   │   │   │   ├── create-group-modal.tsx
│       │   │   │   │   │   │   │   ├── groups-table.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   ├── messages/
│       │   │   │   │   │   │   │   ├── [partnerId]/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── messages-disabled.tsx
│       │   │   │   │   │   │   │   ├── messages-upsell.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── network/
│       │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   ├── network-empty-state.tsx
│       │   │   │   │   │   │   │   ├── network-upsell.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   └── use-partner-network-filters.tsx
│       │   │   │   │   │   │   ├── overview-chart.tsx
│       │   │   │   │   │   │   ├── overview-links.tsx
│       │   │   │   │   │   │   ├── overview-tasks.tsx
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   ├── partners/
│       │   │   │   │   │   │   │   ├── [partnerId]/
│       │   │   │   │   │   │   │   │   ├── comments/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── customers/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   │   │   ├── links/
│       │   │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   │   ├── partner-nav.tsx
│       │   │   │   │   │   │   │   │   ├── partner-stats.tsx
│       │   │   │   │   │   │   │   │   └── payouts/
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── applications/
│       │   │   │   │   │   │   │   │   ├── applications-menu.tsx
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   │   └── rejected/
│       │   │   │   │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   │   │   ├── import-export-buttons.tsx
│       │   │   │   │   │   │   │   ├── invite-partner-button.tsx
│       │   │   │   │   │   │   │   ├── invite-partner-sheet.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── partners-table.tsx
│       │   │   │   │   │   │   │   └── use-partner-filters.tsx
│       │   │   │   │   │   │   ├── partners-graphic.tsx
│       │   │   │   │   │   │   ├── partners-upgrade-cta.tsx
│       │   │   │   │   │   │   ├── payouts/
│       │   │   │   │   │   │   │   ├── [payoutId]/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   │   ├── payout-paid-cell.tsx
│       │   │   │   │   │   │   │   ├── payout-stats.tsx
│       │   │   │   │   │   │   │   ├── payout-table.tsx
│       │   │   │   │   │   │   │   ├── program-payout-methods.tsx
│       │   │   │   │   │   │   │   ├── program-payout-mode-section.tsx
│       │   │   │   │   │   │   │   ├── program-payout-settings-button.tsx
│       │   │   │   │   │   │   │   ├── program-payout-settings-sheet.tsx
│       │   │   │   │   │   │   │   ├── success/
│       │   │   │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   │   └── use-payout-filters.tsx
│       │   │   │   │   │   │   ├── program-settings-row.tsx
│       │   │   │   │   │   │   └── resources/
│       │   │   │   │   │   │       ├── page.tsx
│       │   │   │   │   │   │       ├── program-brand-assets/
│       │   │   │   │   │   │       │   ├── add-color-modal.tsx
│       │   │   │   │   │   │       │   ├── add-file-modal.tsx
│       │   │   │   │   │   │       │   ├── add-link-modal.tsx
│       │   │   │   │   │   │       │   ├── add-logo-modal.tsx
│       │   │   │   │   │   │       │   ├── index.tsx
│       │   │   │   │   │   │       │   └── use-upload-program-resource.ts
│       │   │   │   │   │   │       └── program-help-and-support.tsx
│       │   │   │   │   │   └── settings/
│       │   │   │   │   │       ├── billing/
│       │   │   │   │   │       │   ├── invoices/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page.tsx
│       │   │   │   │   │       │   ├── payment-method-types.ts
│       │   │   │   │   │       │   ├── payment-methods.tsx
│       │   │   │   │   │       │   ├── plan-usage.tsx
│       │   │   │   │   │       │   ├── upgrade/
│       │   │   │   │   │       │   │   ├── adjust-usage-row.tsx
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   └── usage-chart.tsx
│       │   │   │   │   │       ├── domains/
│       │   │   │   │   │       │   ├── default/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── email/
│       │   │   │   │   │       │   │   ├── constants.ts
│       │   │   │   │   │       │   │   ├── email-domain-card.tsx
│       │   │   │   │   │       │   │   ├── email-domain-dns-records.tsx
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── header.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── integrations/
│       │   │   │   │   │       │   ├── [integrationSlug]/
│       │   │   │   │   │       │   │   ├── loading.tsx
│       │   │   │   │   │       │   │   ├── manage/
│       │   │   │   │   │       │   │   │   └── page.tsx
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── enabled/
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── enabled-integrations.tsx
│       │   │   │   │   │       │   ├── featured-integrations.tsx
│       │   │   │   │   │       │   ├── integrations-cards.tsx
│       │   │   │   │   │       │   ├── integrations-list.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── new/
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── members/
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── notifications/
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── oauth-apps/
│       │   │   │   │   │       │   ├── [appId]/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── create-oauth-app-button.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── new/
│       │   │   │   │   │       │   │   ├── page-client.tsx
│       │   │   │   │   │       │   │   └── page.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── page-client.tsx
│       │   │   │   │   │       ├── page.tsx
│       │   │   │   │   │       ├── security/
│       │   │   │   │   │       │   ├── audit-logs.tsx
│       │   │   │   │   │       │   ├── layout.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   ├── page.tsx
│       │   │   │   │   │       │   ├── saml.tsx
│       │   │   │   │   │       │   └── scim.tsx
│       │   │   │   │   │       ├── tokens/
│       │   │   │   │   │       │   └── page.tsx
│       │   │   │   │   │       ├── tracking/
│       │   │   │   │   │       │   ├── add-hostname-modal.tsx
│       │   │   │   │   │       │   ├── base-script-section.tsx
│       │   │   │   │   │       │   ├── complete-step-button.tsx
│       │   │   │   │   │       │   ├── connection-instructions.tsx
│       │   │   │   │   │       │   ├── conversion-tracking-section.tsx
│       │   │   │   │   │       │   ├── conversion-tracking-toggle.tsx
│       │   │   │   │   │       │   ├── guide.tsx
│       │   │   │   │   │       │   ├── hostname-menu.tsx
│       │   │   │   │   │       │   ├── hostname-section.tsx
│       │   │   │   │   │       │   ├── outbound-domain-tracking-section.tsx
│       │   │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │   │       │   ├── page.tsx
│       │   │   │   │   │       │   ├── publishable-key-form.tsx
│       │   │   │   │   │       │   ├── publishable-key-menu.tsx
│       │   │   │   │   │       │   ├── site-visit-tracking-section.tsx
│       │   │   │   │   │       │   ├── step.tsx
│       │   │   │   │   │       │   ├── track-lead-guides-section.tsx
│       │   │   │   │   │       │   ├── track-sales-guides-section.tsx
│       │   │   │   │   │       │   ├── use-dynamic-guide.ts
│       │   │   │   │   │       │   ├── use-selected-guide.ts
│       │   │   │   │   │       │   └── verify-install.tsx
│       │   │   │   │   │       └── webhooks/
│       │   │   │   │   │           ├── [webhookId]/
│       │   │   │   │   │           │   ├── edit/
│       │   │   │   │   │           │   │   ├── page-client.tsx
│       │   │   │   │   │           │   │   └── page.tsx
│       │   │   │   │   │           │   ├── layout.tsx
│       │   │   │   │   │           │   ├── page-client.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── create-webhook-button.tsx
│       │   │   │   │   │           ├── layout.tsx
│       │   │   │   │   │           ├── new/
│       │   │   │   │   │           │   ├── page-client.tsx
│       │   │   │   │   │           │   └── page.tsx
│       │   │   │   │   │           ├── page-client.tsx
│       │   │   │   │   │           └── page.tsx
│       │   │   │   │   ├── analytics/
│       │   │   │   │   │   ├── client.tsx
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   ├── auth.tsx
│       │   │   │   │   ├── layout.tsx
│       │   │   │   │   └── links/
│       │   │   │   │       ├── [...link]/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── domains/
│       │   │   │   │       │   ├── default/
│       │   │   │   │       │   │   └── page.tsx
│       │   │   │   │       │   ├── email/
│       │   │   │   │       │   │   └── page.tsx
│       │   │   │   │       │   ├── layout.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── folders/
│       │   │   │   │       │   ├── [folderId]/
│       │   │   │   │       │   │   └── members/
│       │   │   │   │       │   │       ├── page-client.tsx
│       │   │   │   │       │   │       └── page.tsx
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── page-client.tsx
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       ├── tags/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   ├── page.tsx
│       │   │   │   │       │   ├── tag-card-placeholder.tsx
│       │   │   │   │       │   └── tag-card.tsx
│       │   │   │   │       └── utm/
│       │   │   │   │           ├── page-client.tsx
│       │   │   │   │           ├── page.tsx
│       │   │   │   │           ├── template-card-placeholder.tsx
│       │   │   │   │           └── template-card.tsx
│       │   │   │   ├── account/
│       │   │   │   │   └── settings/
│       │   │   │   │       ├── page-client.tsx
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       ├── referrals/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       ├── security/
│       │   │   │   │       │   ├── page-client.tsx
│       │   │   │   │       │   ├── page.tsx
│       │   │   │   │       │   ├── request-set-password.tsx
│       │   │   │   │       │   └── update-password.tsx
│       │   │   │   │       └── tokens/
│       │   │   │   │           ├── page-client.tsx
│       │   │   │   │           └── page.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   └── loading.tsx
│       │   │   ├── (deeplink)/
│       │   │   │   └── deeplink/
│       │   │   │       └── [domain]/
│       │   │   │           └── [[...key]]/
│       │   │   │               ├── action-buttons.tsx
│       │   │   │               ├── brand-logo-badge.tsx
│       │   │   │               ├── page.tsx
│       │   │   │               └── translations.ts
│       │   │   ├── (invites)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   └── invite/
│       │   │   │   │       ├── accept-invite-button.tsx
│       │   │   │   │       ├── close-invite-button.tsx
│       │   │   │   │       ├── invite-confetti.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   └── layout.tsx
│       │   │   ├── (onboarding)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   └── wrapped/
│       │   │   │   │       ├── [year]/
│       │   │   │   │       │   ├── client.tsx
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       └── page.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── onboarding/
│       │   │   │   │   ├── (steps)/
│       │   │   │   │   │   ├── domain/
│       │   │   │   │   │   │   ├── custom/
│       │   │   │   │   │   │   │   ├── form.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   ├── default-domain-selector.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   └── register/
│       │   │   │   │   │   │       ├── form.tsx
│       │   │   │   │   │   │       └── page.tsx
│       │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   ├── plan/
│       │   │   │   │   │   │   ├── enterprise-link.tsx
│       │   │   │   │   │   │   ├── free-plan-button.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   └── plan-selector.tsx
│       │   │   │   │   │   ├── products/
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   └── product-selector.tsx
│       │   │   │   │   │   ├── program/
│       │   │   │   │   │   │   ├── form.tsx
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   ├── page.tsx
│       │   │   │   │   │   │   ├── reward/
│       │   │   │   │   │   │   │   ├── form.tsx
│       │   │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   │   └── use-onboarding-program.tsx
│       │   │   │   │   │   ├── step-page.tsx
│       │   │   │   │   │   ├── success/
│       │   │   │   │   │   │   ├── page-client.tsx
│       │   │   │   │   │   │   └── page.tsx
│       │   │   │   │   │   └── workspace/
│       │   │   │   │   │       ├── form.tsx
│       │   │   │   │   │       └── page.tsx
│       │   │   │   │   ├── later-button.tsx
│       │   │   │   │   ├── next-button.tsx
│       │   │   │   │   ├── use-onboarding-product.ts
│       │   │   │   │   ├── use-onboarding-progress.ts
│       │   │   │   │   └── welcome/
│       │   │   │   │       ├── page.tsx
│       │   │   │   │       └── track-signup.tsx
│       │   │   │   └── signed-in-hint.tsx
│       │   │   ├── (redirects)/
│       │   │   │   ├── [slug]/
│       │   │   │   │   ├── domains/
│       │   │   │   │   │   └── page.tsx
│       │   │   │   │   └── settings/
│       │   │   │   │       ├── referrals/
│       │   │   │   │       │   └── page.tsx
│       │   │   │   │       └── tags/
│       │   │   │   │           └── page.tsx
│       │   │   │   ├── analytics/
│       │   │   │   │   └── page.tsx
│       │   │   │   └── loading.tsx
│       │   │   ├── (share)/
│       │   │   │   └── share/
│       │   │   │       └── [dashboardId]/
│       │   │   │           ├── action.ts
│       │   │   │           ├── form.tsx
│       │   │   │           └── page.tsx
│       │   │   ├── embed/
│       │   │   │   └── support-chat/
│       │   │   │       ├── dynamic-height-messenger.tsx
│       │   │   │       ├── layout.tsx
│       │   │   │       └── page.tsx
│       │   │   └── layout.tsx
│       │   ├── banned/
│       │   │   └── page.tsx
│       │   ├── cloaked/
│       │   │   └── [url]/
│       │   │       └── page.tsx
│       │   ├── custom-uri-scheme/
│       │   │   └── [url]/
│       │   │       └── page.tsx
│       │   ├── expired/
│       │   │   └── [domain]/
│       │   │       └── page.tsx
│       │   ├── inspect/
│       │   │   └── [domain]/
│       │   │       └── [key]/
│       │   │           ├── card.tsx
│       │   │           └── page.tsx
│       │   ├── layout.tsx
│       │   ├── manifest.ts
│       │   ├── not-found-hint.tsx
│       │   ├── not-found.tsx
│       │   ├── password/
│       │   │   └── [linkId]/
│       │   │       ├── action.ts
│       │   │       ├── form.tsx
│       │   │       ├── loading.tsx
│       │   │       └── page.tsx
│       │   ├── providers.tsx
│       │   ├── proxy/
│       │   │   └── [domain]/
│       │   │       └── [key]/
│       │   │           └── page.tsx
│       │   ├── robots.ts
│       │   ├── sitemap.ts
│       │   └── wellknown/
│       │       └── [domain]/
│       │           └── [file]/
│       │               └── route.ts
│       ├── docker-compose.yml
│       ├── global-setup.ts
│       ├── guides/
│       │   ├── appwrite.md
│       │   ├── auth0.md
│       │   ├── better-auth.md
│       │   ├── clerk.md
│       │   ├── framer.md
│       │   ├── gtm-client-sdk.md
│       │   ├── gtm-track-lead.md
│       │   ├── gtm-track-sale.md
│       │   ├── manual-client-sdk.md
│       │   ├── manual-track-lead.md
│       │   ├── manual-track-sale.md
│       │   ├── next-auth.md
│       │   ├── react.md
│       │   ├── rest-api.md
│       │   ├── segment-track-lead.md
│       │   ├── segment-track-sale.md
│       │   ├── shopify.md
│       │   ├── stripe-checkout.md
│       │   ├── stripe-customers.md
│       │   ├── stripe-payment-links.md
│       │   ├── supabase.md
│       │   ├── webflow.md
│       │   └── wordpress.md
│       ├── instrumentation.ts
│       ├── lib/
│       │   ├── actions/
│       │   │   ├── add-edit-integration.ts
│       │   │   ├── auth/
│       │   │   │   └── throw-if-authenticated.ts
│       │   │   ├── check-account-exists.ts
│       │   │   ├── create-oauth-url.ts
│       │   │   ├── create-user-account.ts
│       │   │   ├── enable-disable-webhook.ts
│       │   │   ├── folders/
│       │   │   │   ├── request-folder-edit-access.ts
│       │   │   │   ├── set-default-folder.ts
│       │   │   │   └── update-folder-user-role.ts
│       │   │   ├── fraud/
│       │   │   │   ├── bulk-resolve-fraud-groups.ts
│       │   │   │   └── resolve-fraud-group.ts
│       │   │   ├── generate-client-secret.ts
│       │   │   ├── generate-unsubscribe-url.ts
│       │   │   ├── get-integration-install-url.ts
│       │   │   ├── parse-action-errors.ts
│       │   │   ├── partners/
│       │   │   │   ├── accept-program-invite.ts
│       │   │   │   ├── approve-bounty-submission.ts
│       │   │   │   ├── approve-partner.ts
│       │   │   │   ├── archive-partner.ts
│       │   │   │   ├── ban-partner.ts
│       │   │   │   ├── bulk-approve-partners.ts
│       │   │   │   ├── bulk-archive-partners.ts
│       │   │   │   ├── bulk-ban-partners.ts
│       │   │   │   ├── bulk-deactivate-partners.ts
│       │   │   │   ├── bulk-invite-partners.ts
│       │   │   │   ├── bulk-reject-partner-applications.ts
│       │   │   │   ├── confirm-payouts.ts
│       │   │   │   ├── create-bounty-submission.ts
│       │   │   │   ├── create-clawback.ts
│       │   │   │   ├── create-discount.ts
│       │   │   │   ├── create-manual-commission.ts
│       │   │   │   ├── create-partner-comment.ts
│       │   │   │   ├── create-program-application.ts
│       │   │   │   ├── create-program.ts
│       │   │   │   ├── create-reward.ts
│       │   │   │   ├── deactivate-partner.ts
│       │   │   │   ├── delete-discount.ts
│       │   │   │   ├── delete-partner-comment.ts
│       │   │   │   ├── delete-program-invite.ts
│       │   │   │   ├── delete-reward.ts
│       │   │   │   ├── force-withdrawal.ts
│       │   │   │   ├── generate-lander.ts
│       │   │   │   ├── generate-paypal-oauth-url.ts
│       │   │   │   ├── generate-stripe-account-link.ts
│       │   │   │   ├── generate-stripe-recipient-account-link.ts
│       │   │   │   ├── get-conversion-score.ts
│       │   │   │   ├── invite-partner-from-network.ts
│       │   │   │   ├── invite-partner.ts
│       │   │   │   ├── mark-commission-duplicate.ts
│       │   │   │   ├── mark-commission-fraud-or-canceled.ts
│       │   │   │   ├── mark-partner-messages-read.ts
│       │   │   │   ├── mark-program-messages-read.ts
│       │   │   │   ├── merge-partner-accounts.ts
│       │   │   │   ├── message-partner.ts
│       │   │   │   ├── message-program.ts
│       │   │   │   ├── onboard-partner.ts
│       │   │   │   ├── onboard-program.ts
│       │   │   │   ├── program-resources/
│       │   │   │   │   ├── add-program-resource.ts
│       │   │   │   │   ├── constants.ts
│       │   │   │   │   ├── delete-program-resource.ts
│       │   │   │   │   ├── get-program-resource-upload-url.ts
│       │   │   │   │   └── update-program-resource.ts
│       │   │   │   ├── reactivate-partner.ts
│       │   │   │   ├── reject-bounty-submission.ts
│       │   │   │   ├── reject-partner-application.ts
│       │   │   │   ├── reopen-bounty-submission.ts
│       │   │   │   ├── resend-program-invite.ts
│       │   │   │   ├── retry-failed-paypal-payouts.ts
│       │   │   │   ├── revoke-program-invite.ts
│       │   │   │   ├── save-invite-email-data.ts
│       │   │   │   ├── set-rewardful-token.ts
│       │   │   │   ├── set-tolt-token.ts
│       │   │   │   ├── start-firstpromoter-import.ts
│       │   │   │   ├── start-partner-platform-verification.ts
│       │   │   │   ├── start-partnerstack-import.ts
│       │   │   │   ├── start-rewardful-import.ts
│       │   │   │   ├── start-tolt-import.ts
│       │   │   │   ├── trigger-aggregate-due-commissions.ts
│       │   │   │   ├── unban-partner.ts
│       │   │   │   ├── update-application-settings.ts
│       │   │   │   ├── update-discount.ts
│       │   │   │   ├── update-discovered-partner.ts
│       │   │   │   ├── update-group-branding.ts
│       │   │   │   ├── update-partner-comment.ts
│       │   │   │   ├── update-partner-enrollment.ts
│       │   │   │   ├── update-partner-notification-preference.ts
│       │   │   │   ├── update-partner-payout-settings.ts
│       │   │   │   ├── update-partner-platforms.ts
│       │   │   │   ├── update-partner-profile.ts
│       │   │   │   ├── update-program.ts
│       │   │   │   ├── update-reward.ts
│       │   │   │   ├── upload-bounty-submission-file.ts
│       │   │   │   ├── upload-campaign-image.ts
│       │   │   │   ├── upload-lander-image.ts
│       │   │   │   ├── upload-program-application-image.ts
│       │   │   │   ├── verify-partner-website.ts
│       │   │   │   ├── verify-social-account-by-code.ts
│       │   │   │   └── withdraw-partner-application.ts
│       │   │   ├── referrals/
│       │   │   │   ├── submit-referral.ts
│       │   │   │   ├── update-referral-status.ts
│       │   │   │   └── update-referral.ts
│       │   │   ├── request-password-reset.ts
│       │   │   ├── safe-action.ts
│       │   │   ├── send-invite-referral-email.ts
│       │   │   ├── send-otp.ts
│       │   │   ├── send-test-webhook.ts
│       │   │   ├── set-onboarding-progress.ts
│       │   │   ├── submit-oauth-app-for-review.ts
│       │   │   ├── throw-if-no-permission.ts
│       │   │   ├── update-workspace-notification-preference.ts
│       │   │   ├── update-workspace-preferences.ts
│       │   │   ├── update-workspace-store.ts
│       │   │   └── verify-workspace-setup.ts
│       │   ├── ai/
│       │   │   ├── build-system-prompt.ts
│       │   │   ├── create-support-ticket.ts
│       │   │   ├── find-relevant-docs.ts
│       │   │   ├── generate-csv-mapping.ts
│       │   │   ├── generate-filters.ts
│       │   │   ├── get-program-performance.ts
│       │   │   ├── get-workspace-details.ts
│       │   │   ├── request-support-ticket.ts
│       │   │   └── upsert-docs-embedding.ts
│       │   ├── analytics/
│       │   │   ├── allowed-hostnames-cache.ts
│       │   │   ├── constants.ts
│       │   │   ├── convert-currency.ts
│       │   │   ├── events-export-helpers.ts
│       │   │   ├── filter-helpers.ts
│       │   │   ├── format-date-tooltip.ts
│       │   │   ├── get-analytics.ts
│       │   │   ├── get-customer-events.ts
│       │   │   ├── get-events.ts
│       │   │   ├── get-folder-ids-to-filter.ts
│       │   │   ├── is-first-conversion.ts
│       │   │   ├── metadata-query-parser.ts
│       │   │   ├── types.ts
│       │   │   ├── utils/
│       │   │   │   ├── convert-to-csv.ts
│       │   │   │   ├── edit-query-string.ts
│       │   │   │   ├── format-utc-datetime-clickhouse.ts
│       │   │   │   ├── get-interval-data.ts
│       │   │   │   ├── get-start-end-dates.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── valid-date-range-for-plan.ts
│       │   │   └── verify-analytics-allowed-hostnames.ts
│       │   ├── api/
│       │   │   ├── activity-log/
│       │   │   │   ├── build-program-enrollment-change-set.ts
│       │   │   │   ├── get-resource-diff.ts
│       │   │   │   ├── track-activity-log.ts
│       │   │   │   └── track-reward-activity-log.ts
│       │   │   ├── audit-logs/
│       │   │   │   ├── get-audit-logs.ts
│       │   │   │   ├── record-audit-log.ts
│       │   │   │   └── schemas.ts
│       │   │   ├── campaigns/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── get-campaign-events.ts
│       │   │   │   ├── get-campaign-or-throw.ts
│       │   │   │   ├── get-campaign-summary.ts
│       │   │   │   ├── schedule-campaigns.ts
│       │   │   │   └── validate-campaign.ts
│       │   │   ├── commissions/
│       │   │   │   ├── format-commissions-for-export.ts
│       │   │   │   ├── get-commissions-count.ts
│       │   │   │   └── get-commissions.ts
│       │   │   ├── conversions/
│       │   │   │   ├── track-lead.ts
│       │   │   │   └── track-sale.ts
│       │   │   ├── cors.ts
│       │   │   ├── create-downloadable-export.ts
│       │   │   ├── create-id.ts
│       │   │   ├── customers/
│       │   │   │   ├── get-customer-or-throw.ts
│       │   │   │   ├── get-customer-stripe-invoices.ts
│       │   │   │   └── transform-customer.ts
│       │   │   ├── discounts/
│       │   │   │   ├── construct-discount-code.ts
│       │   │   │   ├── create-discount-code.ts
│       │   │   │   ├── delete-discount-code.ts
│       │   │   │   └── is-discount-equivalent.ts
│       │   │   ├── domains/
│       │   │   │   ├── add-domain-vercel.ts
│       │   │   │   ├── claim-dot-link-domain.ts
│       │   │   │   ├── configure-vercel-nameservers.ts
│       │   │   │   ├── get-config-response.ts
│       │   │   │   ├── get-domain-or-throw.ts
│       │   │   │   ├── get-domain-response.ts
│       │   │   │   ├── get-email-domain-or-throw.ts
│       │   │   │   ├── is-valid-domain.ts
│       │   │   │   ├── mark-domain-deleted.ts
│       │   │   │   ├── queue-domain-update.ts
│       │   │   │   ├── remove-domain-vercel.ts
│       │   │   │   ├── transform-domain.ts
│       │   │   │   ├── utils.ts
│       │   │   │   └── verify-domain.ts
│       │   │   ├── environment.ts
│       │   │   ├── error-codes.ts
│       │   │   ├── errors.ts
│       │   │   ├── folders/
│       │   │   │   ├── delete-workspace-folders.ts
│       │   │   │   └── queue-folder-deletion.ts
│       │   │   ├── fraud/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── create-fraud-events.ts
│       │   │   │   ├── define-fraud-rule.ts
│       │   │   │   ├── detect-duplicate-payout-method-fraud.ts
│       │   │   │   ├── detect-record-fraud-application.ts
│       │   │   │   ├── detect-record-fraud-event.ts
│       │   │   │   ├── execute-fraud-rule.ts
│       │   │   │   ├── get-merged-fraud-rules.ts
│       │   │   │   ├── get-partner-application-risks.ts
│       │   │   │   ├── report-cross-program-ban-to-network.ts
│       │   │   │   ├── report-fraud-to-network.ts
│       │   │   │   ├── resolve-fraud-groups.ts
│       │   │   │   ├── rules/
│       │   │   │   │   ├── check-customer-email-match.ts
│       │   │   │   │   ├── check-customer-email-suspicious.ts
│       │   │   │   │   ├── check-paid-traffic-detected.ts
│       │   │   │   │   ├── check-partner-email-domain-mismatch.ts
│       │   │   │   │   ├── check-partner-email-masked.ts
│       │   │   │   │   ├── check-partner-no-social-links.ts
│       │   │   │   │   ├── check-partner-no-verified-social-links.ts
│       │   │   │   │   └── check-referral-source-banned.ts
│       │   │   │   └── utils.ts
│       │   │   ├── get-ratelimit-for-plan.ts
│       │   │   ├── get-workspace-users.ts
│       │   │   ├── groups/
│       │   │   │   ├── find-groups-with-matching-rules.ts
│       │   │   │   ├── get-group-move-rules.ts
│       │   │   │   ├── get-group-or-throw.ts
│       │   │   │   ├── get-groups.ts
│       │   │   │   ├── move-partners-to-group.ts
│       │   │   │   ├── throw-if-invalid-group-ids.ts
│       │   │   │   ├── upsert-group-move-rules.ts
│       │   │   │   └── validate-group-move-rules.ts
│       │   │   ├── links/
│       │   │   │   ├── ab-test-scheduler.ts
│       │   │   │   ├── archive-link.ts
│       │   │   │   ├── bulk-create-links.ts
│       │   │   │   ├── bulk-delete-links.ts
│       │   │   │   ├── bulk-update-links.ts
│       │   │   │   ├── cache.ts
│       │   │   │   ├── case-sensitivity.ts
│       │   │   │   ├── complete-ab-tests.ts
│       │   │   │   ├── create-link.ts
│       │   │   │   ├── delete-link.ts
│       │   │   │   ├── format-links-for-export.ts
│       │   │   │   ├── get-link-or-throw.ts
│       │   │   │   ├── get-links-count.ts
│       │   │   │   ├── get-links-for-workspace.ts
│       │   │   │   ├── include-program-enrollment.ts
│       │   │   │   ├── include-tags.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── plan-features-check.ts
│       │   │   │   ├── process-link.ts
│       │   │   │   ├── propagate-bulk-link-changes.ts
│       │   │   │   ├── record-click-cache.ts
│       │   │   │   ├── update-link-stats-for-importer.ts
│       │   │   │   ├── update-link.ts
│       │   │   │   ├── update-links-usage.ts
│       │   │   │   ├── usage-checks.ts
│       │   │   │   ├── utils/
│       │   │   │   │   ├── check-if-links-have-folders.ts
│       │   │   │   │   ├── check-if-links-have-tags.ts
│       │   │   │   │   ├── check-if-links-have-webhooks.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── key-checks.ts
│       │   │   │   │   ├── process-key.ts
│       │   │   │   │   └── transform-link.ts
│       │   │   │   ├── validate-links-query-filters.ts
│       │   │   │   └── validate-partner-link-url.ts
│       │   │   ├── network/
│       │   │   │   └── calculate-partner-ranking.ts
│       │   │   ├── oauth/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── constants.ts
│       │   │   │   └── utils.ts
│       │   │   ├── pagination.ts
│       │   │   ├── partner-profile/
│       │   │   │   ├── client.ts
│       │   │   │   ├── get-partner-earnings-timeseries.ts
│       │   │   │   ├── get-partner-for-program.ts
│       │   │   │   ├── obfuscate-customer-email.ts
│       │   │   │   ├── partner-platforms-providers.ts
│       │   │   │   └── upsert-partner-platform.ts
│       │   │   ├── partners/
│       │   │   │   ├── bulk-deactivate-partners.ts
│       │   │   │   ├── bulk-delete-partners.ts
│       │   │   │   ├── create-and-enroll-partner.ts
│       │   │   │   ├── create-partner-default-links.ts
│       │   │   │   ├── deactivate-partner.ts
│       │   │   │   ├── format-partners-for-export.ts
│       │   │   │   ├── generate-partner-link.ts
│       │   │   │   ├── get-discount-or-throw.ts
│       │   │   │   ├── get-group-rewards-and-bounties.ts
│       │   │   │   ├── get-network-invites-usage.ts
│       │   │   │   ├── get-partner-rewind.ts
│       │   │   │   ├── get-partner-users.ts
│       │   │   │   ├── get-partners-count.ts
│       │   │   │   ├── get-partners.ts
│       │   │   │   ├── get-reward-or-throw.ts
│       │   │   │   ├── invite-partner-user.ts
│       │   │   │   ├── notify-partner-application.ts
│       │   │   │   ├── notify-partner-commission.ts
│       │   │   │   ├── notify-partner-group-change.ts
│       │   │   │   ├── process-partner-deactivation.ts
│       │   │   │   ├── serialize-reward.ts
│       │   │   │   ├── sync-partner-links-stats.ts
│       │   │   │   ├── sync-total-commissions.ts
│       │   │   │   └── throw-if-existing-tenant-id-exists.ts
│       │   │   ├── payouts/
│       │   │   │   ├── get-effective-payout-mode.ts
│       │   │   │   ├── get-eligible-payouts.ts
│       │   │   │   ├── get-payout-or-throw.ts
│       │   │   │   └── payout-eligibility-filter.ts
│       │   │   ├── postbacks/
│       │   │   │   └── get-postback-or-throw.ts
│       │   │   ├── programs/
│       │   │   │   ├── deactivate-program.ts
│       │   │   │   ├── get-default-program-id-or-throw.ts
│       │   │   │   ├── get-program-enrollment-or-throw.ts
│       │   │   │   └── get-program-or-throw.ts
│       │   │   ├── rbac/
│       │   │   │   ├── permissions.ts
│       │   │   │   └── resources.ts
│       │   │   ├── referrals/
│       │   │   │   ├── get-referral-or-throw.ts
│       │   │   │   ├── mark-referral-closed-won.ts
│       │   │   │   ├── mark-referral-qualified.ts
│       │   │   │   ├── notify-partner-referral-submitted.ts
│       │   │   │   └── notify-referral-status-update.ts
│       │   │   ├── rewards/
│       │   │   │   └── validate-reward.ts
│       │   │   ├── sales/
│       │   │   │   ├── calculate-sale-earnings.ts
│       │   │   │   ├── construct-discount-amount.ts
│       │   │   │   └── construct-reward-amount.ts
│       │   │   ├── scrape-creators/
│       │   │   │   ├── client.ts
│       │   │   │   ├── get-linkedin-post.ts
│       │   │   │   ├── get-social-content.ts
│       │   │   │   ├── get-social-profile.ts
│       │   │   │   └── schema.ts
│       │   │   ├── tags/
│       │   │   │   └── combine-tag-ids.ts
│       │   │   ├── tokens/
│       │   │   │   ├── scopes.ts
│       │   │   │   └── throw-if-no-access.ts
│       │   │   ├── users.ts
│       │   │   ├── utils/
│       │   │   │   ├── assert-valid-date-range-for-plan.ts
│       │   │   │   ├── generate-export-filename.ts
│       │   │   │   ├── generate-random-string.ts
│       │   │   │   ├── get-ip.ts
│       │   │   │   ├── is-non-empty-json.ts
│       │   │   │   └── with-prisma-retry.ts
│       │   │   ├── utils.ts
│       │   │   ├── utm/
│       │   │   │   └── extract-utm-params.ts
│       │   │   ├── validate-allowed-hostnames.ts
│       │   │   ├── workflows/
│       │   │   │   ├── evaluate-workflow-conditions.ts
│       │   │   │   ├── execute-complete-bounty-workflow.ts
│       │   │   │   ├── execute-move-group-workflow.ts
│       │   │   │   ├── execute-send-campaign-workflow.ts
│       │   │   │   ├── execute-workflows.ts
│       │   │   │   ├── interpolate-email-template.ts
│       │   │   │   ├── parse-workflow-config.ts
│       │   │   │   ├── render-campaign-email-html.ts
│       │   │   │   ├── render-campaign-email-markdown.ts
│       │   │   │   └── utils.ts
│       │   │   └── workspaces/
│       │   │       ├── assert-role-plan.ts
│       │   │       ├── create-workspace-id.ts
│       │   │       ├── delete-workspace.ts
│       │   │       ├── is-saml-enforced-for-email-domain.ts
│       │   │       ├── onboarding-step-cache.ts
│       │   │       └── workspace-id.ts
│       │   ├── auth/
│       │   │   ├── admin.ts
│       │   │   ├── confirm-email-change.ts
│       │   │   ├── constants.ts
│       │   │   ├── hash-token.ts
│       │   │   ├── index.ts
│       │   │   ├── lock-account.ts
│       │   │   ├── options.ts
│       │   │   ├── partner-users/
│       │   │   │   ├── partner-user-permissions.ts
│       │   │   │   └── throw-if-no-permission.ts
│       │   │   ├── partner.ts
│       │   │   ├── password.ts
│       │   │   ├── publishable-key.ts
│       │   │   ├── rate-limit-request.ts
│       │   │   ├── session.ts
│       │   │   ├── token-cache.ts
│       │   │   ├── track-dub-lead.ts
│       │   │   ├── utils.ts
│       │   │   └── workspace.ts
│       │   ├── axiom/
│       │   │   ├── axiom.ts
│       │   │   └── server.ts
│       │   ├── bounty/
│       │   │   ├── api/
│       │   │   │   ├── approve-bounty-submission.ts
│       │   │   │   ├── create-bounty-submission.ts
│       │   │   │   ├── generate-performance-bounty-name.ts
│       │   │   │   ├── get-bounties-by-groups.ts
│       │   │   │   ├── get-bounty-or-throw.ts
│       │   │   │   ├── get-bounty-with-details.ts
│       │   │   │   ├── get-group-bounty-summaries.ts
│       │   │   │   ├── get-social-metrics-updates.ts
│       │   │   │   ├── performance-bounty-scope-attributes.ts
│       │   │   │   ├── reject-bounty-submission.ts
│       │   │   │   ├── trigger-draft-bounty-submissions.ts
│       │   │   │   └── validate-bounty.ts
│       │   │   ├── constants.ts
│       │   │   ├── periods.ts
│       │   │   ├── rewards.ts
│       │   │   ├── social-content.ts
│       │   │   ├── submission-status.ts
│       │   │   └── utils.ts
│       │   ├── client-access-check.ts
│       │   ├── constants/
│       │   │   ├── misc.ts
│       │   │   ├── notification-preferences.ts
│       │   │   ├── partner-profile.ts
│       │   │   ├── payouts-supported-countries.ts
│       │   │   ├── payouts.ts
│       │   │   └── program.ts
│       │   ├── cron/
│       │   │   ├── enqueue-batch-jobs.ts
│       │   │   ├── index.ts
│       │   │   ├── limiter.ts
│       │   │   ├── qstash-workflow-logger.ts
│       │   │   ├── qstash-workflow.ts
│       │   │   ├── send-limit-email.ts
│       │   │   ├── verify-qstash.ts
│       │   │   ├── verify-vercel.ts
│       │   │   └── with-cron.ts
│       │   ├── customers/
│       │   │   └── api/
│       │   │       ├── customer-count-where.ts
│       │   │       ├── fetch-customers-batch.ts
│       │   │       ├── format-customers-export.ts
│       │   │       └── get-customers.ts
│       │   ├── dub.ts
│       │   ├── dynadot/
│       │   │   ├── constants.ts
│       │   │   ├── register-domain.ts
│       │   │   ├── search-domains.ts
│       │   │   └── set-renew-option.ts
│       │   ├── edge-config/
│       │   │   ├── get-feature-flags.ts
│       │   │   ├── get-partner-feature-flags.ts
│       │   │   ├── index.ts
│       │   │   ├── is-blacklisted-domain.ts
│       │   │   ├── is-blacklisted-email.ts
│       │   │   ├── is-blacklisted-key.ts
│       │   │   ├── is-blacklisted-referrer.ts
│       │   │   ├── is-reserved-username.ts
│       │   │   └── update.ts
│       │   ├── email/
│       │   │   ├── email-templates-map.ts
│       │   │   ├── extract-email-domain.ts
│       │   │   ├── queue-batch-email.ts
│       │   │   └── unsubscribe-token.ts
│       │   ├── embed/
│       │   │   ├── constants.ts
│       │   │   └── referrals/
│       │   │       ├── auth.ts
│       │   │       └── token-class.ts
│       │   ├── exceeded-limit-error.ts
│       │   ├── fetchers/
│       │   │   ├── get-content-api.ts
│       │   │   ├── get-dashboard.ts
│       │   │   ├── get-network-program.ts
│       │   │   ├── get-program-slugs.ts
│       │   │   ├── get-program.ts
│       │   │   └── index.ts
│       │   ├── firstpromoter/
│       │   │   ├── api.ts
│       │   │   ├── import-campaigns.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   ├── types.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── folder/
│       │   │   ├── constants.ts
│       │   │   ├── get-folder-or-throw.ts
│       │   │   ├── get-folders.ts
│       │   │   └── permissions.ts
│       │   ├── form-utils.ts
│       │   ├── get-highest-severity.ts
│       │   ├── get-integration-guide-markdown.ts
│       │   ├── hooks/
│       │   │   └── use-synced-local-storage.ts
│       │   ├── integrations/
│       │   │   ├── bitly/
│       │   │   │   └── oauth.ts
│       │   │   ├── common/
│       │   │   │   └── ui/
│       │   │   │       └── configure-webhook.tsx
│       │   │   ├── hubspot/
│       │   │   │   ├── api.ts
│       │   │   │   ├── constants.ts
│       │   │   │   ├── oauth.ts
│       │   │   │   ├── schema.ts
│       │   │   │   ├── track-lead.ts
│       │   │   │   ├── track-sale.ts
│       │   │   │   ├── ui/
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── update-hubspot-settings.ts
│       │   │   ├── install.ts
│       │   │   ├── oauth-provider.ts
│       │   │   ├── segment/
│       │   │   │   ├── install.ts
│       │   │   │   ├── transform.ts
│       │   │   │   ├── ui/
│       │   │   │   │   ├── set-write-key.tsx
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── utils.ts
│       │   │   ├── shopify/
│       │   │   │   ├── create-lead.ts
│       │   │   │   ├── create-sale.ts
│       │   │   │   ├── process-order.ts
│       │   │   │   └── schema.ts
│       │   │   ├── singular/
│       │   │   │   ├── track-lead.ts
│       │   │   │   └── track-sale.ts
│       │   │   ├── slack/
│       │   │   │   ├── commands.ts
│       │   │   │   ├── oauth.ts
│       │   │   │   ├── schema.ts
│       │   │   │   ├── transform.ts
│       │   │   │   ├── ui/
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── verify-request.ts
│       │   │   ├── stripe/
│       │   │   │   ├── schema.ts
│       │   │   │   ├── ui/
│       │   │   │   │   └── settings.tsx
│       │   │   │   └── update-stripe-settings.ts
│       │   │   ├── types.ts
│       │   │   ├── utils.ts
│       │   │   └── zapier/
│       │   │       └── ui/
│       │   │           └── settings.tsx
│       │   ├── is-generic-email.ts
│       │   ├── jackson.ts
│       │   ├── links/
│       │   │   └── links-display.ts
│       │   ├── middleware/
│       │   │   ├── admin.ts
│       │   │   ├── api.ts
│       │   │   ├── app.ts
│       │   │   ├── create-link.ts
│       │   │   ├── embed.ts
│       │   │   ├── link.ts
│       │   │   ├── new-link.ts
│       │   │   ├── partners.ts
│       │   │   ├── utils/
│       │   │   │   ├── app-redirect.ts
│       │   │   │   ├── bots-list.ts
│       │   │   │   ├── cache-deeplink-click-data.ts
│       │   │   │   ├── crawl-bitly.ts
│       │   │   │   ├── create-response-with-cookies.ts
│       │   │   │   ├── detect-bot.ts
│       │   │   │   ├── detect-qr.ts
│       │   │   │   ├── get-default-partner.ts
│       │   │   │   ├── get-default-workspace.ts
│       │   │   │   ├── get-final-url.ts
│       │   │   │   ├── get-identity-hash.ts
│       │   │   │   ├── get-user-via-token.ts
│       │   │   │   ├── get-workspace-product.ts
│       │   │   │   ├── handle-not-found-link.ts
│       │   │   │   ├── has-pending-invites.ts
│       │   │   │   ├── is-google-play-store-url.ts
│       │   │   │   ├── is-ios-app-store-url.ts
│       │   │   │   ├── is-ip-in-range.ts
│       │   │   │   ├── is-singular-tracking-url.ts
│       │   │   │   ├── is-supported-custom-uri-scheme.ts
│       │   │   │   ├── is-top-level-settings-redirect.ts
│       │   │   │   ├── is-valid-internal-redirect.ts
│       │   │   │   ├── parse.ts
│       │   │   │   ├── partners-redirect.ts
│       │   │   │   └── resolve-ab-test-url.ts
│       │   │   └── workspaces.ts
│       │   ├── names.ts
│       │   ├── network/
│       │   │   ├── get-discoverability-requirements.ts
│       │   │   ├── get-partner-profile-checklist-progress.ts
│       │   │   └── program-categories.ts
│       │   ├── next-auth.d.ts
│       │   ├── onboarding/
│       │   │   └── types.ts
│       │   ├── openapi/
│       │   │   ├── analytics/
│       │   │   │   └── index.ts
│       │   │   ├── bounties/
│       │   │   │   ├── approve-bounty-submission.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-bounty-submissions.ts
│       │   │   │   └── reject-bounty-submission.ts
│       │   │   ├── commissions/
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-commissions.ts
│       │   │   │   └── update-commission.ts
│       │   │   ├── customers/
│       │   │   │   ├── delete-customer.ts
│       │   │   │   ├── get-customer.ts
│       │   │   │   ├── get-customers.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── update-customer.ts
│       │   │   ├── domains/
│       │   │   │   ├── check-domain-status.ts
│       │   │   │   ├── create-domain.ts
│       │   │   │   ├── delete-domain.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-domains.ts
│       │   │   │   ├── register-domain.ts
│       │   │   │   └── update-domain.ts
│       │   │   ├── embed-tokens/
│       │   │   │   ├── create-referrals-embed-token.ts
│       │   │   │   └── index.ts
│       │   │   ├── events/
│       │   │   │   └── index.ts
│       │   │   ├── folders/
│       │   │   │   ├── create-folder.ts
│       │   │   │   ├── delete-folder.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-folders.ts
│       │   │   │   └── update-folder.ts
│       │   │   ├── index.ts
│       │   │   ├── links/
│       │   │   │   ├── bulk-create-links.ts
│       │   │   │   ├── bulk-delete-links.ts
│       │   │   │   ├── bulk-update-links.ts
│       │   │   │   ├── create-link.ts
│       │   │   │   ├── delete-link.ts
│       │   │   │   ├── get-link-info.ts
│       │   │   │   ├── get-links-count.ts
│       │   │   │   ├── get-links.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── update-link.ts
│       │   │   │   └── upsert-link.ts
│       │   │   ├── partners/
│       │   │   │   ├── ban-partner.ts
│       │   │   │   ├── create-partner-link.ts
│       │   │   │   ├── create-partner.ts
│       │   │   │   ├── deactivate-partner.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── list-partners.ts
│       │   │   │   ├── retrieve-analytics.ts
│       │   │   │   ├── retrieve-partner-links.ts
│       │   │   │   └── upsert-partner-link.ts
│       │   │   ├── payouts/
│       │   │   │   ├── index.ts
│       │   │   │   └── list-payouts.ts
│       │   │   ├── qr/
│       │   │   │   └── index.ts
│       │   │   ├── responses.ts
│       │   │   ├── tags/
│       │   │   │   ├── create-tag.ts
│       │   │   │   ├── delete-tag.ts
│       │   │   │   ├── get-tags.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── update-tag.ts
│       │   │   └── track/
│       │   │       ├── index.ts
│       │   │       ├── lead.ts
│       │   │       ├── open.ts
│       │   │       └── sale.ts
│       │   ├── partners/
│       │   │   ├── aggregate-partner-links-stats.ts
│       │   │   ├── approve-partner-enrollment.ts
│       │   │   ├── calculate-payout-fee-with-waiver.ts
│       │   │   ├── complete-program-applications.ts
│       │   │   ├── construct-partner-link.ts
│       │   │   ├── create-partner-commission.ts
│       │   │   ├── create-stablecoin-payout.ts
│       │   │   ├── create-stripe-transfer.ts
│       │   │   ├── cutoff-period.ts
│       │   │   ├── determine-partner-reward.ts
│       │   │   ├── evaluate-application-requirements.ts
│       │   │   ├── evaluate-reward-conditions.ts
│       │   │   ├── format-application-form-data.ts
│       │   │   ├── get-group-rewards-and-discount.ts
│       │   │   ├── get-link-structure-options.ts
│       │   │   ├── get-partner-bank-account.ts
│       │   │   ├── get-payout-methods-for-country.ts
│       │   │   ├── get-reward-amount.ts
│       │   │   ├── partner-platforms.ts
│       │   │   ├── partner-profile.ts
│       │   │   ├── query-link-structure-help-text.tsx
│       │   │   ├── sanitize-markdown.ts
│       │   │   ├── sort-rewards-by-event-order.ts
│       │   │   └── throw-if-no-partnerid-tenantid.ts
│       │   ├── partnerstack/
│       │   │   ├── api.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-groups.ts
│       │   │   ├── import-links.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   ├── types.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── payouts/
│       │   │   ├── create-payouts-idempotency-key.ts
│       │   │   ├── get-partner-payout-methods.ts
│       │   │   ├── mark-payouts-as-processed.ts
│       │   │   └── recompute-partner-payout-state.ts
│       │   ├── paypal/
│       │   │   ├── create-batch-payout.ts
│       │   │   ├── create-paypal-token.ts
│       │   │   ├── env.ts
│       │   │   ├── get-pending-payouts.ts
│       │   │   ├── oauth.ts
│       │   │   └── schema.ts
│       │   ├── plain/
│       │   │   ├── client.ts
│       │   │   ├── create-plain-thread.ts
│       │   │   ├── sync-user-plan.ts
│       │   │   └── upsert-plain-customer.ts
│       │   ├── plan-capabilities.ts
│       │   ├── planetscale/
│       │   │   ├── check-if-key-exists.ts
│       │   │   ├── check-if-user-exists.ts
│       │   │   ├── connection.ts
│       │   │   ├── get-domain-via-edge.ts
│       │   │   ├── get-link-via-edge.ts
│       │   │   ├── get-link-with-partner.ts
│       │   │   ├── get-partner-enrollment-info.ts
│       │   │   ├── get-random-key.ts
│       │   │   ├── get-shortlink-via-edge.ts
│       │   │   ├── get-workspace-via-edge.ts
│       │   │   ├── granularity.ts
│       │   │   ├── index.ts
│       │   │   └── types.ts
│       │   ├── plans/
│       │   │   └── has-partner-access.ts
│       │   ├── postback/
│       │   │   ├── api/
│       │   │   │   ├── get-postback-events.ts
│       │   │   │   ├── postback-adapter-custom.ts
│       │   │   │   ├── postback-adapter-slack.ts
│       │   │   │   ├── postback-adapters.ts
│       │   │   │   ├── postback-event-enrichers.ts
│       │   │   │   ├── postback-event-transformers.ts
│       │   │   │   ├── record-postback-event.ts
│       │   │   │   ├── send-partner-postback.ts
│       │   │   │   └── utils.ts
│       │   │   ├── constants.ts
│       │   │   ├── sample-events/
│       │   │   │   ├── commission-created.json
│       │   │   │   ├── lead-created.json
│       │   │   │   └── sale-created.json
│       │   │   └── schemas.ts
│       │   ├── qr/
│       │   │   ├── api.tsx
│       │   │   ├── codegen.ts
│       │   │   ├── constants.ts
│       │   │   ├── index.tsx
│       │   │   ├── types.ts
│       │   │   └── utils.tsx
│       │   ├── referrals/
│       │   │   └── constants.ts
│       │   ├── rewardful/
│       │   │   ├── api.ts
│       │   │   ├── import-affiliate-coupons.ts
│       │   │   ├── import-campaigns.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   └── types.ts
│       │   ├── social-utils.ts
│       │   ├── storage.ts
│       │   ├── stripe/
│       │   │   ├── cancel-subscription.ts
│       │   │   ├── check-payment-method-mandate.ts
│       │   │   ├── client.ts
│       │   │   ├── coupon-discount-converter.ts
│       │   │   ├── create-connected-account.ts
│       │   │   ├── create-fx-quote.ts
│       │   │   ├── create-payment-intent.ts
│       │   │   ├── create-stripe-discount-code.ts
│       │   │   ├── create-stripe-outbound-payment.ts
│       │   │   ├── create-stripe-recipient-account-link.ts
│       │   │   ├── create-stripe-recipient-account.ts
│       │   │   ├── disable-stripe-discount-code.ts
│       │   │   ├── fund-financial-account.ts
│       │   │   ├── get-stripe-outbound-payment.ts
│       │   │   ├── get-stripe-recipient-account.ts
│       │   │   ├── get-stripe-recipient-payout-method.ts
│       │   │   ├── index.ts
│       │   │   ├── payment-methods.ts
│       │   │   ├── stripe-v2-client.ts
│       │   │   └── stripe-v2-schemas.ts
│       │   ├── swr/
│       │   │   ├── mutate.ts
│       │   │   ├── use-activity-logs.ts
│       │   │   ├── use-api-mutation.ts
│       │   │   ├── use-bounty-submissions-count.ts
│       │   │   ├── use-bounty.ts
│       │   │   ├── use-commission.ts
│       │   │   ├── use-commissions-count.ts
│       │   │   ├── use-commissions-timeseries.ts
│       │   │   ├── use-current-folder-id.ts
│       │   │   ├── use-customer-activity.ts
│       │   │   ├── use-customer.ts
│       │   │   ├── use-customers-count.ts
│       │   │   ├── use-customers.ts
│       │   │   ├── use-default-domains.ts
│       │   │   ├── use-discount-codes.ts
│       │   │   ├── use-discounts.ts
│       │   │   ├── use-domain.ts
│       │   │   ├── use-domains-count.ts
│       │   │   ├── use-domains.ts
│       │   │   ├── use-email-domains.ts
│       │   │   ├── use-folder-access-requests.ts
│       │   │   ├── use-folder-link-count.ts
│       │   │   ├── use-folder-permissions.ts
│       │   │   ├── use-folder-users.ts
│       │   │   ├── use-folder.ts
│       │   │   ├── use-folders-count.ts
│       │   │   ├── use-folders.ts
│       │   │   ├── use-fraud-events-count.ts
│       │   │   ├── use-fraud-events-paginated.ts
│       │   │   ├── use-fraud-events.ts
│       │   │   ├── use-fraud-groups-count.ts
│       │   │   ├── use-fraud-groups.ts
│       │   │   ├── use-group-move-rules.ts
│       │   │   ├── use-group.ts
│       │   │   ├── use-groups-count.ts
│       │   │   ├── use-groups.ts
│       │   │   ├── use-guide.ts
│       │   │   ├── use-integrations.ts
│       │   │   ├── use-link.ts
│       │   │   ├── use-links-count.ts
│       │   │   ├── use-links.ts
│       │   │   ├── use-network-partners-count.ts
│       │   │   ├── use-network-programs-count.ts
│       │   │   ├── use-partner-activity-logs.ts
│       │   │   ├── use-partner-analytics.ts
│       │   │   ├── use-partner-application-risks.ts
│       │   │   ├── use-partner-bounty.ts
│       │   │   ├── use-partner-comments-count.ts
│       │   │   ├── use-partner-comments.ts
│       │   │   ├── use-partner-cross-program-summary.ts
│       │   │   ├── use-partner-customer.ts
│       │   │   ├── use-partner-customers-count.ts
│       │   │   ├── use-partner-customers.ts
│       │   │   ├── use-partner-earnings-count.ts
│       │   │   ├── use-partner-earnings-timeseries.ts
│       │   │   ├── use-partner-group-default-links.ts
│       │   │   ├── use-partner-links.ts
│       │   │   ├── use-partner-messages-count.ts
│       │   │   ├── use-partner-messages.ts
│       │   │   ├── use-partner-network-invites-usage.ts
│       │   │   ├── use-partner-payout-settings.ts
│       │   │   ├── use-partner-payouts-count.ts
│       │   │   ├── use-partner-payouts.ts
│       │   │   ├── use-partner-profile.ts
│       │   │   ├── use-partner-program-bounties.ts
│       │   │   ├── use-partner-referrals-count.ts
│       │   │   ├── use-partner-referrals.ts
│       │   │   ├── use-partner-rewind.ts
│       │   │   ├── use-partner.ts
│       │   │   ├── use-partners-count-by-groupids.ts
│       │   │   ├── use-partners-count.ts
│       │   │   ├── use-partners.ts
│       │   │   ├── use-payment-methods.ts
│       │   │   ├── use-payout.ts
│       │   │   ├── use-payouts-count.ts
│       │   │   ├── use-payouts.ts
│       │   │   ├── use-program-enrollment.ts
│       │   │   ├── use-program-enrollments-count.ts
│       │   │   ├── use-program-enrollments.ts
│       │   │   ├── use-program-messages-count.ts
│       │   │   ├── use-program-messages.ts
│       │   │   ├── use-program-referrals-count.ts
│       │   │   ├── use-program-resources.ts
│       │   │   ├── use-program.ts
│       │   │   ├── use-refresh-session.ts
│       │   │   ├── use-rewardful-campaigns.ts
│       │   │   ├── use-rewards.ts
│       │   │   ├── use-saml.ts
│       │   │   ├── use-scim.ts
│       │   │   ├── use-tags-count.ts
│       │   │   ├── use-tags.ts
│       │   │   ├── use-usage-timeseries.ts
│       │   │   ├── use-user.ts
│       │   │   ├── use-webhook.ts
│       │   │   ├── use-webhooks.ts
│       │   │   ├── use-workspace-preferences.ts
│       │   │   ├── use-workspace-store.ts
│       │   │   ├── use-workspace-users.ts
│       │   │   ├── use-workspace.ts
│       │   │   └── use-workspaces.ts
│       │   ├── tinybird/
│       │   │   ├── client.ts
│       │   │   ├── get-click-event.ts
│       │   │   ├── get-customer-events-tb.ts
│       │   │   ├── get-import-error-logs.ts
│       │   │   ├── get-lead-event.ts
│       │   │   ├── get-lead-events.ts
│       │   │   ├── get-top-links-by-countries.ts
│       │   │   ├── get-webhook-events.ts
│       │   │   ├── index.ts
│       │   │   ├── log-conversion-events.ts
│       │   │   ├── log-import-error.ts
│       │   │   ├── record-click-zod.ts
│       │   │   ├── record-click.ts
│       │   │   ├── record-fake-click.ts
│       │   │   ├── record-lead.ts
│       │   │   ├── record-link.ts
│       │   │   ├── record-sale.ts
│       │   │   └── record-webhook-event.ts
│       │   ├── tolt/
│       │   │   ├── api.ts
│       │   │   ├── cleanup-partners.ts
│       │   │   ├── import-commissions.ts
│       │   │   ├── import-customers.ts
│       │   │   ├── import-links.ts
│       │   │   ├── import-partners.ts
│       │   │   ├── importer.ts
│       │   │   ├── schemas.ts
│       │   │   ├── types.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── types.ts
│       │   ├── upstash/
│       │   │   ├── format-redis-link.ts
│       │   │   ├── index.ts
│       │   │   ├── ratelimit-policy.ts
│       │   │   ├── ratelimit.ts
│       │   │   ├── record-metatags.ts
│       │   │   ├── redis-streams.ts
│       │   │   ├── redis.ts
│       │   │   └── vector.ts
│       │   ├── webhook/
│       │   │   ├── cache.ts
│       │   │   ├── constants.ts
│       │   │   ├── create-webhook.ts
│       │   │   ├── failure.ts
│       │   │   ├── get-webhooks.ts
│       │   │   ├── handle-external-payout-event.ts
│       │   │   ├── publish.ts
│       │   │   ├── qstash.ts
│       │   │   ├── sample-events/
│       │   │   │   ├── bounty-created.json
│       │   │   │   ├── bounty-updated.json
│       │   │   │   ├── commission-created.json
│       │   │   │   ├── lead-created.json
│       │   │   │   ├── link-clicked.json
│       │   │   │   ├── link-created.json
│       │   │   │   ├── link-deleted.json
│       │   │   │   ├── link-updated.json
│       │   │   │   ├── partner-application-submitted.json
│       │   │   │   ├── partner-enrolled.json
│       │   │   │   ├── payload.ts
│       │   │   │   ├── payout-confirmed.json
│       │   │   │   └── sale-created.json
│       │   │   ├── schemas.ts
│       │   │   ├── secret.ts
│       │   │   ├── signature.ts
│       │   │   ├── transform.ts
│       │   │   ├── types.ts
│       │   │   ├── update-webhook.ts
│       │   │   ├── utils.ts
│       │   │   └── validate-webhook.ts
│       │   ├── well-known.ts
│       │   ├── workspace-roles.ts
│       │   └── zod/
│       │       └── schemas/
│       │           ├── activity-log.ts
│       │           ├── analytics-response.ts
│       │           ├── analytics.ts
│       │           ├── auth.ts
│       │           ├── bounties.ts
│       │           ├── campaigns.ts
│       │           ├── clicks.ts
│       │           ├── commissions.ts
│       │           ├── customer-activity.ts
│       │           ├── customers.ts
│       │           ├── dashboard.ts
│       │           ├── deep-links.ts
│       │           ├── deprecated.ts
│       │           ├── discount.ts
│       │           ├── domains.ts
│       │           ├── email-domains.ts
│       │           ├── folders.ts
│       │           ├── fraud.ts
│       │           ├── group-bounties.ts
│       │           ├── group-with-program.ts
│       │           ├── groups.ts
│       │           ├── import-csv.ts
│       │           ├── import-error-log.ts
│       │           ├── integration.ts
│       │           ├── invites.ts
│       │           ├── invoices.ts
│       │           ├── leads.ts
│       │           ├── links.ts
│       │           ├── messages.ts
│       │           ├── misc.ts
│       │           ├── oauth.ts
│       │           ├── opens.ts
│       │           ├── partner-network.ts
│       │           ├── partner-profile.ts
│       │           ├── partners.ts
│       │           ├── payouts.ts
│       │           ├── program-application-form.ts
│       │           ├── program-application.ts
│       │           ├── program-embed.ts
│       │           ├── program-invite-email.ts
│       │           ├── program-lander.ts
│       │           ├── program-network.ts
│       │           ├── program-onboarding.ts
│       │           ├── program-resources.ts
│       │           ├── programs.ts
│       │           ├── qr.ts
│       │           ├── referral-form.ts
│       │           ├── referrals-embed.ts
│       │           ├── referrals.ts
│       │           ├── rewards.ts
│       │           ├── sales.ts
│       │           ├── schemas.ts
│       │           ├── tags.ts
│       │           ├── token.ts
│       │           ├── usage.ts
│       │           ├── users.ts
│       │           ├── utils.ts
│       │           ├── utm.ts
│       │           ├── webhooks.ts
│       │           ├── workflows.ts
│       │           ├── workspace-preferences.ts
│       │           └── workspaces.ts
│       ├── middleware.ts
│       ├── next.config.js
│       ├── package.json
│       ├── playwright/
│       │   ├── README.md
│       │   ├── auth.setup.ts
│       │   ├── env.ts
│       │   ├── partner-login.spec.ts
│       │   ├── partner-onboarding.spec.ts
│       │   └── seed.ts
│       ├── playwright.config.ts
│       ├── postcss.config.js
│       ├── public/
│       │   └── .well-known/
│       │       └── security.txt
│       ├── scripts/
│       │   ├── analyze-bundle.ts
│       │   ├── analyze-domains.ts
│       │   ├── analyze-link-webhooks.ts
│       │   ├── analyze-top-utms.ts
│       │   ├── analyze-utm-usage.ts
│       │   ├── annature/
│       │   │   └── import-domains.ts
│       │   ├── buffer/
│       │   │   ├── delete-old-links.ts
│       │   │   └── migrate-to-case-sensitive.ts
│       │   ├── bulk-archive-links.ts
│       │   ├── bulk-create-domains.ts
│       │   ├── bulk-create-links.ts
│       │   ├── bulk-delete-links.ts
│       │   ├── bulk-update-links.ts
│       │   ├── cache-popular-urls.ts
│       │   ├── cal/
│       │   │   └── backfill-referral-links.ts
│       │   ├── check-customers.ts
│       │   ├── conversion-customers.ts
│       │   ├── convert-case-sensitive.ts
│       │   ├── convert-manual-commissions.ts
│       │   ├── create-integration.ts
│       │   ├── create-key.ts
│       │   ├── deactivate-programs.ts
│       │   ├── delete-link-cache.ts
│       │   ├── dev/
│       │   │   ├── data.json
│       │   │   └── seed.ts
│       │   ├── download-links.ts
│       │   ├── download-top-links.ts
│       │   ├── dub-domain-users.ts
│       │   ├── dub-partner-rewind.ts
│       │   ├── dub-sdk.ts
│       │   ├── dub-wrapped.ts
│       │   ├── find-link.ts
│       │   ├── find-workspaces-without-users.ts
│       │   ├── fix-broken-applications.ts
│       │   ├── fix-broken-link-tags.ts
│       │   ├── fix-broken-partner-users.ts
│       │   ├── fix-broken-root-domains.ts
│       │   ├── fix-broken-workspace-users.ts
│       │   ├── fix-usage-count.ts
│       │   ├── format-clicks.ts
│       │   ├── format-links.ts
│       │   ├── framer/
│       │   │   ├── 1-process-framer-combined.ts
│       │   │   ├── 2-sort-lead-events-by-date.ts
│       │   │   ├── 3-backfill-tb-events.ts
│       │   │   ├── backfill-commissions.ts
│       │   │   ├── check-pending-payout-totals.ts
│       │   │   ├── get-links-to-backfill.ts
│       │   │   ├── get-remaining-links-to-backfill.ts
│       │   │   ├── mark-commissions-paid.ts
│       │   │   ├── mark-commissions-pending.ts
│       │   │   ├── process-lead-events.ts
│       │   │   └── tally-commissions.ts
│       │   ├── generate-openapi.ts
│       │   ├── get-api-users.ts
│       │   ├── get-customers.ts
│       │   ├── get-inactive-users.ts
│       │   ├── get-premium-workspaces.ts
│       │   ├── get-top-domains-for-links.ts
│       │   ├── get-top-links-for-workspace.ts
│       │   ├── get-users-by-links.ts
│       │   ├── get-users-with-multiple-free-workspaces.ts
│       │   ├── get-users.ts
│       │   ├── get-workspaces-by-clicks.ts
│       │   ├── get-workspaces-by-links.ts
│       │   ├── hash-speed.ts
│       │   ├── lua-convert.ts
│       │   ├── migrate-commission-attributes.ts
│       │   ├── migrations/
│       │   │   ├── backfill-application-groupId.ts
│       │   │   ├── backfill-attribution.ts
│       │   │   ├── backfill-banned-partner-links.ts
│       │   │   ├── backfill-click-commissions.ts
│       │   │   ├── backfill-commissions-rewardId.ts
│       │   │   ├── backfill-cross-program-ban-fraud-events.ts
│       │   │   ├── backfill-customer-first-sale.ts
│       │   │   ├── backfill-customer-partner-ids.ts
│       │   │   ├── backfill-customer-sales.ts
│       │   │   ├── backfill-customer-subscription-cancellation.ts
│       │   │   ├── backfill-customers.ts
│       │   │   ├── backfill-dashboards.ts
│       │   │   ├── backfill-deepview.ts
│       │   │   ├── backfill-default-payout-method.ts
│       │   │   ├── backfill-default-program-ids.ts
│       │   │   ├── backfill-discoverableat.ts
│       │   │   ├── backfill-domain-logo.ts
│       │   │   ├── backfill-folders-limit.ts
│       │   │   ├── backfill-folders-usage.ts
│       │   │   ├── backfill-group-links-pgdl-acme.ts
│       │   │   ├── backfill-group-links-pgdl.ts
│       │   │   ├── backfill-group-links-settings.ts
│       │   │   ├── backfill-group-settings.ts
│       │   │   ├── backfill-invoice-paid-at.ts
│       │   │   ├── backfill-invoice-payment-method.ts
│       │   │   ├── backfill-invoice-prefixes.ts
│       │   │   ├── backfill-link-commissions.ts
│       │   │   ├── backfill-link-partner-group-ids.ts
│       │   │   ├── backfill-link-stats.ts
│       │   │   ├── backfill-link-webhooks.ts
│       │   │   ├── backfill-missing-lead-commissions.ts
│       │   │   ├── backfill-missing-sales.ts
│       │   │   ├── backfill-notification-email-columns.ts
│       │   │   ├── backfill-notification-email-deliveredat.ts
│       │   │   ├── backfill-notification-preferences.ts
│       │   │   ├── backfill-partner-groupid-logs.ts
│       │   │   ├── backfill-partner-groups-verify.ts
│       │   │   ├── backfill-partner-groups.ts
│       │   │   ├── backfill-partner-platforms.ts
│       │   │   ├── backfill-payout-initiated-at.ts
│       │   │   ├── backfill-payout-method-hash.ts
│       │   │   ├── backfill-payout-method.ts
│       │   │   ├── backfill-payout-mode.ts
│       │   │   ├── backfill-performance-bounty-submissions.ts
│       │   │   ├── backfill-plain-customers.ts
│       │   │   ├── backfill-program-categories.ts
│       │   │   ├── backfill-program-marketplace-descriptions.ts
│       │   │   ├── backfill-program-marketplace.ts
│       │   │   ├── backfill-referral-links.ts
│       │   │   ├── backfill-reward-activity-log.ts
│       │   │   ├── backfill-reward-modifier-ids.ts
│       │   │   ├── backfill-saml-sso.ts
│       │   │   ├── backfill-short-links.ts
│       │   │   ├── backfill-stripe-connect.ts
│       │   │   ├── backfill-submission-completedat.ts
│       │   │   ├── backfill-total-commissions.ts
│       │   │   ├── migrate-application-formdata.ts
│       │   │   ├── migrate-application-submissions.ts
│       │   │   ├── migrate-bounties-submission-requirements.ts
│       │   │   ├── migrate-campaign-message-to-markdown.ts
│       │   │   ├── migrate-discounts.ts
│       │   │   ├── migrate-domains.ts
│       │   │   ├── migrate-images.ts
│       │   │   ├── migrate-integrations.ts
│       │   │   ├── migrate-lander-data.ts
│       │   │   ├── migrate-links-to-workspaces.ts
│       │   │   ├── migrate-partner-links.ts
│       │   │   ├── migrate-partners-with-tenantids.ts
│       │   │   ├── migrate-reward-amounts.ts
│       │   │   ├── migrate-rewards-remainder.ts
│       │   │   ├── migrate-rewards.ts
│       │   │   ├── migrate-sales.ts
│       │   │   ├── migrate-workflow-triggers.ts
│       │   │   ├── remove-duplicate-notification-emails.ts
│       │   │   ├── restore-group-ids.ts
│       │   │   ├── sanitize-partner-platform.ts
│       │   │   ├── update-discoverable-partners.ts
│       │   │   └── update-payout-mode-to-internal.ts
│       │   ├── misc/
│       │   │   ├── cleanup-fraud-events.ts
│       │   │   ├── cleanup-generic-email-fraud-events.ts
│       │   │   ├── fraud-campaign-ids.ts
│       │   │   ├── remove-fraud-events.ts
│       │   │   ├── restore-link-analytics.ts
│       │   │   ├── restore-links.ts
│       │   │   ├── restore-program-enrollments.ts
│       │   │   └── restore-program-folders.ts
│       │   ├── move-links-to-folder.ts
│       │   ├── partners/
│       │   │   ├── aggregate-stats-seeding.ts
│       │   │   ├── check-pending-paypal-payouts.ts
│       │   │   ├── combine-payouts.ts
│       │   │   ├── delete-partner-profile.ts
│       │   │   ├── delete-partners-for-program.ts
│       │   │   ├── delete-program-application.ts
│       │   │   ├── delete-program-enrollment.ts
│       │   │   ├── delete-program.ts
│       │   │   ├── export-partners.ts
│       │   │   ├── fix-partner-groups.ts
│       │   │   ├── fix-partner-payouts.ts
│       │   │   ├── get-largest-programs.ts
│       │   │   ├── invalidate-partner-links.ts
│       │   │   ├── merge-partner-profile.ts
│       │   │   ├── update-links.ts
│       │   │   ├── update-partner-country.ts
│       │   │   └── update-payout-dates.ts
│       │   ├── perplexity/
│       │   │   ├── backfill-leads.ts
│       │   │   ├── backfill-tenantids.ts
│       │   │   ├── ban-partners.ts
│       │   │   ├── deactivate-partners.ts
│       │   │   ├── move-partners.ts
│       │   │   ├── partners-updated-countries.ts
│       │   │   ├── review-bounties.ts
│       │   │   ├── update-commissions.ts
│       │   │   └── update-notifications.ts
│       │   ├── persist-customer-avatars.ts
│       │   ├── processed-payouts.ts
│       │   ├── programs/
│       │   │   ├── 1-import-partners.ts
│       │   │   ├── 2-import-partner-links.ts
│       │   │   ├── 3-import-customer-leads.ts
│       │   │   ├── 4-export-stripe-invoices.ts
│       │   │   ├── 5-import-customer-sales.ts
│       │   │   ├── add-to-marketplace.ts
│       │   │   ├── backfill-custom-commissions.ts
│       │   │   ├── backfill-discount-codes.ts
│       │   │   ├── backfill-reuse-commission.ts
│       │   │   ├── delete-program-enrollments.ts
│       │   │   ├── update-commissions-canceled.ts
│       │   │   └── update-commissions-paid.ts
│       │   ├── referral-form-sample.json
│       │   ├── remove-workspace-scopes.ts
│       │   ├── restore-backup.ts
│       │   ├── revert-partner-payout-demo.ts
│       │   ├── reward-conditions.ts
│       │   ├── run.ts
│       │   ├── seed-invite-codes.ts
│       │   ├── seed-support-embeddings.ts
│       │   ├── send-batch-emails.ts
│       │   ├── sent-mail-reset.ts
│       │   ├── ship30/
│       │   │   └── backfill-leads.ts
│       │   ├── sitemap-importer.ts
│       │   ├── stripe/
│       │   │   ├── backfill-stripe-webhook-events.ts
│       │   │   ├── backfill-trace-id.ts
│       │   │   ├── connect-client.ts
│       │   │   ├── delete-connected-account.ts
│       │   │   ├── fix-processed-payouts.ts
│       │   │   ├── get-connected-customer.ts
│       │   │   ├── manual-payouts.ts
│       │   │   ├── retrieve-balance.ts
│       │   │   ├── search-customers.ts
│       │   │   ├── update-payouts-schedule.ts
│       │   │   └── update-stripe-customers.ts
│       │   ├── sync-conversions.ts
│       │   ├── sync-domain-clicks.ts
│       │   ├── sync-expired-links.ts
│       │   ├── sync-limits.ts
│       │   ├── sync-link-clicks.ts
│       │   ├── sync-link-tags.ts
│       │   ├── sync-links-metadata.ts
│       │   ├── sync-tag-analytics.ts
│       │   ├── tella/
│       │   │   ├── remind-applications.ts
│       │   │   ├── update-commission-flat.ts
│       │   │   ├── update-commission-percentage.ts
│       │   │   ├── update-commissions.ts
│       │   │   └── update-reward-tier.ts
│       │   ├── test-paypal-payouts.ts
│       │   ├── testimonial/
│       │   │   ├── final-sync-commissions.ts
│       │   │   ├── sync-commissions.ts
│       │   │   └── update-commissions.ts
│       │   ├── tinybird/
│       │   │   ├── delete-lead-event.ts
│       │   │   ├── delete-links.ts
│       │   │   ├── delete-sale-event.ts
│       │   │   ├── update-click-event.ts
│       │   │   ├── update-lead-event.ts
│       │   │   └── update-sale-event.ts
│       │   ├── trigger-update-partner-stats.ts
│       │   ├── unban-links.ts
│       │   ├── update-integrations.ts
│       │   ├── update-link-owner.ts
│       │   ├── update-not-found.ts
│       │   ├── update-payment-failed.ts
│       │   ├── update-payouts-limits.ts
│       │   ├── update-referral-form-data.ts
│       │   ├── update-spam-links.ts
│       │   ├── update-subscribers.ts
│       │   ├── update-user-notifications.ts
│       │   ├── update-webhook-cache.ts
│       │   ├── update-workspace-dates.ts
│       │   ├── update-workspace-tags.ts
│       │   ├── upload-users.ts
│       │   └── wispr-flow/
│       │       └── update-links.ts
│       ├── styles/
│       │   ├── fonts.ts
│       │   └── globals.css
│       ├── tailwind.config.ts
│       ├── tests/
│       │   ├── analytics/
│       │   │   ├── advanced-filter-helpers.test.ts
│       │   │   ├── get-analytics-advanced.test.ts
│       │   │   ├── get-analytics.test.ts
│       │   │   ├── get-events.test.ts
│       │   │   ├── metadata-query-parser.test.ts
│       │   │   ├── partner-analytics.test.ts
│       │   │   └── public-analytics-dashboard.test.ts
│       │   ├── bounties/
│       │   │   └── index.test.ts
│       │   ├── campaigns/
│       │   │   └── index.test.ts
│       │   ├── commissions/
│       │   │   ├── index.test.ts
│       │   │   └── pagination.test.ts
│       │   ├── customers/
│       │   │   ├── index.test.ts
│       │   │   └── pagination.test.ts
│       │   ├── discounts/
│       │   │   └── index.test.ts
│       │   ├── domains/
│       │   │   └── index.test.ts
│       │   ├── embed-tokens/
│       │   │   └── referrals.test.ts
│       │   ├── folders/
│       │   │   └── index.test.ts
│       │   ├── fraud/
│       │   │   ├── fraud-groups.test.ts
│       │   │   └── index.test.ts
│       │   ├── links/
│       │   │   ├── bulk-create-link.test.ts
│       │   │   ├── bulk-delete-link.test.ts
│       │   │   ├── bulk-update-link.test.ts
│       │   │   ├── count-links.test.ts
│       │   │   ├── create-link-error.test.ts
│       │   │   ├── create-link.test.ts
│       │   │   ├── delete-link.test.ts
│       │   │   ├── folder-link-access.test.ts
│       │   │   ├── list-links.test.ts
│       │   │   ├── retrieve-link.test.ts
│       │   │   ├── retrieve-metatags.test.ts
│       │   │   ├── update-link.test.ts
│       │   │   └── upsert-link.test.ts
│       │   ├── misc/
│       │   │   ├── allowed-hostnames.test.ts
│       │   │   ├── base64.test.ts
│       │   │   ├── calculate-payout-fee-with-waiver.test.ts
│       │   │   ├── case-sensitive-keys.test.ts
│       │   │   ├── check-eligibility-requirements.test.ts
│       │   │   ├── create-id.test.ts
│       │   │   ├── eligibility-condition-schema.test.ts
│       │   │   ├── email-domain-validation.test.ts
│       │   │   ├── filter-active-group-bounties.test.ts
│       │   │   ├── interpolate-email-template.test.ts
│       │   │   └── ip-cidr.test.ts
│       │   ├── partner-groups/
│       │   │   └── index.test.ts
│       │   ├── partners/
│       │   │   ├── analytics.test.ts
│       │   │   ├── ban-partner.test.ts
│       │   │   ├── create-partner-link.test.ts
│       │   │   ├── create-partner.test.ts
│       │   │   ├── deactivate-partner.test.ts
│       │   │   ├── list-partners.test.ts
│       │   │   ├── resource.ts
│       │   │   └── upsert-partner-link.test.ts
│       │   ├── payouts/
│       │   │   └── index.test.ts
│       │   ├── redirects/
│       │   │   └── index.test.ts
│       │   ├── rewards/
│       │   │   ├── click-reward.test.ts
│       │   │   ├── lead-reward.test.ts
│       │   │   ├── reward-conditions.test.ts
│       │   │   └── sale-reward.test.ts
│       │   ├── setupTests.ts
│       │   ├── tags/
│       │   │   ├── create-tag-error.test.ts
│       │   │   ├── create-tag.test.ts
│       │   │   └── list-tags.test.ts
│       │   ├── tracks/
│       │   │   ├── track-click.test.ts
│       │   │   ├── track-lead-client.test.ts
│       │   │   ├── track-lead.test.ts
│       │   │   ├── track-open.test.ts
│       │   │   ├── track-sale-client.test.ts
│       │   │   └── track-sale.test.ts
│       │   ├── utils/
│       │   │   ├── env.ts
│       │   │   ├── fetch-partner.ts
│       │   │   ├── helpers.ts
│       │   │   ├── http.ts
│       │   │   ├── integration-member.ts
│       │   │   ├── integration-old.ts
│       │   │   ├── integration.ts
│       │   │   ├── resource.ts
│       │   │   ├── schema.ts
│       │   │   └── verify-commission.ts
│       │   ├── webhooks/
│       │   │   └── index.test.ts
│       │   ├── workflows/
│       │   │   ├── award-bounty-workflow.test.ts
│       │   │   ├── e2e-endpoints-guard.test.ts
│       │   │   ├── move-group-workflow.test.ts
│       │   │   ├── send-campaign-workflow.test.ts
│       │   │   └── utils/
│       │   │       ├── delete-bounty-and-submissions.ts
│       │   │       ├── track-e2e-lead.ts
│       │   │       ├── verify-bounty-submission.ts
│       │   │       ├── verify-campaign-sent.ts
│       │   │       └── verify-partner-group-move.ts
│       │   └── workspaces/
│       │       ├── retrieve-workspace.error.test.ts
│       │       └── retrieve-workspace.test.ts
│       ├── tsconfig.json
│       ├── ui/
│       │   ├── account/
│       │   │   ├── delete-account.tsx
│       │   │   ├── update-default-workspace.tsx
│       │   │   ├── update-subscription.tsx
│       │   │   ├── upload-avatar.tsx
│       │   │   └── user-id.tsx
│       │   ├── activity-logs/
│       │   │   ├── action-renderers/
│       │   │   │   ├── partner-group-changed-renderer.tsx
│       │   │   │   ├── referral-created-renderer.tsx
│       │   │   │   ├── referral-status-changed-renderer.tsx
│       │   │   │   └── reward-activity-renderer.tsx
│       │   │   ├── activity-entry-chips.tsx
│       │   │   ├── activity-feed.tsx
│       │   │   ├── activity-log-context.tsx
│       │   │   ├── activity-log-description.tsx
│       │   │   ├── activity-log-registry.tsx
│       │   │   ├── partner-group-activity-item.tsx
│       │   │   ├── partner-group-activity-section.tsx
│       │   │   ├── partner-group-history-sheet.tsx
│       │   │   ├── partner-referral-activity-section.tsx
│       │   │   ├── referral-activity-item.tsx
│       │   │   ├── referral-activity-section.tsx
│       │   │   ├── reward-activity-item.tsx
│       │   │   ├── reward-activity-section.tsx
│       │   │   └── reward-history-sheet.tsx
│       │   ├── analytics/
│       │   │   ├── analytics-area-chart.tsx
│       │   │   ├── analytics-card.tsx
│       │   │   ├── analytics-export-button.tsx
│       │   │   ├── analytics-funnel-chart.tsx
│       │   │   ├── analytics-loading-spinner.tsx
│       │   │   ├── analytics-options.tsx
│       │   │   ├── analytics-provider.tsx
│       │   │   ├── analytics-tabs.tsx
│       │   │   ├── bar-list.tsx
│       │   │   ├── chart-section.tsx
│       │   │   ├── chart-view-switcher.tsx
│       │   │   ├── continent-icon.tsx
│       │   │   ├── device-icon.tsx
│       │   │   ├── device-section.tsx
│       │   │   ├── events/
│       │   │   │   ├── events-export-button.tsx
│       │   │   │   ├── events-provider.tsx
│       │   │   │   ├── events-table.tsx
│       │   │   │   ├── events-tabs.tsx
│       │   │   │   ├── example-data.ts
│       │   │   │   ├── index.tsx
│       │   │   │   ├── metadata-viewer.tsx
│       │   │   │   └── row-menu-button.tsx
│       │   │   ├── index.tsx
│       │   │   ├── link-preview.tsx
│       │   │   ├── location-section.tsx
│       │   │   ├── partner-section.tsx
│       │   │   ├── referrer-icon.tsx
│       │   │   ├── referrers-utms.tsx
│       │   │   ├── share-button.tsx
│       │   │   ├── toggle.tsx
│       │   │   ├── top-links.tsx
│       │   │   ├── trigger-display.tsx
│       │   │   ├── use-analytics-connected-status.ts
│       │   │   ├── use-analytics-filters.tsx
│       │   │   ├── use-analytics-query.tsx
│       │   │   └── utils.ts
│       │   ├── auth/
│       │   │   ├── auth-alternative-banner.tsx
│       │   │   ├── auth-methods-separator.tsx
│       │   │   ├── forgot-password-form.tsx
│       │   │   ├── login/
│       │   │   │   ├── email-sign-in.tsx
│       │   │   │   ├── framer-button.tsx
│       │   │   │   ├── github-button.tsx
│       │   │   │   ├── google-button.tsx
│       │   │   │   ├── login-form.tsx
│       │   │   │   └── sso-sign-in.tsx
│       │   │   ├── register/
│       │   │   │   ├── context.tsx
│       │   │   │   ├── resend-otp.tsx
│       │   │   │   ├── signup-email.tsx
│       │   │   │   ├── signup-form.tsx
│       │   │   │   ├── signup-oauth.tsx
│       │   │   │   └── verify-email-form.tsx
│       │   │   └── reset-password-form.tsx
│       │   ├── colors.ts
│       │   ├── customers/
│       │   │   ├── customer-activity-list.tsx
│       │   │   ├── customer-avatar.tsx
│       │   │   ├── customer-details-column.tsx
│       │   │   ├── customer-partner-earnings-table.tsx
│       │   │   ├── customer-row-item.tsx
│       │   │   ├── customer-sales-table.tsx
│       │   │   ├── customer-selector.tsx
│       │   │   ├── customer-stats.tsx
│       │   │   ├── customer-tabs.tsx
│       │   │   ├── customers-table/
│       │   │   │   ├── customers-table.tsx
│       │   │   │   ├── example-data.ts
│       │   │   │   └── use-customer-filters.tsx
│       │   │   └── export-customers-button.tsx
│       │   ├── domains/
│       │   │   ├── add-edit-domain-form.tsx
│       │   │   ├── domain-card-placeholder.tsx
│       │   │   ├── domain-card-title-column.tsx
│       │   │   ├── domain-card.tsx
│       │   │   ├── domain-configuration.tsx
│       │   │   ├── domain-selector.tsx
│       │   │   ├── free-dot-link-banner.tsx
│       │   │   └── register-domain-form.tsx
│       │   ├── dub-partners-logo.tsx
│       │   ├── folders/
│       │   │   ├── add-folder-form.tsx
│       │   │   ├── edit-folder-form.tsx
│       │   │   ├── edit-folder-sheet.tsx
│       │   │   ├── folder-actions.tsx
│       │   │   ├── folder-card-placeholder.tsx
│       │   │   ├── folder-card.tsx
│       │   │   ├── folder-dropdown.tsx
│       │   │   ├── folder-icon.tsx
│       │   │   ├── folder-info-panel.tsx
│       │   │   ├── move-link-form.tsx
│       │   │   ├── rename-folder-form.tsx
│       │   │   ├── request-edit-button.tsx
│       │   │   ├── simple-folder-card.tsx
│       │   │   └── utils.ts
│       │   ├── guides/
│       │   │   ├── guide-action-button.tsx
│       │   │   ├── guide-list.tsx
│       │   │   ├── guide-selector.tsx
│       │   │   ├── guide.tsx
│       │   │   ├── icons/
│       │   │   │   ├── appwrite.tsx
│       │   │   │   ├── auth-js.tsx
│       │   │   │   ├── auth0.tsx
│       │   │   │   ├── better-auth.tsx
│       │   │   │   ├── clerk.tsx
│       │   │   │   ├── code-editor.tsx
│       │   │   │   ├── custom.tsx
│       │   │   │   ├── framer.tsx
│       │   │   │   ├── gtm.tsx
│       │   │   │   ├── next-auth.tsx
│       │   │   │   ├── react.tsx
│       │   │   │   ├── segment.tsx
│       │   │   │   ├── shopify.tsx
│       │   │   │   ├── supabase.tsx
│       │   │   │   ├── webflow.tsx
│       │   │   │   └── wordpress.tsx
│       │   │   ├── install-stripe-integration-button.tsx
│       │   │   ├── integrations.ts
│       │   │   └── markdown.tsx
│       │   ├── integrations/
│       │   │   ├── integration-card.tsx
│       │   │   └── integration-logo.tsx
│       │   ├── layout/
│       │   │   ├── auth-layout.tsx
│       │   │   ├── changelog-popup.tsx
│       │   │   ├── layout-loader.tsx
│       │   │   ├── main-nav.tsx
│       │   │   ├── page-content/
│       │   │   │   ├── index.tsx
│       │   │   │   ├── nav-button.tsx
│       │   │   │   ├── page-content-header.tsx
│       │   │   │   ├── page-content-old.tsx
│       │   │   │   ├── page-content-with-side-panel.tsx
│       │   │   │   └── toggle-side-panel-button.tsx
│       │   │   ├── page-nav-tabs.tsx
│       │   │   ├── page-width-wrapper.tsx
│       │   │   ├── settings-layout.tsx
│       │   │   ├── sidebar/
│       │   │   │   ├── affiliate-program-popup.tsx
│       │   │   │   ├── app-sidebar-nav.tsx
│       │   │   │   ├── dub-partners-popup.tsx
│       │   │   │   ├── help-button.tsx
│       │   │   │   ├── icons/
│       │   │   │   │   ├── compass.tsx
│       │   │   │   │   ├── connected-dots4.tsx
│       │   │   │   │   ├── cursor-rays.tsx
│       │   │   │   │   ├── gear.tsx
│       │   │   │   │   ├── hyperlink.tsx
│       │   │   │   │   ├── lines-y.tsx
│       │   │   │   │   └── user.tsx
│       │   │   │   ├── news-rsc.tsx
│       │   │   │   ├── news.tsx
│       │   │   │   ├── partner-program-dropdown.tsx
│       │   │   │   ├── partners-sidebar-nav.tsx
│       │   │   │   ├── payout-stats.tsx
│       │   │   │   ├── program-help-support.tsx
│       │   │   │   ├── refer-button.tsx
│       │   │   │   ├── sidebar-nav.tsx
│       │   │   │   ├── sidebar-usage.tsx
│       │   │   │   ├── use-program-applications-count.tsx
│       │   │   │   ├── user-dropdown.tsx
│       │   │   │   ├── workspace-dropdown.tsx
│       │   │   │   └── year-in-review-card.tsx
│       │   │   ├── toolbar/
│       │   │   │   ├── onboarding/
│       │   │   │   │   └── onboarding-button.tsx
│       │   │   │   └── toolbar.tsx
│       │   │   ├── upgrade-banner.tsx
│       │   │   └── user-survey/
│       │   │       ├── index.tsx
│       │   │       └── survey-form.tsx
│       │   ├── links/
│       │   │   ├── archived-links-hint.tsx
│       │   │   ├── comments-badge.tsx
│       │   │   ├── destination-url-input.tsx
│       │   │   ├── disabled-link-tooltip.tsx
│       │   │   ├── link-analytics-badge.tsx
│       │   │   ├── link-builder/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── controls/
│       │   │   │   │   ├── link-builder-destination-url-input.tsx
│       │   │   │   │   ├── link-builder-folder-selector.tsx
│       │   │   │   │   ├── link-builder-short-link-input.tsx
│       │   │   │   │   └── link-comments-input.tsx
│       │   │   │   ├── conversion-tracking-toggle.tsx
│       │   │   │   ├── draft-controls.tsx
│       │   │   │   ├── link-action-bar.tsx
│       │   │   │   ├── link-builder-header.tsx
│       │   │   │   ├── link-builder-provider.tsx
│       │   │   │   ├── link-creator-info.tsx
│       │   │   │   ├── link-feature-buttons.tsx
│       │   │   │   ├── link-partner-details.tsx
│       │   │   │   ├── link-preview.tsx
│       │   │   │   ├── more-dropdown.tsx
│       │   │   │   ├── multi-tags-icon.tsx
│       │   │   │   ├── options-list.tsx
│       │   │   │   ├── qr-code-preview.tsx
│       │   │   │   ├── tag-select.tsx
│       │   │   │   ├── use-link-builder-keyboard-shortcut.ts
│       │   │   │   ├── use-link-builder-submit.tsx
│       │   │   │   ├── use-metatags.ts
│       │   │   │   └── utm-templates-button.tsx
│       │   │   ├── link-card-placeholder.tsx
│       │   │   ├── link-card.tsx
│       │   │   ├── link-controls.tsx
│       │   │   ├── link-details-column.tsx
│       │   │   ├── link-display.tsx
│       │   │   ├── link-icon.tsx
│       │   │   ├── link-not-found.tsx
│       │   │   ├── link-selection-provider.tsx
│       │   │   ├── link-sort.tsx
│       │   │   ├── link-tests.tsx
│       │   │   ├── link-title-column.tsx
│       │   │   ├── links-container.tsx
│       │   │   ├── links-display-provider.tsx
│       │   │   ├── links-toolbar.tsx
│       │   │   ├── short-link-input.tsx
│       │   │   ├── simple-link-card.tsx
│       │   │   ├── tag-badge.tsx
│       │   │   ├── tests-badge.tsx
│       │   │   ├── use-available-domains.ts
│       │   │   ├── use-folder-filter-options.ts
│       │   │   └── use-link-filters.tsx
│       │   ├── messages/
│       │   │   ├── message-markdown.tsx
│       │   │   ├── messages-context.tsx
│       │   │   ├── messages-list.tsx
│       │   │   ├── messages-panel.tsx
│       │   │   └── toggle-side-panel-button.tsx
│       │   ├── modals/
│       │   │   ├── add-customer-modal.tsx
│       │   │   ├── add-discount-code-modal.tsx
│       │   │   ├── add-edit-domain-modal.tsx
│       │   │   ├── add-edit-email-domain-modal.tsx
│       │   │   ├── add-edit-tag-modal.tsx
│       │   │   ├── add-edit-token-modal.tsx
│       │   │   ├── add-edit-utm-template.modal.tsx
│       │   │   ├── add-folder-modal.tsx
│       │   │   ├── add-partner-link-modal.tsx
│       │   │   ├── add-payment-method-modal.tsx
│       │   │   ├── add-workspace-modal.tsx
│       │   │   ├── application-settings-modal.tsx
│       │   │   ├── archive-domain-modal.tsx
│       │   │   ├── archive-link-modal.tsx
│       │   │   ├── archive-partner-modal.tsx
│       │   │   ├── ban-partner-modal.tsx
│       │   │   ├── bulk-approve-partners-modal.tsx
│       │   │   ├── bulk-archive-partners-modal.tsx
│       │   │   ├── bulk-ban-partners-modal.tsx
│       │   │   ├── bulk-deactivate-partners-modal.tsx
│       │   │   ├── bulk-reject-partners-modal.tsx
│       │   │   ├── bulk-resolve-fraud-groups-modal.tsx
│       │   │   ├── change-group-modal.tsx
│       │   │   ├── confirm-approve-bounty-submission-modal.tsx
│       │   │   ├── confirm-modal.tsx
│       │   │   ├── confirm-referral-status-change-modal.tsx
│       │   │   ├── confirm-set-default-group-modal.tsx
│       │   │   ├── deactivate-partner-modal.tsx
│       │   │   ├── delete-account-modal.tsx
│       │   │   ├── delete-discount-code-modal.tsx
│       │   │   ├── delete-domain-modal.tsx
│       │   │   ├── delete-email-domain-modal.tsx
│       │   │   ├── delete-folder-modal.tsx
│       │   │   ├── delete-group-modal.tsx
│       │   │   ├── delete-link-modal.tsx
│       │   │   ├── delete-partner-link-modal.tsx
│       │   │   ├── delete-token-modal.tsx
│       │   │   ├── delete-webhook-modal.tsx
│       │   │   ├── delete-workspace-modal.tsx
│       │   │   ├── disable-fraud-rules-modal.tsx
│       │   │   ├── domain-auto-renewal-modal.tsx
│       │   │   ├── domain-verification-modal.tsx
│       │   │   ├── dot-link-offer-modal.tsx
│       │   │   ├── edit-customer-modal.tsx
│       │   │   ├── edit-referral-modal.tsx
│       │   │   ├── export-applications-modal.tsx
│       │   │   ├── export-commissions-modal.tsx
│       │   │   ├── export-customers-modal.tsx
│       │   │   ├── export-links-modal.tsx
│       │   │   ├── export-partners-modal.tsx
│       │   │   ├── google-oauth-modal.tsx
│       │   │   ├── import-bitly-modal.tsx
│       │   │   ├── import-csv-modal/
│       │   │   │   ├── field-mapping.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   └── select-file.tsx
│       │   │   ├── import-firstpromoter-modal.tsx
│       │   │   ├── import-partnerstack-modal.tsx
│       │   │   ├── import-rebrandly-modal.tsx
│       │   │   ├── import-rewardful-modal.tsx
│       │   │   ├── import-short-modal.tsx
│       │   │   ├── import-tolt-modal.tsx
│       │   │   ├── invite-code-modal.tsx
│       │   │   ├── invite-partner-user-modal.tsx
│       │   │   ├── invite-referral-modal.tsx
│       │   │   ├── invite-workspace-user-modal.tsx
│       │   │   ├── link-builder/
│       │   │   │   ├── ab-testing/
│       │   │   │   │   ├── ab-testing-modal.tsx
│       │   │   │   │   ├── end-ab-testing-modal.tsx
│       │   │   │   │   └── traffic-split-slider.tsx
│       │   │   │   ├── ab-testing-modal.tsx
│       │   │   │   ├── advanced-modal.tsx
│       │   │   │   ├── expiration-modal.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   ├── og-modal.tsx
│       │   │   │   ├── partners-modal.tsx
│       │   │   │   ├── password-modal.tsx
│       │   │   │   ├── targeting-modal.tsx
│       │   │   │   ├── unsplash-search.tsx
│       │   │   │   ├── use-link-drafts.ts
│       │   │   │   ├── utm-modal.tsx
│       │   │   │   ├── utm-templates-combo.tsx
│       │   │   │   └── webhooks-modal.tsx
│       │   │   ├── link-conversion-tracking-modal.tsx
│       │   │   ├── link-qr-modal.tsx
│       │   │   ├── manage-usage-modal.tsx
│       │   │   ├── modal-provider.tsx
│       │   │   ├── move-link-to-folder-modal.tsx
│       │   │   ├── oauth-app-created-modal.tsx
│       │   │   ├── partner-link-modal.tsx
│       │   │   ├── partner-link-qr-modal.tsx
│       │   │   ├── plan-change-confirmation-modal.tsx
│       │   │   ├── primary-domain-modal.tsx
│       │   │   ├── program-welcome-modal.tsx
│       │   │   ├── prompt-modal.tsx
│       │   │   ├── reactivate-partner-modal.tsx
│       │   │   ├── register-domain-modal.tsx
│       │   │   ├── register-domain-success-modal.tsx
│       │   │   ├── reject-partner-application-modal.tsx
│       │   │   ├── remove-oauth-app-modal.tsx
│       │   │   ├── remove-partner-user-modal.tsx
│       │   │   ├── remove-saml-modal.tsx
│       │   │   ├── remove-scim-modal.tsx
│       │   │   ├── remove-workspace-user-modal.tsx
│       │   │   ├── rename-folder-modal.tsx
│       │   │   ├── saml-modal.tsx
│       │   │   ├── scim-modal.tsx
│       │   │   ├── send-test-webhook-modal.tsx
│       │   │   ├── set-default-folder-modal.tsx
│       │   │   ├── share-dashboard-modal.tsx
│       │   │   ├── social-verification-by-code-modal.tsx
│       │   │   ├── submit-oauth-app-modal.tsx
│       │   │   ├── tag-link-modal.tsx
│       │   │   ├── token-created-modal.tsx
│       │   │   ├── transfer-domain-modal.tsx
│       │   │   ├── transfer-link-modal.tsx
│       │   │   ├── unban-partner-modal.tsx
│       │   │   ├── uninstall-integration-modal.tsx
│       │   │   ├── update-partner-user-modal.tsx
│       │   │   ├── update-workspace-user-role.tsx
│       │   │   └── upgraded-modal.tsx
│       │   ├── oauth-apps/
│       │   │   ├── add-edit-app-form.tsx
│       │   │   ├── add-edit-integration-form.tsx
│       │   │   ├── oauth-app-card.tsx
│       │   │   ├── oauth-app-credentials.tsx
│       │   │   └── oauth-app-placeholder.tsx
│       │   ├── partners/
│       │   │   ├── activity-event.tsx
│       │   │   ├── bounties/
│       │   │   │   ├── bounty-description.tsx
│       │   │   │   ├── bounty-incremental-bonus-tooltip.tsx
│       │   │   │   ├── bounty-performance.tsx
│       │   │   │   ├── bounty-platform-icons.ts
│       │   │   │   ├── bounty-progress-bar-row.tsx
│       │   │   │   ├── bounty-reward-criteria.tsx
│       │   │   │   ├── bounty-reward-description.tsx
│       │   │   │   ├── bounty-social-content-preview.tsx
│       │   │   │   ├── bounty-social-content.tsx
│       │   │   │   ├── bounty-social-metrics-rewards-table.tsx
│       │   │   │   ├── bounty-status-badge.tsx
│       │   │   │   ├── bounty-submission-details-sheet.tsx
│       │   │   │   ├── bounty-submission-requirements.tsx
│       │   │   │   ├── bounty-thumbnail-image.tsx
│       │   │   │   ├── claim-bounty-context.tsx
│       │   │   │   ├── claim-bounty-sheet.tsx
│       │   │   │   ├── reject-bounty-submission-modal.tsx
│       │   │   │   ├── use-claim-bounty-form.ts
│       │   │   │   └── use-social-content.ts
│       │   │   ├── comission-type-icon.tsx
│       │   │   ├── commission-row-menu.tsx
│       │   │   ├── commission-status-badges.tsx
│       │   │   ├── commission-type-badge.tsx
│       │   │   ├── confirm-payouts-sheet.tsx
│       │   │   ├── constants.ts
│       │   │   ├── conversion-score-icon.tsx
│       │   │   ├── country-combobox.tsx
│       │   │   ├── discounts/
│       │   │   │   ├── add-edit-discount-sheet.tsx
│       │   │   │   └── discount-code-badge.tsx
│       │   │   ├── eligibility-requirements.tsx
│       │   │   ├── external-payouts-indicator.tsx
│       │   │   ├── format-discount-description.ts
│       │   │   ├── format-reward-description.ts
│       │   │   ├── fraud-risks/
│       │   │   │   ├── commissions-on-hold-table.tsx
│       │   │   │   ├── fraud-disclaimer-banner.tsx
│       │   │   │   ├── fraud-events-tables/
│       │   │   │   │   ├── fraud-cross-program-ban-table.tsx
│       │   │   │   │   ├── fraud-matching-customer-email-table.tsx
│       │   │   │   │   ├── fraud-paid-traffic-detected-table.tsx
│       │   │   │   │   ├── fraud-partner-info-table.tsx
│       │   │   │   │   ├── fraud-referral-source-banned-table.tsx
│       │   │   │   │   └── index.tsx
│       │   │   │   ├── fraud-review-sheet.tsx
│       │   │   │   ├── partner-application-fraud-severity-indicator.tsx
│       │   │   │   ├── partner-application-risk-summary-modal.tsx
│       │   │   │   ├── partner-application-risk-summary.tsx
│       │   │   │   ├── partner-cross-program-summary.tsx
│       │   │   │   ├── partner-fraud-banner.tsx
│       │   │   │   ├── partner-fraud-indicator.tsx
│       │   │   │   ├── resolve-fraud-group-modal.tsx
│       │   │   │   └── resolved-fraud-group-table.tsx
│       │   │   ├── groups/
│       │   │   │   ├── design/
│       │   │   │   │   ├── application-form/
│       │   │   │   │   │   ├── application-hero-preview.tsx
│       │   │   │   │   │   ├── fields/
│       │   │   │   │   │   │   ├── form-control.tsx
│       │   │   │   │   │   │   ├── image-upload-field.tsx
│       │   │   │   │   │   │   ├── index.tsx
│       │   │   │   │   │   │   ├── long-text-field.tsx
│       │   │   │   │   │   │   ├── max-character-count.tsx
│       │   │   │   │   │   │   ├── multiple-choice-field.tsx
│       │   │   │   │   │   │   ├── select-field.tsx
│       │   │   │   │   │   │   ├── short-text-field.tsx
│       │   │   │   │   │   │   └── website-and-socials-field.tsx
│       │   │   │   │   │   ├── form-data-for-application-form-data.ts
│       │   │   │   │   │   ├── modals/
│       │   │   │   │   │   │   ├── add-field-modal.tsx
│       │   │   │   │   │   │   ├── edit-application-hero-modal.tsx
│       │   │   │   │   │   │   ├── generate-lander-modal.tsx
│       │   │   │   │   │   │   ├── image-upload-field-modal.tsx
│       │   │   │   │   │   │   ├── long-text-field-modal.tsx
│       │   │   │   │   │   │   ├── multiple-choice-field-modal.tsx
│       │   │   │   │   │   │   ├── select-field-modal.tsx
│       │   │   │   │   │   │   ├── short-text-field-modal.tsx
│       │   │   │   │   │   │   └── website-and-socials-field-modal.tsx
│       │   │   │   │   │   ├── program-application-form.tsx
│       │   │   │   │   │   ├── program-terms-preview.tsx
│       │   │   │   │   │   └── required-fields-preview.tsx
│       │   │   │   │   ├── branding-context-provider.tsx
│       │   │   │   │   ├── branding-form.tsx
│       │   │   │   │   ├── branding-settings-form.tsx
│       │   │   │   │   ├── edit-list.tsx
│       │   │   │   │   ├── lander/
│       │   │   │   │   │   ├── lander-ai-banner.tsx
│       │   │   │   │   │   ├── lander-preview-controls.tsx
│       │   │   │   │   │   └── modals/
│       │   │   │   │   │       ├── accordion-block-modal.tsx
│       │   │   │   │   │       ├── add-block-modal.tsx
│       │   │   │   │   │       ├── earnings-calculator-block-modal.tsx
│       │   │   │   │   │       ├── edit-hero-modal.tsx
│       │   │   │   │   │       ├── files-block-modal.tsx
│       │   │   │   │   │       ├── generate-lander-modal.tsx
│       │   │   │   │   │       ├── image-block-modal.tsx
│       │   │   │   │   │       └── text-block-modal.tsx
│       │   │   │   │   ├── preview-window.tsx
│       │   │   │   │   ├── previews/
│       │   │   │   │   │   ├── application-preview.tsx
│       │   │   │   │   │   ├── embed-preview.tsx
│       │   │   │   │   │   ├── lander-preview.tsx
│       │   │   │   │   │   └── portal-preview.tsx
│       │   │   │   │   └── studs-pattern.tsx
│       │   │   │   ├── group-color-circle.tsx
│       │   │   │   ├── group-color-picker.tsx
│       │   │   │   ├── group-selector.tsx
│       │   │   │   ├── group-settings-row.tsx
│       │   │   │   ├── groups-multi-select.tsx
│       │   │   │   └── reward-discount-partners-card.tsx
│       │   │   ├── hero-background.tsx
│       │   │   ├── lander/
│       │   │   │   ├── blocks/
│       │   │   │   │   ├── accordion-block.tsx
│       │   │   │   │   ├── block-description.tsx
│       │   │   │   │   ├── block-markdown.tsx
│       │   │   │   │   ├── block-title.tsx
│       │   │   │   │   ├── earnings-calculator-block.tsx
│       │   │   │   │   ├── files-block.tsx
│       │   │   │   │   ├── image-block.tsx
│       │   │   │   │   ├── index.tsx
│       │   │   │   │   ├── text-block.tsx
│       │   │   │   │   └── wave-pattern.tsx
│       │   │   │   ├── lander-hero.tsx
│       │   │   │   └── lander-rewards.tsx
│       │   │   ├── mark-commission-duplicate-modal.tsx
│       │   │   ├── mark-commission-fraud-or-canceled-modal.tsx
│       │   │   ├── merge-accounts/
│       │   │   │   ├── account-input-group.tsx
│       │   │   │   ├── form-context.tsx
│       │   │   │   ├── merge-account-form.tsx
│       │   │   │   ├── merge-partner-accounts-modal.tsx
│       │   │   │   ├── otp-input-field.tsx
│       │   │   │   ├── send-verification-code-form.tsx
│       │   │   │   ├── step-progress-bar.tsx
│       │   │   │   └── verify-code-form.tsx
│       │   │   ├── overview/
│       │   │   │   ├── blocks/
│       │   │   │   │   ├── commissions-block.tsx
│       │   │   │   │   ├── conversion-block.tsx
│       │   │   │   │   ├── countries-block.tsx
│       │   │   │   │   ├── links-block.tsx
│       │   │   │   │   ├── partners-block.tsx
│       │   │   │   │   ├── sale-type-block.tsx
│       │   │   │   │   └── traffic-sources-block.tsx
│       │   │   │   ├── exceeded-events-limit.tsx
│       │   │   │   ├── program-overview-block.tsx
│       │   │   │   └── program-overview-card.tsx
│       │   │   ├── partner-about.tsx
│       │   │   ├── partner-advanced-settings-modal.tsx
│       │   │   ├── partner-application-details.tsx
│       │   │   ├── partner-application-sheet.tsx
│       │   │   ├── partner-avatar.tsx
│       │   │   ├── partner-comments.tsx
│       │   │   ├── partner-info-cards.tsx
│       │   │   ├── partner-info-group.tsx
│       │   │   ├── partner-info-section.tsx
│       │   │   ├── partner-info-stats.tsx
│       │   │   ├── partner-link-selector.tsx
│       │   │   ├── partner-network/
│       │   │   │   ├── conversion-score-tooltip.tsx
│       │   │   │   ├── invites-usage.tsx
│       │   │   │   └── network-partner-sheet.tsx
│       │   │   ├── partner-platform-card.tsx
│       │   │   ├── partner-platform-summary.tsx
│       │   │   ├── partner-platforms-form.tsx
│       │   │   ├── partner-profile-sheet.tsx
│       │   │   ├── partner-row-item.tsx
│       │   │   ├── partner-selector.tsx
│       │   │   ├── partner-sheet-tabs.tsx
│       │   │   ├── partner-social-column.tsx
│       │   │   ├── partner-star-button.tsx
│       │   │   ├── partner-status-badge-with-tooltip.tsx
│       │   │   ├── partner-status-badges.ts
│       │   │   ├── partners-upgrade-modal.tsx
│       │   │   ├── payout-row-menu.tsx
│       │   │   ├── payout-status-badge-partner.tsx
│       │   │   ├── payout-status-badges.tsx
│       │   │   ├── payout-status-descriptions.ts
│       │   │   ├── payouts/
│       │   │   │   ├── bank-account-requirements-modal.tsx
│       │   │   │   ├── connect-payout-button.tsx
│       │   │   │   ├── connect-payout-modal.tsx
│       │   │   │   ├── payout-method-cards.tsx
│       │   │   │   ├── payout-method-config.ts
│       │   │   │   ├── payout-method-dropdown.tsx
│       │   │   │   ├── stablecoin-payout-banner.tsx
│       │   │   │   ├── stablecoin-payout-card.tsx
│       │   │   │   ├── stablecoin-payout-icon.tsx
│       │   │   │   ├── stablecoin-payout-modal.tsx
│       │   │   │   ├── use-payout-connect-flow.tsx
│       │   │   │   └── use-stablecoin-payout-promo.tsx
│       │   │   ├── program-application-sheet.tsx
│       │   │   ├── program-card.tsx
│       │   │   ├── program-category-select.tsx
│       │   │   ├── program-color-picker.tsx
│       │   │   ├── program-eligibility-card.tsx
│       │   │   ├── program-help-links.tsx
│       │   │   ├── program-invite-card.tsx
│       │   │   ├── program-link-configuration.tsx
│       │   │   ├── program-marketplace/
│       │   │   │   ├── program-category.tsx
│       │   │   │   ├── program-marketplace-banner.tsx
│       │   │   │   ├── program-marketplace-card.tsx
│       │   │   │   ├── program-marketplace-logos.tsx
│       │   │   │   ├── program-reward-icon.tsx
│       │   │   │   ├── program-rewards-display.tsx
│       │   │   │   ├── programs-promo-banner.tsx
│       │   │   │   ├── programs-promo-card.tsx
│       │   │   │   └── use-program-marketplace-promo.tsx
│       │   │   ├── program-onboarding-form-wrapper.tsx
│       │   │   ├── program-reward-description.tsx
│       │   │   ├── program-reward-list.tsx
│       │   │   ├── program-reward-modifiers-tooltip.tsx
│       │   │   ├── program-reward-terms.tsx
│       │   │   ├── program-rewards-panel.tsx
│       │   │   ├── program-selector.tsx
│       │   │   ├── program-sheet-accordion.tsx
│       │   │   ├── program-stats-filter.tsx
│       │   │   ├── resources/
│       │   │   │   ├── resource-card.tsx
│       │   │   │   └── resource-section.tsx
│       │   │   ├── rewards/
│       │   │   │   ├── add-edit-reward-sheet.tsx
│       │   │   │   ├── reward-icon-square.tsx
│       │   │   │   ├── reward-preview-card.tsx
│       │   │   │   └── rewards-logic.tsx
│       │   │   ├── rewind/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── partner-rewind-banner.tsx
│       │   │   │   ├── partner-rewind-card.tsx
│       │   │   │   └── use-partner-rewind-status.tsx
│       │   │   ├── trusted-partner-badge.tsx
│       │   │   └── use-country-change-warning-modal.tsx
│       │   ├── placeholders/
│       │   │   ├── bubble-icon.tsx
│       │   │   ├── button-link.tsx
│       │   │   ├── cta.tsx
│       │   │   ├── feature-graphics/
│       │   │   │   ├── analytics.tsx
│       │   │   │   ├── collaboration.tsx
│       │   │   │   ├── domains.tsx
│       │   │   │   ├── personalization.tsx
│       │   │   │   └── qr.tsx
│       │   │   ├── features-section.tsx
│       │   │   ├── hero.tsx
│       │   │   └── logos.tsx
│       │   ├── postbacks/
│       │   │   ├── add-edit-postback-modal.tsx
│       │   │   ├── partner-postback-actions.tsx
│       │   │   ├── postback-card.tsx
│       │   │   ├── postback-detail-skeleton.tsx
│       │   │   ├── postback-event-details-sheet.tsx
│       │   │   ├── postback-event-list-skeleton.tsx
│       │   │   ├── postback-event-list.tsx
│       │   │   ├── postback-placeholder.tsx
│       │   │   ├── postback-secret-modal.tsx
│       │   │   ├── postback-status.tsx
│       │   │   └── send-test-postback-modal.tsx
│       │   ├── referrals/
│       │   │   ├── form-fields/
│       │   │   │   ├── country-field.tsx
│       │   │   │   ├── date-field.tsx
│       │   │   │   ├── form-control.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   ├── max-character-count.tsx
│       │   │   │   ├── multi-select-field.tsx
│       │   │   │   ├── number-field.tsx
│       │   │   │   ├── phone-field.tsx
│       │   │   │   ├── select-field.tsx
│       │   │   │   ├── text-field.tsx
│       │   │   │   └── textarea-field.tsx
│       │   │   ├── partner-profile-referral-sheet.tsx
│       │   │   ├── partner-profile-referrals-empty-state.tsx
│       │   │   ├── partner-referral-sheet.tsx
│       │   │   ├── partner-referral-table.tsx
│       │   │   ├── referral-details.tsx
│       │   │   ├── referral-form.tsx
│       │   │   ├── referral-lead-details.tsx
│       │   │   ├── referral-partner-details.tsx
│       │   │   ├── referral-status-badge.tsx
│       │   │   ├── referral-status-badges.ts
│       │   │   ├── referral-status-dropdown.tsx
│       │   │   ├── referral-utils.ts
│       │   │   ├── submit-referral-sheet.tsx
│       │   │   └── use-program-referral-filters.tsx
│       │   ├── shared/
│       │   │   ├── amount-input.tsx
│       │   │   ├── animated-empty-state.tsx
│       │   │   ├── back-link.tsx
│       │   │   ├── business-badge-tooltip.tsx
│       │   │   ├── conditional-link.tsx
│       │   │   ├── custom-toast.tsx
│       │   │   ├── emoji-picker.tsx
│       │   │   ├── empty-state.tsx
│       │   │   ├── filter-button-table-row.tsx
│       │   │   ├── icons/
│       │   │   │   ├── airplay.tsx
│       │   │   │   ├── alert-circle-fill.tsx
│       │   │   │   ├── chart.tsx
│       │   │   │   ├── check-circle-fill.tsx
│       │   │   │   ├── clipboard.tsx
│       │   │   │   ├── delete.tsx
│       │   │   │   ├── devices.tsx
│       │   │   │   ├── divider.tsx
│       │   │   │   ├── download.tsx
│       │   │   │   ├── drag.tsx
│       │   │   │   ├── edit.tsx
│       │   │   │   ├── external-link.tsx
│       │   │   │   ├── eye-off.tsx
│       │   │   │   ├── eye.tsx
│       │   │   │   ├── filter.tsx
│       │   │   │   ├── heart.tsx
│       │   │   │   ├── index.tsx
│       │   │   │   ├── infinity.tsx
│       │   │   │   ├── link.tsx
│       │   │   │   ├── lock.tsx
│       │   │   │   ├── logout.tsx
│       │   │   │   ├── message.tsx
│       │   │   │   ├── qr.tsx
│       │   │   │   ├── random.tsx
│       │   │   │   ├── repeat.tsx
│       │   │   │   ├── save.tsx
│       │   │   │   ├── search.tsx
│       │   │   │   ├── sort.tsx
│       │   │   │   ├── three-dots.tsx
│       │   │   │   ├── upload-cloud.tsx
│       │   │   │   ├── users.tsx
│       │   │   │   ├── x-circle-fill.tsx
│       │   │   │   └── x.tsx
│       │   │   ├── inline-badge-popover.tsx
│       │   │   ├── markdown-description.tsx
│       │   │   ├── markdown.tsx
│       │   │   ├── max-characters-counter.tsx
│       │   │   ├── message-input.tsx
│       │   │   ├── modal-hero.tsx
│       │   │   ├── new-background.tsx
│       │   │   ├── password-requirements.tsx
│       │   │   ├── pro-badge-tooltip.tsx
│       │   │   ├── qr-code.tsx
│       │   │   ├── search-box.tsx
│       │   │   ├── simple-date-range-picker.tsx
│       │   │   ├── simple-empty-state.tsx
│       │   │   ├── upgrade-required-toast.tsx
│       │   │   └── zoom-image.tsx
│       │   ├── support/
│       │   │   ├── chat-bubble.tsx
│       │   │   ├── chat-interface.tsx
│       │   │   ├── clear-chat-button.tsx
│       │   │   ├── code-block.tsx
│       │   │   ├── embedded-chat.tsx
│       │   │   ├── message.tsx
│       │   │   ├── program-combobox.tsx
│       │   │   ├── source-citations.tsx
│       │   │   ├── starter-questions.tsx
│       │   │   ├── status-indicator.tsx
│       │   │   ├── ticket-upload.tsx
│       │   │   ├── types.ts
│       │   │   └── workspace-combobox.tsx
│       │   ├── token-avatar.tsx
│       │   ├── users/
│       │   │   ├── user-avatar.tsx
│       │   │   └── user-row-item.tsx
│       │   ├── webhooks/
│       │   │   ├── add-edit-webhook-form.tsx
│       │   │   ├── link-selector.tsx
│       │   │   ├── loading-events-skelton.tsx
│       │   │   ├── no-events-placeholder.tsx
│       │   │   ├── webhook-card.tsx
│       │   │   ├── webhook-event-details-sheet.tsx
│       │   │   ├── webhook-event-list.tsx
│       │   │   ├── webhook-header.tsx
│       │   │   ├── webhook-placeholder.tsx
│       │   │   └── webhook-status.tsx
│       │   └── workspaces/
│       │       ├── create-workspace-button.tsx
│       │       ├── create-workspace-form.tsx
│       │       ├── delete-workspace.tsx
│       │       ├── invite-teammates-form.tsx
│       │       ├── manage-subscription-button.tsx
│       │       ├── plan-badge.tsx
│       │       ├── plan-features.tsx
│       │       ├── subscription-menu.tsx
│       │       ├── upgrade-plan-button.tsx
│       │       ├── upload-logo.tsx
│       │       ├── workspace-arrow.tsx
│       │       ├── workspace-exceeded-events.tsx
│       │       └── workspace-selector.tsx
│       ├── vercel.json
│       └── vitest.config.ts
├── package.json
├── packages/
│   ├── cli/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── api/
│   │   │   │   ├── callback.ts
│   │   │   │   ├── domains.ts
│   │   │   │   └── links.ts
│   │   │   ├── commands/
│   │   │   │   ├── config.ts
│   │   │   │   ├── domains.ts
│   │   │   │   ├── links.ts
│   │   │   │   ├── login.ts
│   │   │   │   └── shorten.ts
│   │   │   ├── index.ts
│   │   │   ├── types/
│   │   │   │   └── index.ts
│   │   │   └── utils/
│   │   │       ├── config.ts
│   │   │       ├── get-nanoid.ts
│   │   │       ├── get-package-info.ts
│   │   │       ├── handle-error.ts
│   │   │       ├── logger.ts
│   │   │       ├── oauth.ts
│   │   │       └── parser.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── email/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── bounty-thumbnail.tsx
│   │   │   │   └── footer.tsx
│   │   │   ├── index.ts
│   │   │   ├── react-email.d.ts
│   │   │   ├── resend/
│   │   │   │   ├── client.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── send-via-nodemailer.ts
│   │   │   ├── send-via-resend.ts
│   │   │   ├── templates/
│   │   │   │   ├── api-key-created.tsx
│   │   │   │   ├── bounty-approved.tsx
│   │   │   │   ├── bounty-completed.tsx
│   │   │   │   ├── bounty-new-submission.tsx
│   │   │   │   ├── bounty-rejected.tsx
│   │   │   │   ├── bounty-submitted.tsx
│   │   │   │   ├── broadcasts/
│   │   │   │   │   ├── dub-product-update-mar26.tsx
│   │   │   │   │   ├── dub-wrapped.tsx
│   │   │   │   │   ├── payout-auto-withdrawals.tsx
│   │   │   │   │   ├── program-marketplace-announcement.tsx
│   │   │   │   │   └── stablecoin-payouts-announcement.tsx
│   │   │   │   ├── campaign-email.tsx
│   │   │   │   ├── clicks-exceeded.tsx
│   │   │   │   ├── clicks-summary.tsx
│   │   │   │   ├── confirm-email-change.tsx
│   │   │   │   ├── connect-payout-reminder.tsx
│   │   │   │   ├── connect-platforms-reminder.tsx
│   │   │   │   ├── connected-payout-method.tsx
│   │   │   │   ├── connected-paypal-account.tsx
│   │   │   │   ├── discount-deleted.tsx
│   │   │   │   ├── domain-claimed.tsx
│   │   │   │   ├── domain-deleted.tsx
│   │   │   │   ├── domain-expired.tsx
│   │   │   │   ├── domain-renewal-failed.tsx
│   │   │   │   ├── domain-renewal-reminder.tsx
│   │   │   │   ├── domain-renewed.tsx
│   │   │   │   ├── domain-transferred.tsx
│   │   │   │   ├── dub-partner-rewind.tsx
│   │   │   │   ├── duplicate-payout-method.tsx
│   │   │   │   ├── email-domain-status-changed.tsx
│   │   │   │   ├── email-updated.tsx
│   │   │   │   ├── export-ready.tsx
│   │   │   │   ├── failed-payment.tsx
│   │   │   │   ├── feedback-email.tsx
│   │   │   │   ├── folder-edit-access-requested.tsx
│   │   │   │   ├── integration-installed.tsx
│   │   │   │   ├── invalid-domain.tsx
│   │   │   │   ├── links-import-errors.tsx
│   │   │   │   ├── links-imported.tsx
│   │   │   │   ├── links-limit.tsx
│   │   │   │   ├── login-link.tsx
│   │   │   │   ├── new-bounty-available.tsx
│   │   │   │   ├── new-commission-alert-partner.tsx
│   │   │   │   ├── new-message-from-partner.tsx
│   │   │   │   ├── new-message-from-program.tsx
│   │   │   │   ├── new-referral-signup.tsx
│   │   │   │   ├── new-sale-alert-program-owner.tsx
│   │   │   │   ├── notify-partner-reapply.tsx
│   │   │   │   ├── partner-account-merged.tsx
│   │   │   │   ├── partner-application-approved.tsx
│   │   │   │   ├── partner-application-received.tsx
│   │   │   │   ├── partner-application-rejected.tsx
│   │   │   │   ├── partner-banned.tsx
│   │   │   │   ├── partner-deactivated.tsx
│   │   │   │   ├── partner-group-changed.tsx
│   │   │   │   ├── partner-payout-confirmed.tsx
│   │   │   │   ├── partner-payout-failed.tsx
│   │   │   │   ├── partner-payout-force-withdrawal.tsx
│   │   │   │   ├── partner-payout-processed.tsx
│   │   │   │   ├── partner-payout-withdrawal-completed.tsx
│   │   │   │   ├── partner-payout-withdrawal-failed.tsx
│   │   │   │   ├── partner-payout-withdrawal-initiated.tsx
│   │   │   │   ├── partner-paypal-payout-failed.tsx
│   │   │   │   ├── partner-program-summary.tsx
│   │   │   │   ├── partner-referral-submitted.tsx
│   │   │   │   ├── partner-user-invited.tsx
│   │   │   │   ├── password-updated.tsx
│   │   │   │   ├── pending-applications-summary.tsx
│   │   │   │   ├── program-application-reminder.tsx
│   │   │   │   ├── program-imported.tsx
│   │   │   │   ├── program-invite.tsx
│   │   │   │   ├── program-network-invite.tsx
│   │   │   │   ├── program-payout-reminder.tsx
│   │   │   │   ├── program-payout-thank-you.tsx
│   │   │   │   ├── program-welcome.tsx
│   │   │   │   ├── referral-invite.tsx
│   │   │   │   ├── referral-status-update.tsx
│   │   │   │   ├── reset-password-link.tsx
│   │   │   │   ├── unresolved-fraud-events-summary.tsx
│   │   │   │   ├── upgrade-email.tsx
│   │   │   │   ├── verify-email-for-account-merge.tsx
│   │   │   │   ├── verify-email.tsx
│   │   │   │   ├── webhook-added.tsx
│   │   │   │   ├── webhook-disabled.tsx
│   │   │   │   ├── webhook-failed.tsx
│   │   │   │   ├── welcome-email-partner.tsx
│   │   │   │   ├── welcome-email.tsx
│   │   │   │   └── workspace-invite.tsx
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── embeds/
│   │   ├── core/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── constants.ts
│   │   │   │   ├── core.ts
│   │   │   │   ├── embed.ts
│   │   │   │   ├── error.ts
│   │   │   │   ├── example/
│   │   │   │   │   └── index.html
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsup.config.ts
│   │   └── react/
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── postcss.config.js
│   │       ├── prepublish.js
│   │       ├── src/
│   │       │   ├── embed.tsx
│   │       │   ├── example/
│   │       │   │   └── app.tsx
│   │       │   └── index.ts
│   │       ├── tailwind.config.ts
│   │       ├── tsconfig.json
│   │       └── tsup.config.ts
│   ├── hubspot-app/
│   │   ├── CLAUDE.md
│   │   ├── README.md
│   │   ├── hsproject.json
│   │   ├── package.json
│   │   └── src/
│   │       └── app/
│   │           ├── app-hsmeta.json
│   │           └── webhooks/
│   │               └── webhooks-hsmeta.json
│   ├── prisma/
│   │   ├── client.ts
│   │   ├── edge.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── schema/
│   │   │   ├── activity.prisma
│   │   │   ├── bounty.prisma
│   │   │   ├── campaign.prisma
│   │   │   ├── comment.prisma
│   │   │   ├── commission.prisma
│   │   │   ├── customer.prisma
│   │   │   ├── dashboard.prisma
│   │   │   ├── discount.prisma
│   │   │   ├── domain.prisma
│   │   │   ├── folder.prisma
│   │   │   ├── fraud.prisma
│   │   │   ├── group.prisma
│   │   │   ├── integration.prisma
│   │   │   ├── invoice.prisma
│   │   │   ├── jackson.prisma
│   │   │   ├── link.prisma
│   │   │   ├── message.prisma
│   │   │   ├── misc.prisma
│   │   │   ├── network.prisma
│   │   │   ├── notification.prisma
│   │   │   ├── oauth.prisma
│   │   │   ├── partner.prisma
│   │   │   ├── payout.prisma
│   │   │   ├── platform.prisma
│   │   │   ├── postback.prisma
│   │   │   ├── program.prisma
│   │   │   ├── referral.prisma
│   │   │   ├── reward.prisma
│   │   │   ├── schema.prisma
│   │   │   ├── tag.prisma
│   │   │   ├── token.prisma
│   │   │   ├── utm.prisma
│   │   │   ├── webhook.prisma
│   │   │   ├── workflow.prisma
│   │   │   └── workspace.prisma
│   │   └── tsconfig.json
│   ├── stripe-app/
│   │   ├── README.md
│   │   ├── jest.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── hooks/
│   │   │   │   └── use-workspace.ts
│   │   │   ├── utils/
│   │   │   │   ├── constants.ts
│   │   │   │   ├── dub.ts
│   │   │   │   ├── oauth.ts
│   │   │   │   ├── secrets.ts
│   │   │   │   ├── stripe.ts
│   │   │   │   └── types.ts
│   │   │   └── views/
│   │   │       └── AppSettings.tsx
│   │   ├── stripe-app.dev.json
│   │   ├── stripe-app.json
│   │   ├── tsconfig.json
│   │   └── ui-extensions.d.ts
│   ├── tailwind-config/
│   │   ├── package.json
│   │   ├── tailwind.config.ts
│   │   └── themes.css
│   ├── tinybird/
│   │   ├── README.md
│   │   ├── datasources/
│   │   │   ├── dub_audit_logs.datasource
│   │   │   ├── dub_click_events.datasource
│   │   │   ├── dub_click_events_id.datasource
│   │   │   ├── dub_click_events_mv.datasource
│   │   │   ├── dub_conversion_events_log.datasource
│   │   │   ├── dub_first_sale_mv.datasource
│   │   │   ├── dub_import_error_logs.datasource
│   │   │   ├── dub_lead_events.datasource
│   │   │   ├── dub_lead_events_mv.datasource
│   │   │   ├── dub_links_metadata.datasource
│   │   │   ├── dub_links_metadata_latest.datasource
│   │   │   ├── dub_postback_events.datasource
│   │   │   ├── dub_sale_events.datasource
│   │   │   ├── dub_sale_events_mv.datasource
│   │   │   └── dub_webhook_events.datasource
│   │   └── pipes/
│   │       ├── all_stats.pipe
│   │       ├── coordinates_all.pipe
│   │       ├── coordinates_sales.pipe
│   │       ├── dub_click_events_id_pipe.pipe
│   │       ├── dub_click_events_pipe.pipe
│   │       ├── dub_first_sale_pipe.pipe
│   │       ├── dub_lead_events_pipe.pipe
│   │       ├── dub_links_metadata_pipe.pipe
│   │       ├── dub_sale_events_pipe.pipe
│   │       ├── get_audit_logs.pipe
│   │       ├── get_click_event.pipe
│   │       ├── get_framer_lead_events.pipe
│   │       ├── get_import_error_logs.pipe
│   │       ├── get_lead_event.pipe
│   │       ├── get_lead_events.pipe
│   │       ├── get_postback_events.pipe
│   │       ├── get_webhook_events.pipe
│   │       ├── v2_customer_events.pipe
│   │       ├── v2_top_programs.pipe
│   │       ├── v3_count.pipe
│   │       ├── v3_events.pipe
│   │       ├── v3_group_by.pipe
│   │       ├── v3_group_by_link_country.pipe
│   │       ├── v3_group_by_link_metadata.pipe
│   │       ├── v3_timeseries.pipe
│   │       ├── v3_usage.pipe
│   │       ├── v3_usage_latest.pipe
│   │       ├── v4_count.pipe
│   │       ├── v4_events.pipe
│   │       ├── v4_group_by.pipe
│   │       ├── v4_group_by_link_metadata.pipe
│   │       └── v4_timeseries.pipe
│   ├── tsconfig/
│   │   ├── base.json
│   │   ├── nextjs.json
│   │   ├── package.json
│   │   └── react-library.json
│   ├── ui/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── accordion.tsx
│   │   │   ├── activity-ring.tsx
│   │   │   ├── alert.tsx
│   │   │   ├── animated-size-container.tsx
│   │   │   ├── avatar.tsx
│   │   │   ├── background.tsx
│   │   │   ├── badge.tsx
│   │   │   ├── blur-image.tsx
│   │   │   ├── button.tsx
│   │   │   ├── card-list/
│   │   │   │   ├── card-list-card.tsx
│   │   │   │   ├── card-list.tsx
│   │   │   │   └── index.ts
│   │   │   ├── card-selector.tsx
│   │   │   ├── carousel/
│   │   │   │   ├── carousel.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── nav-bar.tsx
│   │   │   │   └── thumbnails.tsx
│   │   │   ├── charts/
│   │   │   │   ├── areas.tsx
│   │   │   │   ├── bars.tsx
│   │   │   │   ├── chart-context.ts
│   │   │   │   ├── funnel-chart.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── time-series-chart.tsx
│   │   │   │   ├── tooltip-sync.tsx
│   │   │   │   ├── types.ts
│   │   │   │   ├── use-tooltip.ts
│   │   │   │   ├── utils.ts
│   │   │   │   ├── x-axis.tsx
│   │   │   │   └── y-axis.tsx
│   │   │   ├── checkbox.tsx
│   │   │   ├── client-only.tsx
│   │   │   ├── combobox/
│   │   │   │   └── index.tsx
│   │   │   ├── composite-logo.tsx
│   │   │   ├── content.ts
│   │   │   ├── copy-button.tsx
│   │   │   ├── copy-text.tsx
│   │   │   ├── date-picker/
│   │   │   │   ├── calendar.tsx
│   │   │   │   ├── date-picker.tsx
│   │   │   │   ├── date-range-picker.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── presets.tsx
│   │   │   │   ├── shared.ts
│   │   │   │   ├── trigger.tsx
│   │   │   │   └── types.ts
│   │   │   ├── dots-pattern.tsx
│   │   │   ├── dub-status-badge.tsx
│   │   │   ├── empty-state.tsx
│   │   │   ├── file-upload.tsx
│   │   │   ├── filter/
│   │   │   │   ├── filter-list.tsx
│   │   │   │   ├── filter-select.tsx
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── footer.tsx
│   │   │   ├── form.tsx
│   │   │   ├── grid.tsx
│   │   │   ├── hooks/
│   │   │   │   ├── index.ts
│   │   │   │   ├── use-click-handlers.ts
│   │   │   │   ├── use-column-visibility.ts
│   │   │   │   ├── use-cookies.ts
│   │   │   │   ├── use-copy-to-clipboard.tsx
│   │   │   │   ├── use-current-anchor.ts
│   │   │   │   ├── use-current-subdomain.ts
│   │   │   │   ├── use-enter-submit.ts
│   │   │   │   ├── use-in-viewport.tsx
│   │   │   │   ├── use-input-focused.ts
│   │   │   │   ├── use-intersection-observer.ts
│   │   │   │   ├── use-keyboard-shortcut.tsx
│   │   │   │   ├── use-local-storage.ts
│   │   │   │   ├── use-media-query.ts
│   │   │   │   ├── use-optimistic-update.ts
│   │   │   │   ├── use-pagination.ts
│   │   │   │   ├── use-remove-ga-params.ts
│   │   │   │   ├── use-resize-observer.ts
│   │   │   │   ├── use-router-stuff.ts
│   │   │   │   ├── use-scroll-progress.ts
│   │   │   │   ├── use-scroll.ts
│   │   │   │   └── use-toast-with-undo.tsx
│   │   │   ├── icon-menu.tsx
│   │   │   ├── icons/
│   │   │   │   ├── anthropic.tsx
│   │   │   │   ├── arrow-up-right-2.tsx
│   │   │   │   ├── bing.tsx
│   │   │   │   ├── continents/
│   │   │   │   │   ├── af.tsx
│   │   │   │   │   ├── as.tsx
│   │   │   │   │   ├── eu.tsx
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── na.tsx
│   │   │   │   │   ├── oc.tsx
│   │   │   │   │   └── sa.tsx
│   │   │   │   ├── copy.tsx
│   │   │   │   ├── crown-small.tsx
│   │   │   │   ├── default-domains/
│   │   │   │   │   ├── amazon.tsx
│   │   │   │   │   ├── chatgpt.tsx
│   │   │   │   │   ├── figma.tsx
│   │   │   │   │   ├── github-enhanced.tsx
│   │   │   │   │   ├── google-enhanced.tsx
│   │   │   │   │   └── spotify.tsx
│   │   │   │   ├── dub-analytics.tsx
│   │   │   │   ├── dub-api.tsx
│   │   │   │   ├── dub-crafted-shield.tsx
│   │   │   │   ├── dub-links.tsx
│   │   │   │   ├── dub-partners.tsx
│   │   │   │   ├── dub-product-icon.tsx
│   │   │   │   ├── expanding-arrow.tsx
│   │   │   │   ├── facebook.tsx
│   │   │   │   ├── file-pen.tsx
│   │   │   │   ├── file-send.tsx
│   │   │   │   ├── github.tsx
│   │   │   │   ├── go.tsx
│   │   │   │   ├── google.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   ├── instagram.tsx
│   │   │   │   ├── ios-app-store.tsx
│   │   │   │   ├── linkedin.tsx
│   │   │   │   ├── loading-circle.tsx
│   │   │   │   ├── loading-dots.tsx
│   │   │   │   ├── loading-spinner.tsx
│   │   │   │   ├── lock-small.tsx
│   │   │   │   ├── magic.tsx
│   │   │   │   ├── markdown-icon.tsx
│   │   │   │   ├── matrix-lines.tsx
│   │   │   │   ├── nucleo/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── android-logo.tsx
│   │   │   │   │   ├── apple-logo.tsx
│   │   │   │   │   ├── apple.tsx
│   │   │   │   │   ├── arrow-bold-up.tsx
│   │   │   │   │   ├── arrow-right.tsx
│   │   │   │   │   ├── arrow-trend-up.tsx
│   │   │   │   │   ├── arrow-turn-left.tsx
│   │   │   │   │   ├── arrow-turn-right2.tsx
│   │   │   │   │   ├── arrow-up-right.tsx
│   │   │   │   │   ├── arrows-opposite-direction-x.tsx
│   │   │   │   │   ├── arrows-opposite-direction-y.tsx
│   │   │   │   │   ├── at-sign.tsx
│   │   │   │   │   ├── badge-check.tsx
│   │   │   │   │   ├── badge-check2-fill.tsx
│   │   │   │   │   ├── bell.tsx
│   │   │   │   │   ├── blog.tsx
│   │   │   │   │   ├── bolt-fill.tsx
│   │   │   │   │   ├── bolt.tsx
│   │   │   │   │   ├── book-open.tsx
│   │   │   │   │   ├── book2-fill.tsx
│   │   │   │   │   ├── book2-small.tsx
│   │   │   │   │   ├── book2.tsx
│   │   │   │   │   ├── books2.tsx
│   │   │   │   │   ├── box-archive.tsx
│   │   │   │   │   ├── brackets-curly.tsx
│   │   │   │   │   ├── briefcase-fill.tsx
│   │   │   │   │   ├── brush.tsx
│   │   │   │   │   ├── bullet-list-fill.tsx
│   │   │   │   │   ├── bullet-list.tsx
│   │   │   │   │   ├── calculator.tsx
│   │   │   │   │   ├── calendar-days.tsx
│   │   │   │   │   ├── calendar-refresh.tsx
│   │   │   │   │   ├── calendar.tsx
│   │   │   │   │   ├── calendar6.tsx
│   │   │   │   │   ├── cards.tsx
│   │   │   │   │   ├── caret-up-fill.tsx
│   │   │   │   │   ├── chart-activity2.tsx
│   │   │   │   │   ├── chart-area2.tsx
│   │   │   │   │   ├── chart-line.tsx
│   │   │   │   │   ├── check.tsx
│   │   │   │   │   ├── check2.tsx
│   │   │   │   │   ├── checkbox-checked-fill.tsx
│   │   │   │   │   ├── checkbox-unchecked.tsx
│   │   │   │   │   ├── chevron-left.tsx
│   │   │   │   │   ├── chevron-right.tsx
│   │   │   │   │   ├── chevron-up.tsx
│   │   │   │   │   ├── circle-arrow-right.tsx
│   │   │   │   │   ├── circle-check-fill.tsx
│   │   │   │   │   ├── circle-check.tsx
│   │   │   │   │   ├── circle-dollar-out.tsx
│   │   │   │   │   ├── circle-dollar.tsx
│   │   │   │   │   ├── circle-dollar3.tsx
│   │   │   │   │   ├── circle-dotted.tsx
│   │   │   │   │   ├── circle-half-dotted-check.tsx
│   │   │   │   │   ├── circle-half-dotted-clock.tsx
│   │   │   │   │   ├── circle-info.tsx
│   │   │   │   │   ├── circle-percentage.tsx
│   │   │   │   │   ├── circle-play-fill.tsx
│   │   │   │   │   ├── circle-play.tsx
│   │   │   │   │   ├── circle-question.tsx
│   │   │   │   │   ├── circle-user.tsx
│   │   │   │   │   ├── circle-warning.tsx
│   │   │   │   │   ├── circle-xmark.tsx
│   │   │   │   │   ├── circles.tsx
│   │   │   │   │   ├── circles3.tsx
│   │   │   │   │   ├── cloud-upload.tsx
│   │   │   │   │   ├── 
Download .txt
Showing preview only (650K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5941 symbols across 3089 files)

FILE: apps/web/app/(ee)/admin.dub.co/(auth)/layout.tsx
  function AdminAuthLayout (line 3) | function AdminAuthLayout({

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/analytics/page.tsx
  function AdminAnalytics (line 5) | function AdminAnalytics() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/commissions/client.tsx
  function CommissionsPageClient (line 28) | function CommissionsPageClient() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/commissions/page.tsx
  function CommissionsPage (line 4) | async function CommissionsPage() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/ban-link.tsx
  function BanLink (line 8) | function BanLink() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/delete-partner-account.tsx
  function DeletePartnerAccount (line 8) | function DeletePartnerAccount() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/impersonate-user.tsx
  function ImpersonateUser (line 10) | function ImpersonateUser() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/impersonate-workspace.tsx
  function ImpersonateWorkspace (line 10) | function ImpersonateWorkspace() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/refresh-domain.tsx
  function RefreshDomain (line 8) | function RefreshDomain() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/reset-login-attempts.tsx
  function ResetLoginAttempts (line 8) | function ResetLoginAttempts() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/components/user-info.tsx
  type UserInfoProps (line 7) | interface UserInfoProps {
  function UserInfo (line 51) | function UserInfo({ data }: { data: UserInfoProps }) {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/events/page.tsx
  function AdminEvents (line 7) | function AdminEvents() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/layout-nav-client.tsx
  function AdminNav (line 37) | function AdminNav() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/layout.tsx
  function AdminLayout (line 7) | function AdminLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/links/page.tsx
  function AdminLinks (line 4) | function AdminLinks() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/page.tsx
  function AdminPage (line 14) | function AdminPage() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/client.tsx
  type TimeseriesData (line 32) | interface TimeseriesData {
  type InvoiceData (line 39) | interface InvoiceData {
  type Tab (line 50) | type Tab = {
  function PayoutsPageClient (line 56) | function PayoutsPageClient() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/page.tsx
  function PayoutsPage (line 4) | async function PayoutsPage() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/paypal/client.tsx
  function PaypalPayoutsPageClient (line 30) | function PaypalPayoutsPageClient() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/paypal/page.tsx
  function PaypalPayoutsPage (line 4) | async function PaypalPayoutsPage() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/revenue/client.tsx
  function RevenuePageClient (line 16) | function RevenuePageClient() {

FILE: apps/web/app/(ee)/admin.dub.co/(dashboard)/revenue/page.tsx
  function RevenuePage (line 4) | async function RevenuePage() {

FILE: apps/web/app/(ee)/admin.dub.co/layout.tsx
  function AdminLayout (line 6) | function AdminLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/(ee)/api/admin/analytics/route.ts
  constant GET (line 7) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/ban/route.ts
  constant POST (line 11) | const POST = withAdmin(async ({ req }) => {

FILE: apps/web/app/(ee)/api/admin/commissions/get-commissions-timeseries.ts
  type Commission (line 8) | interface Commission {
  function getCommissionsTimeseries (line 13) | async function getCommissionsTimeseries({

FILE: apps/web/app/(ee)/api/admin/commissions/get-top-program-by-commissions.ts
  function getTopProgramsByCommissions (line 4) | async function getTopProgramsByCommissions({

FILE: apps/web/app/(ee)/api/admin/commissions/route.ts
  constant GET (line 20) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/delete-partner-account/route.ts
  constant POST (line 10) | const POST = withAdmin(async ({ req }) => {

FILE: apps/web/app/(ee)/api/admin/events/route.ts
  constant GET (line 7) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/impersonate/route.ts
  constant POST (line 8) | const POST = withAdmin(async ({ req }) => {
  function getImpersonateUrl (line 104) | async function getImpersonateUrl(email: string) {

FILE: apps/web/app/(ee)/api/admin/links/[linkId]/route.ts
  constant GET (line 7) | const GET = withAdmin(async ({ params }) => {

FILE: apps/web/app/(ee)/api/admin/links/ban/route.ts
  constant DELETE (line 14) | const DELETE = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/links/count/route.ts
  constant GET (line 7) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/links/route.ts
  constant GET (line 8) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/payouts/paypal/route.ts
  constant GET (line 5) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/payouts/route.ts
  type TimeseriesPoint (line 12) | interface TimeseriesPoint {
  type FormattedTimeseriesPoint (line 18) | interface FormattedTimeseriesPoint extends TimeseriesPoint {
  constant GET (line 31) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/admin/refresh-domain/route.ts
  constant POST (line 6) | const POST = withAdmin(async ({ req }) => {

FILE: apps/web/app/(ee)/api/admin/reset-login-attempts/route.ts
  constant POST (line 6) | const POST = withAdmin(async ({ req }) => {

FILE: apps/web/app/(ee)/api/admin/revenue/get-top-programs-by-sales.ts
  function getTopProgramsBySales (line 7) | async function getTopProgramsBySales({

FILE: apps/web/app/(ee)/api/admin/revenue/route.ts
  constant GET (line 8) | const GET = withAdmin(async ({ searchParams }) => {

FILE: apps/web/app/(ee)/api/audit-logs/export/route.ts
  constant POST (line 16) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/auth/saml/callback/route.ts
  function POST (line 4) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/auth/saml/token/route.ts
  function POST (line 6) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/auth/saml/userinfo/route.ts
  function GET (line 4) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/auth/saml/verify/route.tsx
  function POST (line 5) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/bounties/[bountyId]/route.ts
  constant GET (line 26) | const GET = withWorkspace(
  constant PATCH (line 54) | const PATCH = withWorkspace(
  constant DELETE (line 293) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/bounties/[bountyId]/submissions/[submissionId]/approve/route.ts
  constant POST (line 10) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/bounties/[bountyId]/submissions/[submissionId]/reject/route.ts
  constant POST (line 10) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts
  constant GET (line 12) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/bounties/[bountyId]/sync-social-metrics/route.ts
  constant POST (line 27) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/bounties/count/submissions/route.ts
  constant GET (line 17) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/bounties/route.ts
  constant GET (line 32) | const GET = withWorkspace(
  constant POST (line 155) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/[campaignId]/duplicate/route.ts
  constant POST (line 12) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/[campaignId]/events/count/route.ts
  constant GET (line 9) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/[campaignId]/events/route.ts
  constant GET (line 9) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/[campaignId]/preview/route.ts
  constant POST (line 28) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/[campaignId]/route.ts
  constant GET (line 25) | const GET = withWorkspace(
  constant PATCH (line 52) | const PATCH = withWorkspace(
  constant DELETE (line 180) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/[campaignId]/summary/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/count/route.ts
  constant GET (line 9) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/campaigns/route.ts
  constant GET (line 21) | const GET = withWorkspace(
  constant POST (line 80) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/commissions/[commissionId]/route.ts
  constant GET (line 22) | const GET = withWorkspace(async ({ workspace, params }) => {
  constant PATCH (line 100) | const PATCH = withWorkspace(

FILE: apps/web/app/(ee)/api/commissions/count/route.ts
  constant GET (line 8) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/commissions/export/route.ts
  constant MAX_COMMISSIONS_TO_EXPORT (line 12) | const MAX_COMMISSIONS_TO_EXPORT = 1000;
  constant GET (line 15) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/commissions/route.ts
  constant GET (line 15) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/commissions/timeseries/route.ts
  type Commission (line 18) | interface Commission {
  constant GET (line 24) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/cron/aggregate-clicks/resolve-click-reward-amount.ts
  function resolveClickRewardAmount (line 8) | function resolveClickRewardAmount({

FILE: apps/web/app/(ee)/api/cron/aggregate-clicks/route.ts
  constant BATCH_SIZE (line 22) | const BATCH_SIZE = 200;
  function handler (line 32) | async function handler(req: Request) {

FILE: apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts
  constant MAX_PAGE_SIZE (line 23) | const MAX_PAGE_SIZE = 100;
  function POST (line 27) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/bounties/notify-partners/route.ts
  constant EMAIL_BATCH_SIZE (line 27) | const EMAIL_BATCH_SIZE = 100;
  constant BATCH_DELAY_SECONDS (line 28) | const BATCH_DELAY_SECONDS = 2;
  constant EXTENDED_DELAY_SECONDS (line 29) | const EXTENDED_DELAY_SECONDS = 30;
  constant EXTENDED_DELAY_INTERVAL (line 30) | const EXTENDED_DELAY_INTERVAL = 25;
  function POST (line 34) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/bounties/queue-sync-social-metrics/route.ts
  constant GET (line 11) | const GET = withCron(async () => {

FILE: apps/web/app/(ee)/api/cron/bounties/sync-social-metrics/route.ts
  constant SUBMISSION_BATCH_SIZE (line 23) | const SUBMISSION_BATCH_SIZE = 50;
  constant POST (line 26) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/campaigns/broadcast/route.ts
  constant EMAIL_BATCH_SIZE (line 31) | const EMAIL_BATCH_SIZE = 100;
  constant BATCH_DELAY_SECONDS (line 32) | const BATCH_DELAY_SECONDS = 2;
  constant EXTENDED_DELAY_SECONDS (line 33) | const EXTENDED_DELAY_SECONDS = 30;
  constant EXTENDED_DELAY_INTERVAL (line 34) | const EXTENDED_DELAY_INTERVAL = 25;
  function POST (line 38) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/cleanup/demo-embed-partners/route.ts
  function POST (line 13) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/cleanup/e2e-tests/route.ts
  constant E2E_USER_ID (line 14) | const E2E_USER_ID = "clxz1q7c7000hbqx5ckv4r82h";
  constant E2E_WORKSPACE_ID (line 15) | const E2E_WORKSPACE_ID = "clrei1gld0002vs9mzn93p8ik";
  function POST (line 19) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/cleanup/expired-tokens/route.ts
  function POST (line 15) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/cleanup/link-retention/route.ts
  function POST (line 16) | async function POST(req: Request) {
  constant LINKS_PER_BATCH (line 56) | const LINKS_PER_BATCH = 100;
  constant MAX_LINK_BATCHES (line 57) | const MAX_LINK_BATCHES = 10;
  function deleteOldLinks (line 59) | async function deleteOldLinks(

FILE: apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts
  function POST (line 13) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/cleanup/unenrolled-partners/route.ts
  function POST (line 13) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/discount-codes/create/queue-batches/route.ts
  constant POST (line 18) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/discount-codes/create/route.ts
  constant POST (line 16) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/discount-codes/delete/route.ts
  constant POST (line 15) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/disposable-emails/route.ts
  function POST (line 11) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/domains/delete/route.ts
  function POST (line 21) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/domains/renewal-payments/route.ts
  type GroupedWorkspace (line 20) | interface GroupedWorkspace {
  function GET (line 26) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/domains/renewal-reminders/route.ts
  constant REMINDER_WINDOWS (line 27) | const REMINDER_WINDOWS = [30, 23, 16];
  function GET (line 30) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/domains/transfer/route.ts
  function POST (line 20) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/domains/update/route.ts
  constant LINK_BATCH_SIZE (line 18) | const LINK_BATCH_SIZE = 100;
  function POST (line 21) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/domains/verify/route.ts
  function GET (line 21) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/email-domains/update/route.ts
  constant POST (line 15) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/email-domains/verify/route.ts
  constant GET (line 14) | const GET = withCron(async () => {
  function verifyEmailDomain (line 47) | async function verifyEmailDomain(domain: EmailDomain) {

FILE: apps/web/app/(ee)/api/cron/export/commissions/fetch-commissions-batch.ts
  type CommissionFilters (line 5) | type CommissionFilters = Omit<

FILE: apps/web/app/(ee)/api/cron/export/commissions/route.ts
  function POST (line 23) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/export/customers/route.ts
  constant MAX_CUSTOMERS_EXPORT_LIMIT (line 14) | const MAX_CUSTOMERS_EXPORT_LIMIT = 100_000;
  constant POST (line 19) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/export/events/partner/route.ts
  function POST (line 39) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/export/events/workspace/route.ts
  function POST (line 30) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/export/links/route.ts
  function POST (line 28) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/export/partners/fetch-partners-batch.ts
  type PartnerFilters (line 5) | type PartnerFilters = Omit<

FILE: apps/web/app/(ee)/api/cron/export/partners/route.ts
  function POST (line 23) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/folders/delete/route.ts
  constant MAX_LINKS_PER_BATCH (line 12) | const MAX_LINKS_PER_BATCH = 500;
  function POST (line 20) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/framer/backfill-leads-batch/route.ts
  type PayloadItem (line 31) | type PayloadItem = {
  constant FRAMER_WORKSPACE_ID (line 38) | const FRAMER_WORKSPACE_ID = "clsvopiw0000ejy0grp821me0";
  constant CACHE_KEY (line 39) | const CACHE_KEY = "framerMigratedExternalIdEventNames";
  constant DOMAIN (line 40) | const DOMAIN = "framer.link";
  constant POST (line 56) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/cron/fraud/summary/route.ts
  constant PROGRAMS_BATCH_SIZE (line 17) | const PROGRAMS_BATCH_SIZE = 10;
  function handler (line 26) | async function handler(req: Request) {

FILE: apps/web/app/(ee)/api/cron/fx-rates/route.ts
  function POST (line 11) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/groups/create-default-links/route.ts
  constant PAGE_SIZE (line 19) | const PAGE_SIZE = 100;
  constant MAX_BATCH (line 20) | const MAX_BATCH = 10;
  function POST (line 39) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/groups/remap-default-links/route.ts
  function POST (line 43) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/groups/remap-default-links/utils.ts
  function remapPartnerGroupDefaultLinks (line 5) | function remapPartnerGroupDefaultLinks({

FILE: apps/web/app/(ee)/api/cron/groups/remap-discount-codes/route.ts
  constant POST (line 20) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/groups/sync-utm/route.ts
  constant PAGE_SIZE (line 16) | const PAGE_SIZE = 50;
  function POST (line 34) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/groups/update-default-links/route.ts
  constant PAGE_SIZE (line 16) | const PAGE_SIZE = 100;
  constant MAX_BATCH (line 17) | const MAX_BATCH = 10;
  function POST (line 35) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/bitly/fetch-utils.ts
  type FetchBitlyLinksResult (line 7) | interface FetchBitlyLinksResult {

FILE: apps/web/app/(ee)/api/cron/import/bitly/route.ts
  function POST (line 14) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/bitly/sanitize-json.ts
  function sanitizeBitlyJson (line 1) | function sanitizeBitlyJson(body: string): string {

FILE: apps/web/app/(ee)/api/cron/import/csv/route.ts
  type MapperResult (line 37) | interface MapperResult {
  type ErrorLink (line 51) | interface ErrorLink {
  function POST (line 58) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/csv/utils.ts
  function sendCsvImportEmails (line 6) | async function sendCsvImportEmails({

FILE: apps/web/app/(ee)/api/cron/import/firstpromoter/route.ts
  function POST (line 13) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/partnerstack/route.ts
  function POST (line 14) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/rebrandly/route.ts
  function POST (line 11) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/rewardful/route.ts
  function POST (line 13) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/short/route.ts
  function POST (line 11) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/import/tolt/route.ts
  function POST (line 14) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/invoices/retry-failed/route.ts
  function POST (line 14) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/links/[linkId]/complete-tests/route.ts
  function POST (line 8) | async function POST(

FILE: apps/web/app/(ee)/api/cron/links/delete/route.ts
  function POST (line 12) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/links/invalidate-for-discounts/route.ts
  function POST (line 23) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/links/invalidate-for-partners/route.ts
  function POST (line 15) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/messages/notify-partner/route.ts
  function POST (line 23) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/messages/notify-program/route.ts
  function POST (line 23) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/network/calculate-program-similarities/calculate-category-similarity.ts
  function calculateCategorySimilarity (line 4) | async function calculateCategorySimilarity(

FILE: apps/web/app/(ee)/api/cron/network/calculate-program-similarities/calculate-partner-similarity.ts
  type PartnerSimilarityResult (line 3) | interface PartnerSimilarityResult {
  function calculatePartnerSimilarity (line 10) | async function calculatePartnerSimilarity(

FILE: apps/web/app/(ee)/api/cron/network/calculate-program-similarities/calculate-performance-similarity.ts
  constant METRIC_KEYS (line 3) | const METRIC_KEYS = [
  function calculatePerformanceSimilarity (line 12) | async function calculatePerformanceSimilarity(

FILE: apps/web/app/(ee)/api/cron/network/calculate-program-similarities/route.ts
  constant PROGRAMS_PER_BATCH (line 25) | const PROGRAMS_PER_BATCH = 10;
  function POST (line 30) | async function POST(req: Request) {
  function calculateProgramSimilarity (line 52) | async function calculateProgramSimilarity({
  function findNextProgram (line 215) | async function findNextProgram({

FILE: apps/web/app/(ee)/api/cron/network/update-partner-discoverability/route.ts
  function POST (line 13) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/partner-platforms/route.ts
  constant BATCH_SIZE (line 15) | const BATCH_SIZE = 50;
  constant POST (line 26) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/partner-platforms/youtube/route.ts
  constant POST (line 16) | const POST = withCron(async () => {

FILE: apps/web/app/(ee)/api/cron/partner-program-summary/process/route.ts
  constant PARTNER_BATCH_SIZE (line 15) | const PARTNER_BATCH_SIZE = 100;
  type AnalyticsResponse (line 27) | interface AnalyticsResponse {
  constant POST (line 38) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/partner-program-summary/route.ts
  constant PROGRAM_BATCH_SIZE (line 10) | const PROGRAM_BATCH_SIZE = 50;
  constant GET (line 15) | const GET = withCron(async () => {

FILE: apps/web/app/(ee)/api/cron/partners/auto-approve/route.ts
  constant POST (line 19) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/partners/auto-reject/route.ts
  constant POST (line 20) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/partners/ban/cancel-commissions.ts
  function cancelCommissions (line 4) | async function cancelCommissions({

FILE: apps/web/app/(ee)/api/cron/partners/ban/route.ts
  constant POST (line 23) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/partners/deactivate/route.ts
  constant POST (line 17) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/partners/merge-accounts/route.ts
  constant CACHE_KEY_PREFIX (line 26) | const CACHE_KEY_PREFIX = "merge-partner-accounts";
  function POST (line 30) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/aggregate-due-commissions/route.ts
  constant BATCH_SIZE (line 13) | const BATCH_SIZE = 1000;
  function handler (line 21) | async function handler(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/balance-available/route.ts
  function POST (line 27) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/charge-succeeded/queue-external-payouts.ts
  function queueExternalPayouts (line 9) | async function queueExternalPayouts(

FILE: apps/web/app/(ee)/api/cron/payouts/charge-succeeded/queue-stripe-payouts.ts
  function queueStripePayouts (line 15) | async function queueStripePayouts(

FILE: apps/web/app/(ee)/api/cron/payouts/charge-succeeded/route.ts
  function POST (line 24) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/charge-succeeded/send-paypal-payouts.ts
  function sendPaypalPayouts (line 8) | async function sendPaypalPayouts(invoice: Pick<Invoice, "id">) {

FILE: apps/web/app/(ee)/api/cron/payouts/charge-succeeded/utils.ts
  type StablecoinScheduleResult (line 10) | interface StablecoinScheduleResult {
  function scheduleDelayedStablecoinPayouts (line 17) | async function scheduleDelayedStablecoinPayouts(invoice: {

FILE: apps/web/app/(ee)/api/cron/payouts/force-withdrawals/route.ts
  constant BATCH_SIZE (line 14) | const BATCH_SIZE = 20;
  function handler (line 22) | async function handler(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/payout-failed/route.ts
  function POST (line 22) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/payout-paid/route.ts
  function POST (line 22) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/process/process-payouts.ts
  type ProcessPayoutsProps (line 34) | interface ProcessPayoutsProps {
  function processPayouts (line 63) | async function processPayouts({

FILE: apps/web/app/(ee)/api/cron/payouts/process/route.ts
  function POST (line 27) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/process/split-payouts.ts
  function splitPayouts (line 11) | async function splitPayouts({

FILE: apps/web/app/(ee)/api/cron/payouts/process/updates/route.ts
  constant BATCH_SIZE (line 19) | const BATCH_SIZE = 100;
  function POST (line 23) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/reminders/partners/route.ts
  constant BATCH_SIZE (line 14) | const BATCH_SIZE = 1000;
  function handler (line 20) | async function handler(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/reminders/program-owners/route.ts
  function GET (line 16) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/payouts/send-stripe-payout/route.ts
  function POST (line 19) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/pending-applications-summary/route.ts
  constant PROGRAMS_BATCH_SIZE (line 19) | const PROGRAMS_BATCH_SIZE = 50;
  constant GET (line 28) | const GET = withCron(async ({ rawBody }) => {
  constant POST (line 281) | const POST = GET;

FILE: apps/web/app/(ee)/api/cron/program-application-reminder/route.ts
  function POST (line 11) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/programs/deactivate/route.ts
  constant POST (line 17) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/send-batch-email/route.ts
  type BatchError (line 31) | interface BatchError {
  function POST (line 38) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/shopify/order-paid/route.ts
  function POST (line 15) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts
  constant BATCH_SIZE (line 16) | const BATCH_SIZE = 6000;
  type ProgramEnrollmentStats (line 18) | type ProgramEnrollmentStats = Partial<
  function GET (line 349) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/streams/update-workspace-clicks/route.ts
  constant BATCH_SIZE (line 13) | const BATCH_SIZE = 10000;
  type WorkspaceAggregateUsage (line 15) | type WorkspaceAggregateUsage = {
  function GET (line 182) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts
  function GET (line 12) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/cron/usage/route.ts
  function handler (line 14) | async function handler(req: Request) {

FILE: apps/web/app/(ee)/api/cron/utils.ts
  function logAndRespond (line 1) | function logAndRespond(

FILE: apps/web/app/(ee)/api/cron/welcome-user/route.ts
  function POST (line 17) | async function POST(req: Request) {

FILE: apps/web/app/(ee)/api/cron/workflows/[workflowId]/route.ts
  function POST (line 13) | async function POST(

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-customers.ts
  constant MAX_CUSTOMERS_PER_BATCH (line 9) | const MAX_CUSTOMERS_PER_BATCH = 100;
  function deleteWorkspaceCustomers (line 11) | async function deleteWorkspaceCustomers(

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-domains.ts
  constant MAX_DOMAINS_PER_BATCH (line 8) | const MAX_DOMAINS_PER_BATCH = 10;
  function deleteWorkspaceDomains (line 10) | async function deleteWorkspaceDomains(payload: DeleteWorkspacePayload) {

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-folders.ts
  constant MAX_FOLDERS_PER_BATCH (line 7) | const MAX_FOLDERS_PER_BATCH = 100;
  function deleteWorkspaceFolders (line 9) | async function deleteWorkspaceFolders(payload: DeleteWorkspacePayload) {

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-links.ts
  constant MAX_LINKS_PER_BATCH (line 8) | const MAX_LINKS_PER_BATCH = 100;
  function deleteWorkspaceLinks (line 10) | async function deleteWorkspaceLinks(payload: DeleteWorkspacePayload) {

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace.ts
  function deleteWorkspace (line 5) | async function deleteWorkspace(payload: DeleteWorkspacePayload) {

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/route.ts
  constant POST (line 13) | const POST = withCron(async ({ rawBody }) => {

FILE: apps/web/app/(ee)/api/cron/workspaces/delete/utils.ts
  type DeleteWorkspacePayload (line 21) | type DeleteWorkspacePayload = z.infer<typeof deleteWorkspaceSchema>;
  function enqueueNextWorkspaceDeleteStep (line 23) | async function enqueueNextWorkspaceDeleteStep({

FILE: apps/web/app/(ee)/api/customers/[id]/activity/route.ts
  constant GET (line 10) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/customers/[id]/route.ts
  constant GET (line 19) | const GET = withWorkspace(
  constant PATCH (line 54) | const PATCH = withWorkspace(
  constant DELETE (line 166) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/customers/[id]/stripe-invoices/route.ts
  constant GET (line 8) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/customers/count/route.ts
  constant GET (line 9) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/customers/export/route.ts
  constant MAX_CUSTOMERS_TO_EXPORT (line 13) | const MAX_CUSTOMERS_TO_EXPORT = 1000;
  constant GET (line 16) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/customers/route.ts
  constant GET (line 23) | const GET = withWorkspace(
  constant POST (line 64) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/customers/search-stripe/route.ts
  constant GET (line 13) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/discount-codes/[discountCodeId]/route.ts
  constant DELETE (line 11) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/discount-codes/route.ts
  constant GET (line 18) | const GET = withWorkspace(
  constant POST (line 51) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/domains/register/route.ts
  constant POST (line 10) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/domains/status/route.ts
  constant GET (line 14) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/e2e/bounties/[bountyId]/route.ts
  constant DELETE (line 8) | const DELETE = withWorkspace(async ({ params, workspace }) => {

FILE: apps/web/app/(ee)/api/e2e/enrollments/route.ts
  constant PATCH (line 8) | const PATCH = withWorkspace(

FILE: apps/web/app/(ee)/api/e2e/guard.ts
  function assertE2EWorkspace (line 5) | function assertE2EWorkspace(

FILE: apps/web/app/(ee)/api/e2e/notification-emails/route.ts
  constant GET (line 9) | const GET = withWorkspace(async ({ workspace, searchParams }) => {
  constant POST (line 26) | const POST = withWorkspace(
  constant DELETE (line 53) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/e2e/trigger-workflow/[workflowId]/route.ts
  constant POST (line 13) | const POST = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/e2e/workflows/[workflowId]/route.ts
  constant PATCH (line 8) | const PATCH = withWorkspace(

FILE: apps/web/app/(ee)/api/e2e/workflows/route.ts
  constant GET (line 8) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/email-domains/[domain]/route.ts
  constant PATCH (line 20) | const PATCH = withWorkspace(
  constant DELETE (line 153) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/email-domains/[domain]/verify/route.ts
  constant GET (line 10) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/email-domains/route.ts
  constant GET (line 20) | const GET = withWorkspace(
  constant POST (line 39) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/embed/referrals/analytics/route.ts
  constant GET (line 7) | const GET = withReferralsEmbedToken(async ({ links, program }) => {

FILE: apps/web/app/(ee)/api/embed/referrals/earnings/route.ts
  constant GET (line 11) | const GET = withReferralsEmbedToken(

FILE: apps/web/app/(ee)/api/embed/referrals/leaderboard/route.ts
  constant GET (line 10) | const GET = withReferralsEmbedToken(async ({ program }) => {

FILE: apps/web/app/(ee)/api/embed/referrals/links/[linkId]/route.ts
  constant PATCH (line 19) | const PATCH = withReferralsEmbedToken(

FILE: apps/web/app/(ee)/api/embed/referrals/links/route.ts
  constant GET (line 17) | const GET = withReferralsEmbedToken(async ({ links }) => {
  constant POST (line 24) | const POST = withReferralsEmbedToken(

FILE: apps/web/app/(ee)/api/embed/referrals/token/route.ts
  constant GET (line 5) | const GET = withReferralsEmbedToken(async ({ embedToken }) => {

FILE: apps/web/app/(ee)/api/events/export/route.ts
  constant MAX_EVENTS_TO_EXPORT (line 20) | const MAX_EVENTS_TO_EXPORT = 1000;
  constant GET (line 32) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/events/route.ts
  constant GET (line 12) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/fraud/events/count/route.ts
  constant GET (line 9) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/fraud/events/route.ts
  constant GET (line 14) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/fraud/groups/count/route.ts
  constant GET (line 13) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/fraud/groups/route.ts
  constant GET (line 12) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/fraud/rules/route.ts
  constant GET (line 32) | const GET = withWorkspace(
  constant PATCH (line 76) | const PATCH = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/[groupIdOrSlug]/default-links/[defaultLinkId]/route.ts
  constant PATCH (line 18) | const PATCH = withWorkspace(
  constant DELETE (line 159) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/[groupIdOrSlug]/default-links/route.ts
  constant GET (line 21) | const GET = withWorkspace(
  constant POST (line 57) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/[groupIdOrSlug]/default/route.ts
  constant POST (line 14) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/[groupIdOrSlug]/partners/route.ts
  constant POST (line 16) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/[groupIdOrSlug]/route.ts
  constant GET (line 23) | const GET = withWorkspace(
  constant PATCH (line 50) | const PATCH = withWorkspace(
  constant DELETE (line 272) | const DELETE = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/count/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/route.ts
  constant GET (line 22) | const GET = withWorkspace(
  constant POST (line 50) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/groups/rules/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/hubspot/webhook/route.ts
  constant HUBSPOT_CLIENT_SECRET (line 14) | const HUBSPOT_CLIENT_SECRET = process.env.HUBSPOT_CLIENT_SECRET || "";
  constant POST (line 17) | const POST = withAxiom(async (req) => {
  function processWebhookEvent (line 65) | async function processWebhookEvent(event: any) {

FILE: apps/web/app/(ee)/api/messages/count/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/messages/route.ts
  constant GET (line 11) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/mock/rewardful/affiliates/route.ts
  function GET (line 3) | async function GET(request: NextRequest) {

FILE: apps/web/app/(ee)/api/mock/rewardful/campaigns/[campaignId]/route.ts
  function GET (line 4) | async function GET(

FILE: apps/web/app/(ee)/api/mock/rewardful/campaigns/route.ts
  function GET (line 4) | async function GET() {

FILE: apps/web/app/(ee)/api/mock/rewardful/commissions/route.ts
  function GET (line 3) | async function GET(request: NextRequest) {

FILE: apps/web/app/(ee)/api/mock/rewardful/referrals/route.ts
  function GET (line 3) | async function GET(request: NextRequest) {

FILE: apps/web/app/(ee)/api/network/partners/count/route.ts
  constant GET (line 10) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/network/partners/invites-usage/route.ts
  constant GET (line 6) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/network/partners/route.ts
  constant GET (line 17) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/network/programs/count/route.ts
  constant GET (line 16) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/network/programs/route.ts
  constant GET (line 12) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/invites/accept/route.ts
  constant POST (line 7) | const POST = withSession(async ({ session }) => {

FILE: apps/web/app/(ee)/api/partner-profile/invites/route.ts
  constant GET (line 21) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {
  constant POST (line 46) | const POST = withPartnerProfile(
  constant PATCH (line 169) | const PATCH = withPartnerProfile(
  constant DELETE (line 215) | const DELETE = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/messages/count/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/messages/route.ts
  constant GET (line 10) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/notification-preferences/route.ts
  constant GET (line 6) | const GET = withPartnerProfile(async ({ partner, session }) => {

FILE: apps/web/app/(ee)/api/partner-profile/payouts/count/route.ts
  constant GET (line 8) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/payouts/route.ts
  constant GET (line 10) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/payouts/settings/route.ts
  constant GET (line 6) | const GET = withPartnerProfile(async ({ partner }) => {

FILE: apps/web/app/(ee)/api/partner-profile/postbacks/[postbackId]/events/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/postbacks/[postbackId]/rotate-secret/route.ts
  constant POST (line 12) | const POST = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/postbacks/[postbackId]/route.ts
  constant GET (line 12) | const GET = withPartnerProfile(
  constant PATCH (line 30) | const PATCH = withPartnerProfile(
  constant DELETE (line 66) | const DELETE = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/postbacks/[postbackId]/send-test/route.ts
  constant POST (line 20) | const POST = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/postbacks/route.ts
  constant GET (line 22) | const GET = withPartnerProfile(
  constant POST (line 42) | const POST = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/activity-logs/route.ts
  constant GET (line 12) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/analytics/export/route.ts
  constant GET (line 18) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/analytics/route.ts
  constant GET (line 16) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/route.ts
  constant GET (line 10) | const GET = withPartnerProfile(async ({ partner, params }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/social-content-stats/route.ts
  constant GET (line 16) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/route.ts
  constant GET (line 10) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/customers/[customerId]/route.ts
  constant GET (line 20) | const GET = withPartnerProfile(async ({ partner, params }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/customers/count/route.ts
  constant GET (line 15) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/customers/route.ts
  constant GET (line 22) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/earnings/count/route.ts
  constant GET (line 12) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/earnings/route.ts
  constant GET (line 15) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/earnings/timeseries/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/events/export/route.ts
  constant MAX_EVENTS_TO_EXPORT (line 33) | const MAX_EVENTS_TO_EXPORT = 1000;
  constant GET (line 36) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/events/route.ts
  constant GET (line 22) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/groups/[groupIdOrSlug]/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(async ({ params }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/[linkId]/route.ts
  constant PATCH (line 16) | const PATCH = withPartnerProfile(
  constant DELETE (line 159) | const DELETE = withPartnerProfile(async ({ partner, params }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.ts
  constant GET (line 19) | const GET = withPartnerProfile(async ({ partner, params }) => {
  constant POST (line 47) | const POST = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/referrals/count/route.ts
  constant GET (line 12) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/referrals/route.ts
  constant GET (line 12) | const GET = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/resources/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(async ({ partner, params }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/[programId]/route.ts
  constant GET (line 8) | const GET = withPartnerProfile(async ({ partner, params }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/count/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/programs/route.ts
  constant GET (line 10) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/(ee)/api/partner-profile/rewind/route.ts
  constant GET (line 7) | const GET = withPartnerProfile(async ({ partner }) => {

FILE: apps/web/app/(ee)/api/partner-profile/route.ts
  constant GET (line 6) | const GET = withPartnerProfile(async ({ partner, partnerUser }) => {

FILE: apps/web/app/(ee)/api/partner-profile/users/route.ts
  constant GET (line 15) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {
  constant PATCH (line 63) | const PATCH = withPartnerProfile(
  constant DELETE (line 140) | const DELETE = withPartnerProfile(

FILE: apps/web/app/(ee)/api/partners/[partnerId]/application-risks/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/[partnerId]/comments/count/route.ts
  constant GET (line 7) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/[partnerId]/comments/route.ts
  constant GET (line 9) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/[partnerId]/cross-program-summary/route.ts
  constant GET (line 12) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/[partnerId]/route.ts
  constant GET (line 9) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/analytics/route.ts
  constant GET (line 18) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/ban/route.ts
  constant POST (line 12) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/count/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/deactivate/route.ts
  constant POST (line 13) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/export/route.ts
  constant MAX_PARTNERS_TO_EXPORT (line 12) | const MAX_PARTNERS_TO_EXPORT = 1000;
  constant GET (line 15) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/links/route.ts
  constant GET (line 24) | const GET = withWorkspace(
  constant POST (line 70) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/links/upsert/route.ts
  constant PUT (line 26) | const PUT = withWorkspace(

FILE: apps/web/app/(ee)/api/partners/platforms/callback/route.ts
  type State (line 21) | interface State {
  function GET (line 28) | async function GET(req: Request) {

FILE: apps/web/app/(ee)/api/partners/route.ts
  constant GET (line 19) | const GET = withWorkspace(
  constant POST (line 103) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/payouts/[payoutId]/route.ts
  constant GET (line 11) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/payouts/count/route.ts
  constant GET (line 11) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/payouts/route.ts
  constant GET (line 16) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/paypal/webhook/payouts-item-failed.ts
  constant PAYPAL_TO_DUB_STATUS (line 6) | const PAYPAL_TO_DUB_STATUS = {
  function payoutsItemFailed (line 14) | async function payoutsItemFailed(event: any) {

FILE: apps/web/app/(ee)/api/paypal/webhook/payouts-item-succeeded.ts
  function payoutsItemSucceeded (line 4) | async function payoutsItemSucceeded(event: any) {

FILE: apps/web/app/(ee)/api/paypal/webhook/verify-signature.ts
  constant CERT_CACHE_KEY_PREFIX (line 7) | const CERT_CACHE_KEY_PREFIX = "paypal:cert:";
  constant CERT_CACHE_TTL_SECONDS (line 8) | const CERT_CACHE_TTL_SECONDS = 60 * 60 * 24 * 7;
  function downloadAndCache (line 10) | async function downloadAndCache(url: string) {
  function verifySignature (line 42) | async function verifySignature({

FILE: apps/web/app/(ee)/api/programs/[programId]/applications/[applicationId]/route.ts
  constant GET (line 7) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/programs/[programId]/applications/export/route.ts
  constant GET (line 24) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/programs/[programId]/discounts/route.ts
  constant GET (line 10) | const GET = withWorkspace(async ({ workspace }) => {

FILE: apps/web/app/(ee)/api/programs/[programId]/payouts/eligible/count/route.ts
  constant GET (line 14) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/programs/[programId]/payouts/eligible/route.ts
  constant GET (line 19) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/(ee)/api/programs/[programId]/referrals/count/route.ts
  constant GET (line 12) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/programs/[programId]/referrals/route.ts
  constant GET (line 13) | const GET = withWorkspace(

FILE: apps/web/app/(ee)/api/programs/[programId]/resources/route.ts
  constant GET (line 8) | const GET = withWorkspace(async ({ workspace }) => {

FILE: apps/web/app/(ee)/api/programs/[programId]/route.ts
  constant GET (line 7) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/programs/rewardful/campaigns/route.ts
  constant GET (line 7) | const GET = withWorkspace(async ({ workspace }) => {

FILE: apps/web/app/(ee)/api/rewards/[rewardId]/route.ts
  constant GET (line 8) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/(ee)/api/rewards/route.ts
  constant GET (line 9) | const GET = withWorkspace(async ({ workspace }) => {

FILE: apps/web/app/(ee)/api/shopify/integration/callback/route.ts
  constant PATCH (line 12) | const PATCH = withWorkspace(

FILE: apps/web/app/(ee)/api/shopify/integration/webhook/app-uninstalled.ts
  function appUninstalled (line 3) | async function appUninstalled({ shopDomain }: { shopDomain: string }) {

FILE: apps/web/app/(ee)/api/shopify/integration/webhook/customers-data-request.ts
  function customersDataRequest (line 14) | async function customersDataRequest({

FILE: apps/web/app/(ee)/api/shopify/integration/webhook/customers-redact.ts
  function customersRedact (line 15) | async function customersRedact({

FILE: apps/web/app/(ee)/api/shopify/integration/webhook/orders-paid.ts
  function ordersPaid (line 8) | async function ordersPaid({

FILE: apps/web/app/(ee)/api/shopify/integration/webhook/shop-redact.ts
  function shopRedact (line 10) | async function shopRedact({

FILE: apps/web/app/(ee)/api/singular/webhook/route.ts
  constant GET (line 40) | const GET = withAxiom(async (req) => {

FILE: apps/web/app/(ee)/api/stripe/connect/v2/webhook/outbound-payment-failed.ts
  function outboundPaymentFailed (line 7) | async function outboundPaymentFailed(event: Stripe.ThinEvent) {

FILE: apps/web/app/(ee)/api/stripe/connect/v2/webhook/outbound-payment-posted.ts
  function outboundPaymentPosted (line 6) | async function outboundPaymentPosted(event: Stripe.ThinEvent) {

FILE: apps/web/app/(ee)/api/stripe/connect/v2/webhook/outbound-payment-returned.ts
  function outboundPaymentReturned (line 7) | async function outboundPaymentReturned(event: Stripe.ThinEvent) {

FILE: apps/web/app/(ee)/api/stripe/connect/v2/webhook/recipient-account-closed.ts
  function recipientAccountClosed (line 6) | async function recipientAccountClosed(event: Stripe.ThinEvent) {

FILE: apps/web/app/(ee)/api/stripe/connect/v2/webhook/recipient-configuration-updated.ts
  function recipientConfigurationUpdated (line 8) | async function recipientConfigurationUpdated(event: Stripe.ThinEvent) {

FILE: apps/web/app/(ee)/api/stripe/connect/webhook/account-application-deauthorized.ts
  function accountApplicationDeauthorized (line 5) | async function accountApplicationDeauthorized(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/connect/webhook/account-updated.ts
  function accountUpdated (line 20) | async function accountUpdated(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/connect/webhook/balance-available.ts
  function balanceAvailable (line 9) | async function balanceAvailable(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/connect/webhook/payout-failed.ts
  function payoutFailed (line 9) | async function payoutFailed(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/connect/webhook/payout-paid.ts
  function payoutPaid (line 9) | async function payoutPaid(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/route.ts
  constant CORS_HEADERS (line 11) | const CORS_HEADERS = new Headers({
  constant PATCH (line 18) | const PATCH = withWorkspace(

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/account-application-deauthorized.ts
  function accountApplicationDeauthorized (line 7) | async function accountApplicationDeauthorized(

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/charge-refunded.ts
  function chargeRefunded (line 8) | async function chargeRefunded(event: Stripe.Event, mode: StripeMode) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.ts
  function checkoutSessionCompleted (line 36) | async function checkoutSessionCompleted(
  function attributeViaPromoCode (line 555) | async function attributeViaPromoCode({
  function incrementLinkLeads (line 749) | async function incrementLinkLeads(linkId: string) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/coupon-deleted.ts
  function couponDeleted (line 12) | async function couponDeleted(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/customer-created.ts
  function customerCreated (line 6) | async function customerCreated(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/customer-subscription-created.ts
  function customerSubscriptionCreated (line 13) | async function customerSubscriptionCreated(

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/customer-subscription-deleted.ts
  function customerSubscriptionDeleted (line 5) | async function customerSubscriptionDeleted(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/customer-updated.ts
  function customerUpdated (line 6) | async function customerUpdated(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.ts
  function invoicePaid (line 21) | async function invoicePaid(event: Stripe.Event, mode: StripeMode) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/promotion-code-updated.ts
  function promotionCodeUpdated (line 5) | async function promotionCodeUpdated(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/route.ts
  constant POST (line 31) | const POST = withAxiom(async (req: Request) => {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/utils/create-new-customer.ts
  function createNewCustomer (line 16) | async function createNewCustomer(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/utils/get-connected-customer.ts
  function getConnectedCustomer (line 4) | async function getConnectedCustomer({

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/utils/get-promotion-code.ts
  function getPromotionCode (line 4) | async function getPromotionCode({

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/utils/get-subscription-product-id.ts
  function getSubscriptionProductId (line 4) | async function getSubscriptionProductId({

FILE: apps/web/app/(ee)/api/stripe/integration/webhook/utils/update-customer-with-stripe-customer-id.ts
  function updateCustomerWithStripeCustomerId (line 3) | async function updateCustomerWithStripeCustomerId({

FILE: apps/web/app/(ee)/api/stripe/webhook/charge-failed.ts
  function chargeFailed (line 6) | async function chargeFailed(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/webhook/charge-refunded.ts
  function chargeRefunded (line 6) | async function chargeRefunded(event: Stripe.Event) {
  function processDomainRenewalInvoice (line 33) | async function processDomainRenewalInvoice({ invoice }: { invoice: Invoi...

FILE: apps/web/app/(ee)/api/stripe/webhook/charge-succeeded.ts
  function chargeSucceeded (line 11) | async function chargeSucceeded(event: Stripe.Event) {
  function processPayoutInvoice (line 75) | async function processPayoutInvoice({ invoice }: { invoice: Invoice }) {
  function processDomainRenewalInvoice (line 107) | async function processDomainRenewalInvoice({ invoice }: { invoice: Invoi...

FILE: apps/web/app/(ee)/api/stripe/webhook/checkout-session-completed.ts
  function checkoutSessionCompleted (line 15) | async function checkoutSessionCompleted(event: Stripe.Event) {
  function completeOnboarding (line 143) | async function completeOnboarding({

FILE: apps/web/app/(ee)/api/stripe/webhook/customer-subscription-deleted.ts
  function customerSubscriptionDeleted (line 17) | async function customerSubscriptionDeleted(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/webhook/customer-subscription-updated.ts
  function customerSubscriptionUpdated (line 7) | async function customerSubscriptionUpdated(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/webhook/invoice-payment-failed.tsx
  function invoicePaymentFailed (line 6) | async function invoicePaymentFailed(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/webhook/payment-intent-requires-action.ts
  function paymentIntentRequiresAction (line 6) | async function paymentIntentRequiresAction(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/webhook/transfer-reversed.ts
  function transferReversed (line 5) | async function transferReversed(event: Stripe.Event) {

FILE: apps/web/app/(ee)/api/stripe/webhook/utils/process-domain-renewal-failure.ts
  function processDomainRenewalFailure (line 10) | async function processDomainRenewalFailure({

FILE: apps/web/app/(ee)/api/stripe/webhook/utils/process-payout-invoice-failure.ts
  function processPayoutInvoiceFailure (line 14) | async function processPayoutInvoiceFailure({

FILE: apps/web/app/(ee)/api/stripe/webhook/utils/send-cancellation-feedback.ts
  function sendCancellationFeedback (line 14) | async function sendCancellationFeedback({

FILE: apps/web/app/(ee)/api/stripe/webhook/utils/update-workspace-plan.ts
  function updateWorkspacePlan (line 14) | async function updateWorkspacePlan({

FILE: apps/web/app/(ee)/api/track/click/route.ts
  constant POST (line 58) | const POST = withAxiom(async (req) => {

FILE: apps/web/app/(ee)/api/track/lead/client/route.ts
  constant POST (line 14) | const POST = withPublishableKey(

FILE: apps/web/app/(ee)/api/track/lead/route.ts
  constant POST (line 10) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/track/open/route.ts
  constant POST (line 22) | const POST = withAxiom(async (req) => {

FILE: apps/web/app/(ee)/api/track/sale/client/route.ts
  constant POST (line 14) | const POST = withPublishableKey(

FILE: apps/web/app/(ee)/api/track/sale/route.ts
  constant POST (line 10) | const POST = withWorkspace(

FILE: apps/web/app/(ee)/api/track/visit/route.ts
  constant POST (line 18) | const POST = withAxiom(async (req) => {

FILE: apps/web/app/(ee)/api/workflows/partner-approved/route.ts
  type Payload (line 24) | type Payload = z.infer<typeof payloadSchema>;

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/layout.tsx
  function NewProgramWorkspaceLayout (line 4) | function NewProgramWorkspaceLayout({

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/form.tsx
  function Form (line 15) | function Form() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/overview/page-client.tsx
  function PageClient (line 17) | function PageClient() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/overview/page.tsx
  function Page (line 4) | async function Page() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/page.tsx
  function Page (line 4) | async function Page() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/partners/form.tsx
  function Form (line 16) | function Form() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/partners/page.tsx
  function Page (line 4) | async function Page() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/rewards/form.tsx
  constant DEFAULT_REWARD_TYPES (line 17) | const DEFAULT_REWARD_TYPES = [
  constant COMMISSION_STRUCTURE_DESCRIPTIONS (line 32) | const COMMISSION_STRUCTURE_DESCRIPTIONS: Record<string, string> = {
  constant PAYOUT_MODELS (line 37) | const PAYOUT_MODELS = [
  function Form (line 52) | function Form() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/rewards/page.tsx
  function ProgramOnboardingRewardsPage (line 4) | async function ProgramOnboardingRewardsPage() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/step-page.tsx
  function StepPage (line 4) | function StepPage({

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/support/form.tsx
  function Form (line 13) | function Form() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/[slug]/program/new/support/page.tsx
  function Page (line 4) | function Page() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/header.tsx
  function ProgramOnboardingHeader (line 16) | function ProgramOnboardingHeader() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/layout.tsx
  function Layout (line 8) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/sidebar-context.tsx
  type SidebarContextType (line 8) | interface SidebarContextType {
  function SidebarProvider (line 15) | function SidebarProvider({ children }: { children: ReactNode }) {
  function useSidebar (line 42) | function useSidebar() {

FILE: apps/web/app/(ee)/app.dub.co/(new-program)/steps.tsx
  function ProgramOnboardingSteps (line 14) | function ProgramOnboardingSteps() {

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/activity.tsx
  function ReferralsEmbedActivity (line 9) | function ReferralsEmbedActivity({
  function EmptyState (line 102) | function EmptyState() {
  function EmptyStateBackground (line 126) | function EmptyStateBackground({ className, ...rest }: SVGProps<SVGSVGEle...

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/add-edit-link.tsx
  type Props (line 27) | interface Props {
  type FormData (line 34) | interface FormData {
  function ReferralsEmbedCreateUpdateLink (line 39) | function ReferralsEmbedCreateUpdateLink({
  function DestinationDomainCombobox (line 302) | function DestinationDomainCombobox({

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/dynamic-height-messenger.tsx
  function DynamicHeightMessenger (line 5) | function DynamicHeightMessenger() {

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/earnings-summary.tsx
  function ReferralsEmbedEarningsSummary (line 4) | function ReferralsEmbedEarningsSummary({

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/earnings.tsx
  function ReferralsEmbedEarnings (line 22) | function ReferralsEmbedEarnings({ salesCount }: { salesCount: number }) {

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/faq.tsx
  function ReferralsEmbedFAQ (line 15) | function ReferralsEmbedFAQ({

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/leaderboard.tsx
  function ReferralsEmbedLeaderboard (line 18) | function ReferralsEmbedLeaderboard() {

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/links-list.tsx
  type Props (line 27) | interface Props {
  function ReferralsEmbedLinksList (line 38) | function ReferralsEmbedLinksList({

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/links.tsx
  type Props (line 8) | interface Props {
  function ReferralsEmbedLinks (line 17) | function ReferralsEmbedLinks({ links, program, group }: Props) {

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/page-client.tsx
  function ReferralsEmbedPageClient (line 42) | function ReferralsEmbedPageClient({
  function ReferralLinkDisplay (line 241) | function ReferralLinkDisplay({
  function Menu (line 415) | function Menu({

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/page.tsx
  function ReferralsEmbedPage (line 9) | async function ReferralsEmbedPage(props: {
  function ReferralsEmbedRSC (line 40) | async function ReferralsEmbedRSC({
  function EmbedInlineLoading (line 60) | function EmbedInlineLoading({ themeOptions }: { themeOptions: ThemeOptio...

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/quickstart.tsx
  constant BUTTON_CLASSNAME (line 20) | const BUTTON_CLASSNAME = "h-9 rounded-lg bg-bg-inverted hover:bg-neutral...
  function ReferralsEmbedQuickstart (line 22) | function ReferralsEmbedQuickstart({
  constant BG_MUTED (line 184) | const BG_MUTED = "rgb(var(--bg-muted))";
  constant BG_DEFAULT (line 185) | const BG_DEFAULT = "rgb(var(--bg-default))";
  constant BORDER_SUBTLE (line 186) | const BORDER_SUBTLE = "rgb(var(--border-subtle))";
  constant CONTENT_SUBTLE (line 187) | const CONTENT_SUBTLE = "rgb(var(--content-subtle))";

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/resources.tsx
  function ReferralsEmbedResources (line 14) | function ReferralsEmbedResources({

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/theme-options.ts
  type ThemeOptions (line 3) | type ThemeOptions = {
  function parseThemeOptions (line 7) | function parseThemeOptions(themeOptions?: string): ThemeOptions {

FILE: apps/web/app/(ee)/app.dub.co/embed/referrals/types.ts
  type ReferralsEmbedLink (line 4) | type ReferralsEmbedLink = z.infer<typeof ReferralsEmbedLinkSchema>;

FILE: apps/web/app/(ee)/app.dub.co/invoices/[invoiceId]/domain-renewal-invoice.tsx
  function DomainRenewalInvoice (line 25) | async function DomainRenewalInvoice({

FILE: apps/web/app/(ee)/app.dub.co/invoices/[invoiceId]/partner-payout-invoice.tsx
  function PartnerPayoutInvoice (line 35) | async function PartnerPayoutInvoice({

FILE: apps/web/app/(ee)/app.dub.co/invoices/[invoiceId]/route.tsx
  constant GET (line 9) | const GET = withSession(async ({ session, params }) => {

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/apply-button.tsx
  function ApplyButton (line 7) | function ApplyButton({

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/apply/page.tsx
  function ApplicationPage (line 11) | async function ApplicationPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/apply/success/cta-buttons.tsx
  function CTAButtons (line 8) | function CTAButtons() {

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/apply/success/page.tsx
  constant FEATURES (line 17) | const FEATURES = [
  function SuccessPage (line 44) | async function SuccessPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/apply/success/pixel-conversion.tsx
  type Window (line 8) | interface Window {
  function PixelConversion (line 18) | function PixelConversion() {
  function PixelConversionHelper (line 28) | function PixelConversionHelper() {

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/apply/success/screenshot.tsx
  function Screenshot (line 5) | function Screenshot({

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/header.tsx
  function ApplyHeader (line 10) | function ApplyHeader({

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/layout.tsx
  function generateMetadata (line 13) | async function generateMetadata(props: {
  function generateStaticParams (line 41) | async function generateStaticParams() {
  function ApplyLayout (line 50) | async function ApplyLayout(

FILE: apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/(default)/page.tsx
  function ApplyPage (line 12) | async function ApplyPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/(generic)/layout.tsx
  function generateMetadata (line 12) | async function generateMetadata(props: {
  function generateStaticParams (line 45) | async function generateStaticParams() {
  function PartnerAuthLayout (line 53) | async function PartnerAuthLayout(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/(generic)/login/page.tsx
  function LoginPage (line 10) | async function LoginPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/(generic)/register/page-client.tsx
  type PartialProgram (line 17) | type PartialProgram = Pick<Program, "name" | "logo" | "slug">;
  function RegisterPageClient (line 19) | function RegisterPageClient({
  function SignUp (line 44) | function SignUp({ program }: { program?: PartialProgram }) {
  function Verify (line 80) | function Verify() {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/(generic)/register/page.tsx
  function RegisterPage (line 7) | async function RegisterPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/partner-banner.tsx
  function PartnerBanner (line 5) | function PartnerBanner({

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/program-logos.tsx
  constant LOGO_COUNT (line 4) | const LOGO_COUNT = 13;
  constant ROW_COUNT (line 5) | const ROW_COUNT = 4;
  constant ROWS (line 8) | const ROWS = [...Array(ROW_COUNT)].map(() => {
  constant BLUR_STEPS (line 27) | const BLUR_STEPS = 5;
  constant BLUR_STEP_SIZE (line 28) | const BLUR_STEP_SIZE = 5;
  constant BLACK (line 30) | const BLACK = "rgba(0,0,0,1)";
  constant TRANSPARENT (line 31) | const TRANSPARENT = "rgba(0,0,0,0)";
  function ProgramLogos (line 33) | function ProgramLogos() {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-login-register)/side-panel.tsx
  function SidePanel (line 6) | function SidePanel({

FILE: apps/web/app/(ee)/partners.dub.co/(auth-other)/forgot-password/page.tsx
  function ForgotPasswordPage (line 4) | function ForgotPasswordPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-other)/invite/page.tsx
  function AcceptPartnerInvitePage (line 12) | function AcceptPartnerInvitePage() {

FILE: apps/web/app/(ee)/partners.dub.co/(auth-other)/layout.tsx
  function PartnerAuthLayout (line 5) | function PartnerAuthLayout({

FILE: apps/web/app/(ee)/partners.dub.co/(auth-other)/logo.tsx
  function Logo (line 7) | function Logo({ className }: { className?: string }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/auth.tsx
  constant ERROR_CODES (line 10) | const ERROR_CODES = {
  function PartnerProfileAuth (line 22) | function PartnerProfileAuth({ children }: { children: ReactNode }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/layout.tsx
  function PartnerDashboardLayout (line 6) | function PartnerDashboardLayout({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/messages/[programSlug]/page-client.tsx
  function PartnerMessagesProgramPageClient (line 44) | function PartnerMessagesProgramPageClient() {
  function ProgramInfoPanel (line 311) | function ProgramInfoPanel({
  function ProgramInfoPanelSkeleton (line 477) | function ProgramInfoPanelSkeleton() {
  function ViewProgramButton (line 547) | function ViewProgramButton({ programSlug }: { programSlug: string }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/messages/[programSlug]/page.tsx
  function PartnerMessagesProgramPage (line 3) | function PartnerMessagesProgramPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/messages/layout.tsx
  function MessagesLayout (line 13) | function MessagesLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/messages/page-client.tsx
  function PartnerMessagesPageClient (line 6) | function PartnerMessagesPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/messages/page.tsx
  function PartnerMessages (line 3) | function PartnerMessages() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/page.tsx
  function PartnersPayoutsSettings (line 7) | function PartnersPayoutsSettings() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/partner-payout-details-sheet.tsx
  type PayoutDetailsSheetProps (line 47) | type PayoutDetailsSheetProps = {
  function PayoutDetailsSheetContent (line 61) | function PayoutDetailsSheetContent({ payout }: PayoutDetailsSheetProps) {
  function PayoutDetailsSheet (line 399) | function PayoutDetailsSheet({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/partner-payout-settings-button.tsx
  function PartnerPayoutSettingsButton (line 10) | function PartnerPayoutSettingsButton() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/partner-payout-settings-sheet.tsx
  type PartnerPayoutSettingsFormData (line 32) | type PartnerPayoutSettingsFormData = z.infer<
  function useExternalPayoutEnrollments (line 36) | function useExternalPayoutEnrollments() {
  function PartnerPayoutSettingsSheet (line 58) | function PartnerPayoutSettingsSheet() {
  function PartnerPayoutSettingsSheetInner (line 87) | function PartnerPayoutSettingsSheetInner() {
  function PayoutMethodsSectionSkeleton (line 180) | function PayoutMethodsSectionSkeleton() {
  function PayoutMethodsSection (line 198) | function PayoutMethodsSection() {
  function InvoiceDetailsSection (line 284) | function InvoiceDetailsSection({
  function ConnectedExternalAccounts (line 347) | function ConnectedExternalAccounts() {
  function usePartnerPayoutSettingsSheet (line 413) | function usePartnerPayoutSettingsSheet() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/payout-stats.tsx
  function PayoutStatsCard (line 24) | function PayoutStatsCard({
  function PayoutStats (line 115) | function PayoutStats() {
  function ForceWithdrawalModalDescription (line 270) | function ForceWithdrawalModalDescription({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/payout-table.tsx
  function PayoutTable (line 40) | function PayoutTable() {
  function AmountRowItem (line 276) | function AmountRowItem({ payout }: { payout: PartnerPayoutResponse }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/payouts/use-payout-filters.tsx
  function usePayoutFilters (line 10) | function usePayoutFilters() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/about-you-form.tsx
  type AboutYouFormData (line 22) | type AboutYouFormData = {
  function AboutYouForm (line 28) | function AboutYouForm({ partner }: { partner?: PartnerProps }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/how-you-work-form.tsx
  type HowYouWorkFormData (line 19) | type HowYouWorkFormData = {
  function HowYouWorkForm (line 24) | function HowYouWorkForm({ partner }: { partner?: PartnerProps }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/industry-interests-modal.tsx
  type IndustryInterestsModalProps (line 8) | type IndustryInterestsModalProps = {
  function IndustryInterestsModal (line 15) | function IndustryInterestsModal({
  function IndustryInterestsModalInner (line 27) | function IndustryInterestsModalInner({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/members/page-client.tsx
  function ProfileMembersPageClient (line 41) | function ProfileMembersPageClient() {
  function RoleCell (line 294) | function RoleCell({
  function RowMenuButton (line 352) | function RowMenuButton({
  function MenuItem (line 420) | function MenuItem({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/members/page.tsx
  function ProfileMembersPage (line 3) | function ProfileMembersPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/notifications/page-client.tsx
  type PreferenceType (line 17) | type PreferenceType = z.infer<typeof partnerNotificationTypes>;
  type Preferences (line 18) | type Preferences = Record<PreferenceType, boolean>;
  function PartnerSettingsNotificationsPageClient (line 54) | function PartnerSettingsNotificationsPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/notifications/page.tsx
  function PartnerSettingsNotificationsPage (line 5) | function PartnerSettingsNotificationsPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page-client.tsx
  function ProfileSettingsPageClient (line 18) | function ProfileSettingsPageClient() {
  function Controls (line 47) | function Controls() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/page.tsx
  function ProfileSettingsPage (line 3) | function ProfileSettingsPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/postbacks/[id]/page-client.tsx
  type PostbackDetailPageClientProps (line 22) | interface PostbackDetailPageClientProps {
  function PostbackDetailPageClient (line 26) | function PostbackDetailPageClient({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/postbacks/[id]/page.tsx
  function PostbackDetailPage (line 3) | async function PostbackDetailPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/postbacks/add-postback-button.tsx
  function AddPostbackButton (line 5) | function AddPostbackButton({ onClick }: { onClick: () => void }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/postbacks/page-client.tsx
  function PostbacksPageClient (line 17) | function PostbacksPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/postbacks/page.tsx
  function PostbacksPage (line 3) | function PostbacksPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-details-form.tsx
  type BasicInfoFormData (line 36) | type BasicInfoFormData = {
  function ProfileDetailsForm (line 45) | function ProfileDetailsForm({ partner }: { partner?: PartnerProps }) {
  function BasicInfoForm (line 147) | function BasicInfoForm({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/profile-discovery-guide.tsx
  function ProfileDiscoveryGuide (line 15) | function ProfileDiscoveryGuide() {
  function ConditionalLink (line 119) | function ConditionalLink({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/settings-row.tsx
  function SettingsRow (line 3) | function SettingsRow({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/use-partner-discovery-requirements.ts
  function usePartnerDiscoveryRequirements (line 6) | function usePartnerDiscoveryRequirements() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/analytics/page.tsx
  function PartnerAnalytics (line 4) | function PartnerAnalytics() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/auth.tsx
  function ProgramEnrollmentAuth (line 8) | function ProgramEnrollmentAuth({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/[bountyId]/bounty-performance-section.tsx
  type PerformanceAttribute (line 45) | type PerformanceAttribute = keyof typeof PERFORMANCE_BOUNTY_SCOPE_ATTRIB...
  type PerformanceRow (line 47) | interface PerformanceRow {
  constant ATTRIBUTE_TO_ANALYTICS_FIELD (line 64) | const ATTRIBUTE_TO_ANALYTICS_FIELD: Partial<
  constant ATTRIBUTE_TO_CHART_FIELD (line 72) | const ATTRIBUTE_TO_CHART_FIELD: Partial<
  constant ATTRIBUTE_TO_EVENT_PARAMS (line 80) | const ATTRIBUTE_TO_EVENT_PARAMS: Partial<
  constant ATTRIBUTE_TO_TABLE_TITLE (line 91) | const ATTRIBUTE_TO_TABLE_TITLE: Record<PerformanceAttribute, string> = {
  function BountyPerformanceSection (line 98) | function BountyPerformanceSection({
  function BountyPerformanceChart (line 118) | function BountyPerformanceChart({ bounty }: { bounty: PartnerBountyProps...
  constant PAGE_SIZE (line 259) | const PAGE_SIZE = 10;
  function PerformanceTableShell (line 261) | function PerformanceTableShell({
  function BountyPerformanceTable (line 291) | function BountyPerformanceTable({ bounty }: { bounty: PartnerBountyProps...
  function BountyPerformanceEventsTable (line 303) | function BountyPerformanceEventsTable({
  function BountyPerformanceCommissionsTable (line 544) | function BountyPerformanceCommissionsTable({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/[bountyId]/bounty-submissions-table.tsx
  type PartnerBountySubmission (line 16) | type PartnerBountySubmission = PartnerBountyProps["submissions"][number];
  function BountySubmissionsTable (line 18) | function BountySubmissionsTable({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/[bountyId]/page-client.tsx
  function PartnerBountyPageClient (line 24) | function PartnerBountyPageClient() {
  function BountyDetailsProgressSkeleton (line 99) | function BountyDetailsProgressSkeleton() {
  function PartnerBountyPageHeader (line 115) | function PartnerBountyPageHeader() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/[bountyId]/page.tsx
  function PartnerBountyPage (line 7) | function PartnerBountyPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/bounty-card.tsx
  function PartnerBountyCard (line 21) | function PartnerBountyCard({
  function BountyRewardsTable (line 100) | function BountyRewardsTable({
  function BountyEndDate (line 176) | function BountyEndDate({ bounty }: { bounty: PartnerBountyProps }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/page-client.tsx
  function BountiesPageClient (line 22) | function BountiesPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/bounties/page.tsx
  function BountiesPage (line 4) | function BountiesPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/(index)/layout.tsx
  function PartnerCustomersLayout (line 18) | function PartnerCustomersLayout({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/(index)/page-client.tsx
  function ProgramCustomersPageClient (line 34) | function ProgramCustomersPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/(index)/page.tsx
  function ProgramCustomers (line 3) | function ProgramCustomers() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/(index)/referrals/page.tsx
  function PartnerCustomersReferralsPage (line 29) | function PartnerCustomersReferralsPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/(index)/use-partner-customer-filters.tsx
  function usePartnerCustomerFilters (line 7) | function usePartnerCustomerFilters() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/[customerId]/page-client.tsx
  function ProgramCustomerPageClient (line 22) | function ProgramCustomerPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/customers/[customerId]/page.tsx
  function ProgramCustomer (line 3) | function ProgramCustomer() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/earnings/earnings-composite-chart.tsx
  constant LINE_COLORS (line 29) | const LINE_COLORS = [
  constant EVENT_TYPE_LINE_COLORS (line 38) | const EVENT_TYPE_LINE_COLORS = {
  constant MAX_LINES (line 44) | const MAX_LINES = LINE_COLORS.length;
  function EarningsCompositeChart (line 46) | function EarningsCompositeChart() {
  function EarningsTableControls (line 240) | function EarningsTableControls() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/earnings/earnings-table.tsx
  type ColumnMeta (line 37) | type ColumnMeta = {
  function EarningsTablePartner (line 43) | function EarningsTablePartner({ limit }: { limit?: number }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/earnings/page.tsx
  function ProgramEarning (line 6) | function ProgramEarning() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/events/page.tsx
  function ProgramEvents (line 5) | function ProgramEvents() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/hide-program-details-button.tsx
  function HideProgramDetailsButton (line 8) | function HideProgramDetailsButton() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/layout.tsx
  function Layout (line 3) | function Layout({ children }: { children: React.ReactNode }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/page-client.tsx
  function usePartnerLinksContext (line 34) | function usePartnerLinksContext() {
  function ProgramLinksPageClient (line 44) | function ProgramLinksPageClient() {
  function LinkCardSkeleton (line 199) | function LinkCardSkeleton() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/page.tsx
  function ProgramLinks (line 6) | function ProgramLinks() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-card.tsx
  constant CHARTS (line 45) | const CHARTS = [
  function PartnerLinkCard (line 67) | function PartnerLinkCard({ link }: { link: PartnerProfileLinkProps }) {
  function LinkEventsChart (line 398) | function LinkEventsChart({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-controls.tsx
  function PartnerLinkControls (line 10) | function PartnerLinkControls({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/page-client.tsx
  function ProgramPageClient (line 70) | function ProgramPageClient() {
  function EarningsChart (line 287) | function EarningsChart() {
  function StatCard (line 425) | function StatCard({
  function StatCardSimple (line 505) | function StatCardSimple({
  function BrandedChart (line 554) | function BrandedChart({
  function ViewMoreButton (line 642) | function ViewMoreButton({ href }: { href: string }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/page.tsx
  function ProgramPage (line 5) | function ProgramPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/payouts-card.tsx
  function PayoutsCard (line 14) | function PayoutsCard({ programId }: { programId?: string }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/resources/page-client.tsx
  function ResourcesPageClient (line 19) | function ResourcesPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/resources/page.tsx
  function ResourcesPage (line 4) | function ResourcesPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/share-earnings-modal.tsx
  constant BACKGROUND_OPTIONS (line 10) | const BACKGROUND_OPTIONS = [
  type BackgroundType (line 21) | type BackgroundType = (typeof BACKGROUND_OPTIONS)[number]["id"];
  type ShareEarningsModalProps (line 23) | type ShareEarningsModalProps = {
  function ShareEarningsModal (line 33) | function ShareEarningsModal({
  function ShareEarningsModalInner (line 60) | function ShareEarningsModalInner({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx
  function UnapprovedProgramPage (line 42) | function UnapprovedProgramPage({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/apply/page.tsx
  function ProgramDetailsPage (line 14) | async function ProgramDetailsPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/apply/program-sidebar.tsx
  function ProgramSidebar (line 22) | function ProgramSidebar({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/invite/accept-program-invite-button.tsx
  function AcceptProgramInviteButton (line 11) | function AcceptProgramInviteButton({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/invite/page.tsx
  function ProgramInvitePage (line 18) | async function ProgramInvitePage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/invitations/page-client.tsx
  function ProgramInvitationsPageClient (line 10) | function ProgramInvitationsPageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/invitations/page.tsx
  function ProgramInvitationsPage (line 4) | function ProgramInvitationsPage() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/[programSlug]/header-controls.tsx
  function MarketplaceProgramHeaderControls (line 19) | function MarketplaceProgramHeaderControls({
  function ApplyButton (line 46) | function ApplyButton({ program }: { program: NetworkProgramProps }) {
  function AcceptInviteButton (line 130) | function AcceptInviteButton({ program }: { program: NetworkProgramProps ...

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/[programSlug]/loading.tsx
  function MarketplaceProgramPageLoading (line 4) | function MarketplaceProgramPageLoading() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/[programSlug]/page.tsx
  function generateStaticParams (line 21) | async function generateStaticParams() {
  function MarketplaceProgramPage (line 38) | async function MarketplaceProgramPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/featured-program-card.tsx
  function FeaturedProgramCard (line 9) | function FeaturedProgramCard({
  function FeaturedProgramCardSkeleton (line 180) | function FeaturedProgramCardSkeleton() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/featured-programs.tsx
  function FeaturedPrograms (line 18) | function FeaturedPrograms() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/layout.tsx
  function MarketplaceLayout (line 5) | function MarketplaceLayout({ children }: PropsWithChildren) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/marketplace-empty-state.tsx
  function MarketplaceEmptyState (line 4) | function MarketplaceEmptyState({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/page-client.tsx
  function ProgramMarketplacePageClient (line 22) | function ProgramMarketplacePageClient() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/page.tsx
  function PartnersDashboard (line 5) | function PartnersDashboard() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/program-card.tsx
  function ProgramCard (line 9) | function ProgramCard({ program }: { program: NetworkProgramProps }) {
  function ProgramCardSkeleton (line 121) | function ProgramCardSkeleton() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/program-sort.tsx
  function ProgramSort (line 42) | function ProgramSort() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/program-status-badge.tsx
  function ProgramStatusBadge (line 30) | function ProgramStatusBadge({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/marketplace/use-program-network-filters.tsx
  constant REWARD_TYPES (line 10) | const REWARD_TYPES = {
  function useProgramNetworkFilters (line 29) | function useProgramNetworkFilters() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/page-client.tsx
  function PartnersDashboardPageClient (line 11) | function PartnersDashboardPageClient() {
  function EmptyStateChart (line 61) | function EmptyStateChart() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/page.tsx
  function PartnersDashboard (line 4) | function PartnersDashboard() {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/rewind/2025/conclusion.tsx
  function Conclusion (line 7) | function Conclusion({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/rewind/2025/intro.tsx
  function Intro (line 4) | function Intro({ onStart }: { onStart: () => void }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/rewind/2025/page-client.tsx
  function PartnerRewind2025PageClient (line 11) | function PartnerRewind2025PageClient({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/rewind/2025/page.tsx
  function PartnerRewind2025Page (line 15) | async function PartnerRewind2025Page() {
  function Gradient (line 68) | function Gradient({ className }: { className?: string }) {

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/rewind/2025/rewind.tsx
  constant STEP_DELAY_MS (line 19) | const STEP_DELAY_MS = 8_000;
  function Rewind (line 24) | function Rewind({
  function StepSlide (line 165) | function StepSlide({

FILE: apps/web/app/(ee)/partners.dub.co/(dashboard)/rewind/2025/share-rewind-modal.tsx
  type ShareRewindModalInnerProps (line 7) | type ShareRewindModalInnerProps = {
  type ShareRewindModalProps (line 11) | type ShareRewindModalProps = {
  function ShareRewindModal (line 16) | function ShareRewindModal(props: ShareRewindModalProps) {
  function ShareRewindModalInner (line 24) | function ShareRewindModalInner({ step }: ShareRewindModalInnerProps) {
  function useShareRewindModal (line 114) | function useShareRewindModal(props: ShareRewindModalInnerProps) {

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/layout.tsx
  function PartnerOnboardingLayout (line 7) | function PartnerOnboardingLayout({

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/onboarding/onboarding-form.tsx
  type FormData (line 29) | type FormData = z.infer<typeof onboardPartnerSchema>;
  function OnboardingForm (line 31) | function OnboardingForm({

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/onboarding/page.tsx
  function PartnerOnboarding (line 6) | function PartnerOnboarding() {
  function OnboardingFormRSC (line 21) | async function OnboardingFormRSC() {

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/onboarding/payouts/page.tsx
  function OnboardingVerificationPage (line 9) | function OnboardingVerificationPage() {
  function PayoutSkeleton (line 27) | function PayoutSkeleton() {
  function PayoutRSC (line 54) | async function PayoutRSC() {

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/onboarding/payouts/payout-provider.tsx
  function PayoutProvider (line 8) | function PayoutProvider({

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/onboarding/platforms/page-client.tsx
  function OnboardingPlatformsPageClient (line 9) | function OnboardingPlatformsPageClient({

FILE: apps/web/app/(ee)/partners.dub.co/(onboarding)/onboarding/platforms/page.tsx
  function OnboardingPlatformsPage (line 12) | function OnboardingPlatformsPage() {
  function OnboardingPlatformsFormRSC (line 33) | async function OnboardingPlatformsFormRSC() {

FILE: apps/web/app/(ee)/partners.dub.co/(redirects)/apply/[programSlug]/[[...slug]]/page.tsx
  function OldApplyPage (line 3) | async function OldApplyPage(props: {

FILE: apps/web/app/(ee)/partners.dub.co/invoices/[payoutId]/route.tsx
  constant GET (line 36) | const GET = withPartnerProfile(async ({ partner, params }) => {

FILE: apps/web/app/(ee)/partners.dub.co/layout.tsx
  function PartnersLayout (line 6) | function PartnersLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/[domain]/browser-graphic.tsx
  function BrowserGraphic (line 5) | function BrowserGraphic({ domain }: { domain: string }) {

FILE: apps/web/app/[domain]/layout.tsx
  function CustomDomainLayout (line 3) | function CustomDomainLayout({

FILE: apps/web/app/[domain]/not-found/page.tsx
  constant UTM_PARAMS (line 19) | const UTM_PARAMS = {
  function NotFoundLinkPage (line 24) | async function NotFoundLinkPage(props: {

FILE: apps/web/app/[domain]/page.tsx
  function generateMetadata (line 6) | async function generateMetadata(props: {
  function CustomDomainPage (line 23) | function CustomDomainPage() {

FILE: apps/web/app/[domain]/placeholder.tsx
  constant UTM_PARAMS (line 13) | const UTM_PARAMS = {
  function PlaceholderContent (line 18) | function PlaceholderContent() {

FILE: apps/web/app/[domain]/stats/[key]/page.tsx
  function OldStatsPage (line 5) | async function OldStatsPage(props: {

FILE: apps/web/app/api/activity-logs/route.ts
  constant GET (line 13) | const GET = withWorkspace(async ({ workspace, searchParams }) => {

FILE: apps/web/app/api/ai/completion/route.ts
  constant POST (line 20) | const POST = withWorkspace(async ({ req, workspace }) => {

FILE: apps/web/app/api/ai/support-chat/route.ts
  constant POST (line 15) | const POST = withSession(async ({ req, session }) => {

FILE: apps/web/app/api/ai/support-chat/upload/route.ts
  constant MAX_UPLOAD_SIZE_BYTES (line 6) | const MAX_UPLOAD_SIZE_BYTES = 10 * 1024 * 1024;
  constant MAX_FILE_NAME_LENGTH (line 7) | const MAX_FILE_NAME_LENGTH = 255;
  constant ACCEPTED_EXTENSIONS (line 9) | const ACCEPTED_EXTENSIONS = new Set([
  constant POST (line 24) | const POST = withSession(async ({ req, session }) => {

FILE: apps/web/app/api/ai/sync-embeddings/fetch-plausible-pageviews.ts
  function fetchPlausiblePageviews (line 5) | async function fetchPlausiblePageviews(): Promise<Map<string, number>> {

FILE: apps/web/app/api/analytics/export/route.ts
  constant GET (line 19) | const GET = withWorkspace(

FILE: apps/web/app/api/analytics/route.ts
  constant GET (line 20) | const GET = withWorkspace(

FILE: apps/web/app/api/auth/reset-password/route.ts
  function POST (line 12) | async function POST(req: NextRequest) {

FILE: apps/web/app/api/callback/bitly/route.ts
  function GET (line 10) | async function GET(req: Request) {

FILE: apps/web/app/api/callback/plain/partner/route.ts
  function POST (line 21) | async function POST(req: NextRequest) {

FILE: apps/web/app/api/callback/plain/workspace/route.ts
  function POST (line 18) | async function POST(req: NextRequest) {

FILE: apps/web/app/api/dashboards/[id]/route.ts
  constant PATCH (line 33) | const PATCH = withWorkspace(
  constant DELETE (line 56) | const DELETE = withWorkspace(

FILE: apps/web/app/api/dashboards/route.ts
  constant GET (line 16) | const GET = withWorkspace(
  constant POST (line 30) | const POST = withWorkspace(

FILE: apps/web/app/api/docs/guides/[guide]/route.ts
  constant GET (line 5) | const GET = withSession(async ({ params }) => {

FILE: apps/web/app/api/domains/[domain]/primary/route.ts
  constant POST (line 8) | const POST = withWorkspace(

FILE: apps/web/app/api/domains/[domain]/route.ts
  constant GET (line 28) | const GET = withWorkspace(
  constant PATCH (line 44) | const PATCH = withWorkspace(
  constant DELETE (line 248) | const DELETE = withWorkspace(

FILE: apps/web/app/api/domains/[domain]/transfer/route.ts
  constant POST (line 13) | const POST = withWorkspace(

FILE: apps/web/app/api/domains/[domain]/validate/route.ts
  constant GET (line 8) | const GET = withSession(async ({ params }) => {
  function hasSiteConfigured (line 34) | async function hasSiteConfigured(domain: string): Promise<boolean> {

FILE: apps/web/app/api/domains/[domain]/verify/route.ts
  constant GET (line 13) | const GET = withWorkspace(

FILE: apps/web/app/api/domains/client/register/route.ts
  constant POST (line 16) | const POST = withWorkspace(

FILE: apps/web/app/api/domains/client/saved/route.ts
  constant POST (line 16) | const POST = withWorkspace(

FILE: apps/web/app/api/domains/count/route.ts
  constant GET (line 7) | const GET = withWorkspace(

FILE: apps/web/app/api/domains/default/route.ts
  constant GET (line 10) | const GET = withWorkspace(
  constant PATCH (line 57) | const PATCH = withWorkspace(

FILE: apps/web/app/api/domains/route.ts
  constant GET (line 22) | const GET = withWorkspace(
  constant POST (line 96) | const POST = withWorkspace(

FILE: apps/web/app/api/domains/search-availability/route.ts
  constant GET (line 18) | const GET = withWorkspace(

FILE: apps/web/app/api/dub/webhook/lead-created.ts
  constant REFERRAL_SIGNUPS_MAX (line 6) | const REFERRAL_SIGNUPS_MAX = 32;
  function leadCreated (line 7) | async function leadCreated(data: LeadCreatedEvent["data"]) {

FILE: apps/web/app/api/dub/webhook/sale-created.ts
  function saleCreated (line 3) | async function saleCreated(data: SaleCreatedEvent["data"]) {

FILE: apps/web/app/api/folders/[folderId]/dashboard/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/api/folders/[folderId]/route.ts
  constant GET (line 13) | const GET = withWorkspace(
  constant PATCH (line 41) | const PATCH = withWorkspace(
  constant DELETE (line 111) | const DELETE = withWorkspace(

FILE: apps/web/app/api/folders/[folderId]/users/route.ts
  constant GET (line 10) | const GET = withWorkspace(

FILE: apps/web/app/api/folders/access-requests/route.ts
  constant GET (line 6) | const GET = withWorkspace(

FILE: apps/web/app/api/folders/count/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/api/folders/permissions/route.ts
  constant GET (line 11) | const GET = withWorkspace(

FILE: apps/web/app/api/folders/route.ts
  constant GET (line 18) | const GET = withWorkspace(
  constant POST (line 41) | const POST = withWorkspace(

FILE: apps/web/app/api/integrations/route.ts
  constant GET (line 6) | const GET = withWorkspace(

FILE: apps/web/app/api/integrations/uninstall/route.ts
  constant DELETE (line 12) | const DELETE = withWorkspace(

FILE: apps/web/app/api/links/[linkId]/dashboard/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/api/links/[linkId]/route.ts
  constant GET (line 24) | const GET = withWorkspace(
  constant PATCH (line 73) | const PATCH = withWorkspace(
  constant PUT (line 205) | const PUT = PATCH;
  constant DELETE (line 208) | const DELETE = withWorkspace(

FILE: apps/web/app/api/links/[linkId]/transfer/route.ts
  constant POST (line 22) | const POST = withWorkspace(

FILE: apps/web/app/api/links/bulk/route.ts
  constant POST (line 34) | const POST = withWorkspace(
  constant PATCH (line 264) | const PATCH = withWorkspace(
  constant DELETE (line 467) | const DELETE = withWorkspace(

FILE: apps/web/app/api/links/count/route.ts
  constant GET (line 8) | const GET = withWorkspace(

FILE: apps/web/app/api/links/export/route.ts
  constant MAX_LINKS_TO_EXPORT (line 16) | const MAX_LINKS_TO_EXPORT = 1000;
  constant GET (line 19) | const GET = withWorkspace(

FILE: apps/web/app/api/links/iframeable/route.ts
  function GET (line 12) | async function GET(req: NextRequest) {

FILE: apps/web/app/api/links/info/route.ts
  constant GET (line 11) | const GET = withWorkspace(

FILE: apps/web/app/api/links/metatags/route.ts
  function GET (line 9) | async function GET(req: NextRequest) {

FILE: apps/web/app/api/links/route.ts
  constant GET (line 20) | const GET = withWorkspace(
  constant POST (line 48) | const POST = withWorkspace(

FILE: apps/web/app/api/links/sync/route.ts
  constant POST (line 10) | const POST = withWorkspace(

FILE: apps/web/app/api/links/upsert/route.ts
  constant PUT (line 23) | const PUT = withWorkspace(

FILE: apps/web/app/api/me/route.ts
  constant GET (line 6) | const GET = withSession(async ({ session }) => {

FILE: apps/web/app/api/misc/check-favicon/route.ts
  constant GET (line 5) | const GET = withSession(async ({ searchParams }) => {

FILE: apps/web/app/api/misc/check-workspace-slug/route.ts
  constant GET (line 7) | const GET = withSession(async ({ searchParams }) => {

FILE: apps/web/app/api/oauth/apps/[appId]/route.ts
  constant GET (line 13) | const GET = withWorkspace(
  constant PATCH (line 53) | const PATCH = withWorkspace(
  constant DELETE (line 173) | const DELETE = withWorkspace(

FILE: apps/web/app/api/oauth/apps/route.ts
  constant GET (line 15) | const GET = withWorkspace(
  constant POST (line 45) | const POST = withWorkspace(

FILE: apps/web/app/api/oauth/authorize/route.ts
  constant POST (line 13) | const POST = withWorkspace(async ({ session, req, workspace }) => {

FILE: apps/web/app/api/oauth/token/route.ts
  function POST (line 11) | async function POST(req: NextRequest) {

FILE: apps/web/app/api/oauth/userinfo/route.ts
  constant CORS_HEADERS (line 9) | const CORS_HEADERS = new Headers({
  function GET (line 16) | async function GET(req: NextRequest) {

FILE: apps/web/app/api/og/analytics/route.tsx
  function GET (line 15) | async function GET(req: NextRequest) {

FILE: apps/web/app/api/og/avatar/[[...seed]]/route.tsx
  function GET (line 7) | async function GET(

FILE: apps/web/app/api/og/load-google-font.ts
  function loadGoogleFont (line 1) | async function loadGoogleFont(font: string) {

FILE: apps/web/app/api/og/partner-earnings/route.tsx
  constant WIDTH (line 9) | const WIDTH = 1368;
  constant HEIGHT (line 10) | const HEIGHT = 994;
  constant BACKGROUND_IMAGES (line 12) | const BACKGROUND_IMAGES = {
  constant GET (line 17) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {
  function Chart (line 160) | function Chart({

FILE: apps/web/app/api/og/partner-rewind/route.tsx
  constant WIDTH (line 14) | const WIDTH = 1084;
  constant HEIGHT (line 15) | const HEIGHT = 994;
  constant GET (line 17) | const GET = withPartnerProfile(async ({ partner, searchParams }) => {

FILE: apps/web/app/api/og/program/route.tsx
  constant DARK_CELLS (line 11) | const DARK_CELLS = [
  function GET (line 18) | async function GET(req: NextRequest) {
  function InvoiceDollar (line 188) | function InvoiceDollar({

FILE: apps/web/app/api/providers/route.ts
  function GET (line 9) | async function GET(req: NextRequest) {

FILE: apps/web/app/api/qr/route.tsx
  constant CORS_HEADERS (line 13) | const CORS_HEADERS = new Headers({
  function GET (line 18) | async function GET(req: NextRequest) {
  function OPTIONS (line 106) | function OPTIONS() {

FILE: apps/web/app/api/resend/webhook/email-bounced.ts
  function emailBounced (line 3) | async function emailBounced({

FILE: apps/web/app/api/resend/webhook/email-delivered.ts
  function emailDelivered (line 3) | async function emailDelivered({

FILE: apps/web/app/api/resend/webhook/email-opened.ts
  function emailOpened (line 3) | async function emailOpened({

FILE: apps/web/app/api/resumes/upload-url/route.ts
  constant CORS_HEADERS (line 7) | const CORS_HEADERS = new Headers({

FILE: apps/web/app/api/route.ts
  function GET (line 6) | function GET() {

FILE: apps/web/app/api/supported-countries/route.ts
  function GET (line 6) | async function GET() {

FILE: apps/web/app/api/tags/[id]/route.ts
  constant PATCH (line 12) | const PATCH = withWorkspace(
  constant PUT (line 59) | const PUT = PATCH;
  constant DELETE (line 62) | const DELETE = withWorkspace(

FILE: apps/web/app/api/tags/count/route.ts
  constant GET (line 7) | const GET = withWorkspace(

FILE: apps/web/app/api/tags/route.ts
  constant GET (line 15) | const GET = withWorkspace(
  constant POST (line 68) | const POST = withWorkspace(

FILE: apps/web/app/api/tokens/[id]/route.ts
  constant GET (line 12) | const GET = withWorkspace(
  constant PATCH (line 53) | const PATCH = withWorkspace(
  constant DELETE (line 108) | const DELETE = withWorkspace(

FILE: apps/web/app/api/tokens/embed/referrals/route.ts
  constant POST (line 16) | const POST = withWorkspace(

FILE: apps/web/app/api/tokens/route.ts
  constant MAX_WORKSPACE_TOKENS (line 18) | const MAX_WORKSPACE_TOKENS = 100;
  constant GET (line 25) | const GET = withWorkspace(
  constant POST (line 66) | const POST = withWorkspace(

FILE: apps/web/app/api/unsplash/download/route.ts
  function POST (line 4) | async function POST(req: Request) {

FILE: apps/web/app/api/unsplash/search/route.ts
  function GET (line 8) | async function GET(req: Request) {

FILE: apps/web/app/api/user/notification-preferences/route.ts
  function GET (line 18) | async function GET(request: NextRequest) {
  function POST (line 78) | async function POST(request: NextRequest) {

FILE: apps/web/app/api/user/password/route.ts
  constant PATCH (line 13) | const PATCH = withSession(async ({ req, session }) => {

FILE: apps/web/app/api/user/referrals-token/route.ts
  constant GET (line 11) | const GET = withSession(async ({ session }) => {

FILE: apps/web/app/api/user/route.ts
  constant GET (line 28) | const GET = withSession(async ({ session }) => {
  constant PATCH (line 66) | const PATCH = withSession(async ({ req, session }) => {
  constant PUT (line 151) | const PUT = PATCH;
  constant DELETE (line 154) | const DELETE = withSession(async ({ session }) => {

FILE: apps/web/app/api/user/set-password/route.ts
  constant POST (line 11) | const POST = withSession(async ({ session }) => {

FILE: apps/web/app/api/user/tokens/route.ts
  constant GET (line 6) | const GET = withSession(async ({ session }) => {
  constant DELETE (line 31) | const DELETE = withSession(async ({ searchParams, session }) => {

FILE: apps/web/app/api/utm/[id]/route.ts
  constant PATCH (line 16) | const PATCH = withWorkspace(
  constant DELETE (line 130) | const DELETE = withWorkspace(

FILE: apps/web/app/api/utm/route.ts
  constant GET (line 9) | const GET = withWorkspace(
  constant POST (line 32) | const POST = withWorkspace(

FILE: apps/web/app/api/webhooks/[webhookId]/events/route.ts
  constant GET (line 7) | const GET = withWorkspace(

FILE: apps/web/app/api/webhooks/[webhookId]/route.ts
  constant GET (line 16) | const GET = withWorkspace(
  constant PATCH (line 53) | const PATCH = withWorkspace(
  constant DELETE (line 210) | const DELETE = withWorkspace(

FILE: apps/web/app/api/webhooks/route.ts
  constant GET (line 25) | const GET = withWorkspace(
  constant POST (line 47) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/cancel/route.ts
  constant POST (line 8) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/invoices/[invoiceId]/route.ts
  constant GET (line 6) | const GET = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/invoices/route.ts
  constant GET (line 17) | const GET = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/manage/route.ts
  constant POST (line 8) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/payment-methods/route.ts
  constant GET (line 20) | const GET = withWorkspace(
  constant POST (line 53) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/upgrade/route.ts
  constant POST (line 21) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/billing/usage/route.ts
  constant GET (line 11) | const GET = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/import/[importId]/download/route.ts
  constant GET (line 6) | const GET = withWorkspace(async ({ workspace, params }) => {

FILE: apps/web/app/api/workspaces/[idOrSlug]/import/bitly/route.ts
  constant GET (line 14) | const GET = withWorkspace(async ({ workspace }) => {
  constant POST (line 61) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/import/csv/route.ts
  constant POST (line 13) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/import/rebrandly/route.ts
  constant GET (line 14) | const GET = withWorkspace(async ({ workspace }) => {
  constant PUT (line 80) | const PUT = withWorkspace(
  constant POST (line 95) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/import/short/route.ts
  constant GET (line 14) | const GET = withWorkspace(async ({ workspace }) => {
  constant PUT (line 67) | const PUT = withWorkspace(
  constant POST (line 79) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/invites/accept/route.ts
  constant POST (line 11) | const POST = withSession(async ({ session, params }) => {

FILE: apps/web/app/api/workspaces/[idOrSlug]/invites/decline/route.ts
  constant POST (line 7) | const POST = withSession(async ({ session, params }) => {

FILE: apps/web/app/api/workspaces/[idOrSlug]/invites/reset/route.ts
  constant POST (line 6) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/invites/route.ts
  constant GET (line 19) | const GET = withWorkspace(
  constant POST (line 49) | const POST = withWorkspace(
  constant PATCH (line 180) | const PATCH = withWorkspace(
  constant DELETE (line 225) | const DELETE = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/notification-preferences/route.ts
  constant GET (line 6) | const GET = withWorkspace(async ({ workspace, session }) => {

FILE: apps/web/app/api/workspaces/[idOrSlug]/route.ts
  constant GET (line 42) | const GET = withWorkspace(
  constant PATCH (line 80) | const PATCH = withWorkspace(
  constant PUT (line 241) | const PUT = PATCH;
  constant DELETE (line 244) | const DELETE = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/saml/route.ts
  constant GET (line 30) | const GET = withWorkspace(
  constant POST (line 56) | const POST = withWorkspace(
  constant DELETE (line 100) | const DELETE = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/scim/route.ts
  constant GET (line 17) | const GET = withWorkspace(
  constant POST (line 43) | const POST = withWorkspace(
  constant DELETE (line 70) | const DELETE = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/upload-url/route.ts
  constant POST (line 12) | const POST = withWorkspace(

FILE: apps/web/app/api/workspaces/[idOrSlug]/users/route.ts
  constant GET (line 16) | const GET = withWorkspace(
  constant PATCH (line 60) | const PATCH = withWorkspace(
  constant DELETE (line 95) | const DELETE = withWorkspace(

FILE: apps/web/app/api/workspaces/route.ts
  constant GET (line 19) | const GET = withSession(async ({ session }) => {
  constant POST (line 61) | const POST = withSession(async ({ req, session }) => {

FILE: apps/web/app/app.dub.co/(auth)/auth/confirm-email-change/[token]/page-client.tsx
  function ConfirmEmailChangePageClient (line 9) | async function ConfirmEmailChangePageClient({

FILE: apps/web/app/app.dub.co/(auth)/auth/confirm-email-change/[token]/page.tsx
  type PageProps (line 14) | interface PageProps {
  function ConfirmEmailChangePage (line 19) | async function ConfirmEmailChangePage(props: PageProps) {

FILE: apps/web/app/app.dub.co/(auth)/auth/reset-password/[token]/page.tsx
  type Props (line 7) | interface Props {
  function ResetPasswordPage (line 13) | async function ResetPasswordPage(props: Props) {

FILE: apps/web/app/app.dub.co/(auth)/auth/saml/form.tsx
  function SAMLForm (line 8) | function SAMLForm() {

FILE: apps/web/app/app.dub.co/(auth)/auth/saml/page.tsx
  function SAMLPage (line 7) | function SAMLPage() {

FILE: apps/web/app/app.dub.co/(auth)/customer-logos.tsx
  constant CUSTOMER_LOGOS (line 5) | const CUSTOMER_LOGOS: { name: string; src: string; className?: string }[...
  function CustomerLogos (line 30) | function CustomerLogos() {

FILE: apps/web/app/app.dub.co/(auth)/forgot-password/page.tsx
  function ForgotPasswordPage (line 9) | function ForgotPasswordPage() {

FILE: apps/web/app/app.dub.co/(auth)/invites/[code]/page.tsx
  function InvitesPage (line 11) | async function InvitesPage(props: {
  function VerifyInvite (line 34) | async function VerifyInvite({ code }: { code: string }) {

FILE: apps/web/app/app.dub.co/(auth)/layout.tsx
  function AuthLayout (line 7) | function AuthLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(auth)/login/page.tsx
  function LoginPage (line 12) | function LoginPage() {

FILE: apps/web/app/app.dub.co/(auth)/oauth/authorize/loading.tsx
  function AuthorizeLoading (line 4) | function AuthorizeLoading() {

FILE: apps/web/app/app.dub.co/(auth)/oauth/authorize/page.tsx
  function Authorize (line 21) | async function Authorize(props: {

FILE: apps/web/app/app.dub.co/(auth)/oauth/authorize/scopes-requested.tsx
  type ScopesProps (line 7) | interface ScopesProps {

FILE: apps/web/app/app.dub.co/(auth)/register/page-client.tsx
  function RegisterPageClient (line 13) | function RegisterPageClient() {
  function SignUp (line 21) | function SignUp() {
  function Verify (line 53) | function Verify() {

FILE: apps/web/app/app.dub.co/(auth)/register/page.tsx
  function RegisterPage (line 10) | function RegisterPage() {

FILE: apps/web/app/app.dub.co/(auth)/side-panel.tsx
  function SidePanel (line 5) | function SidePanel() {

FILE: apps/web/app/app.dub.co/(auth)/unsubscribe/[token]/page.tsx
  function UnsubscribePage (line 13) | async function UnsubscribePage(props: {

FILE: apps/web/app/app.dub.co/(auth)/unsubscribe/[token]/unsubscribe-form.tsx
  type PreferenceState (line 15) | type PreferenceState = Record<NotificationPreferenceType, boolean>;
  constant NOTIFICATION_ICONS (line 17) | const NOTIFICATION_ICONS: Record<
  function UnsubscribeForm (line 26) | function UnsubscribeForm({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/[customerId]/earnings/page-client.tsx
  function CustomerEarningsPageClient (line 16) | function CustomerEarningsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/[customerId]/earnings/page.tsx
  function CustomerEarningsPage (line 3) | function CustomerEarningsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/[customerId]/layout.tsx
  function CustomerLayout (line 27) | function CustomerLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/[customerId]/sales/page-client.tsx
  function CustomerSalesPageClient (line 13) | function CustomerSalesPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/[customerId]/sales/page.tsx
  function CustomerSalesPage (line 3) | function CustomerSalesPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/page-client.tsx
  function CustomersPageClient (line 3) | function CustomersPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/customers/page.tsx
  function CustomersPage (line 6) | function CustomersPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/events/page.tsx
  function WorkspaceAnalyticsEvents (line 8) | function WorkspaceAnalyticsEvents() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/analytics-chart.tsx
  function AnalyticsChart (line 13) | function AnalyticsChart() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/analytics-partners-table.tsx
  function AnalyticsPartnersTable (line 27) | function AnalyticsPartnersTable() {
  function PartnerTableSkeleton (line 231) | function PartnerTableSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/analytics-timeseries-chart.tsx
  function AnalyticsTimeseriesChart (line 14) | function AnalyticsTimeseriesChart({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/page-client.tsx
  function ProgramAnalyticsPageClient (line 30) | function ProgramAnalyticsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/page.tsx
  function ProgramAnalytics (line 9) | function ProgramAnalytics() {
  function ProgramAnalyticsPageWrapper (line 26) | function ProgramAnalyticsPageWrapper() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/analytics/partner-analytics-filter-cell.tsx
  type PartnerAnalyticsFilterCellProps (line 9) | interface PartnerAnalyticsFilterCellProps {
  function PartnerAnalyticsFilterCell (line 21) | function PartnerAnalyticsFilterCell({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/auth.tsx
  function ProgramAuth (line 12) | function ProgramAuth({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-header.tsx
  function BountyHeaderTitle (line 9) | function BountyHeaderTitle() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-info.tsx
  function BountyInfo (line 20) | function BountyInfo() {
  function BountyInfoSkeleton (line 184) | function BountyInfoSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-submission-details-sheet.tsx
  type BountySubmissionDetailsSheetProps (line 54) | type BountySubmissionDetailsSheetProps = {
  function BountySubmissionDetailsSheetContent (line 61) | function BountySubmissionDetailsSheetContent({
  function BountySubmissionDetailsSheet (line 614) | function BountySubmissionDetailsSheet({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-submission-row-menu.tsx
  function BountySubmissionRowMenu (line 15) | function BountySubmissionRowMenu({
  function MenuItem (line 110) | function MenuItem({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-submissions-table.tsx
  function BountySubmissionsTable (line 51) | function BountySubmissionsTable() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/page.tsx
  function Page (line 7) | function Page() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/use-bounty-submission-filters.tsx
  function useBountySubmissionFilters (line 17) | function useBountySubmissionFilters({
  function usePartnerFilterOptions (line 168) | function usePartnerFilterOptions(search: string) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsx
  type BountySheetProps (line 50) | interface BountySheetProps {
  constant BOUNTY_TYPES (line 55) | const BOUNTY_TYPES: CardSelectorOption[] = [
  function BountySheetContent (line 68) | function BountySheetContent({ setIsOpen, bounty }: BountySheetProps) {
  function SubmissionWindowBadge (line 567) | function SubmissionWindowBadge({
  function BountySheet (line 603) | function BountySheet({
  function useBountySheet (line 625) | function useBountySheet(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-amount-input.tsx
  type BountyAmountInputProps (line 10) | interface BountyAmountInputProps {
  function BountyAmountInput (line 15) | function BountyAmountInput({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-criteria-manual-submission.tsx
  constant REWARD_TYPES (line 22) | const REWARD_TYPES = [
  type RewardType (line 33) | type RewardType = (typeof REWARD_TYPES)[number]["value"];
  constant REWARD_TYPE_COPY (line 35) | const REWARD_TYPE_COPY: Record<
  constant REWARD_VALID_BUTTON_CLASS (line 43) | const REWARD_VALID_BUTTON_CLASS =
  constant REWARD_INVALID_BUTTON_CLASS (line 45) | const REWARD_INVALID_BUTTON_CLASS =
  function BountyCriteriaManualSubmission (line 48) | function BountyCriteriaManualSubmission() {
  function RewardTypeBadge (line 352) | function RewardTypeBadge({
  function RewardValueBadge (line 376) | function RewardValueBadge({ rewardType }: { rewardType: RewardType }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-criteria-social-metrics.tsx
  type SocialMetricsVariableBonusProps (line 34) | interface SocialMetricsVariableBonusProps {
  function BountyCriteriaSocialMetrics (line 41) | function BountyCriteriaSocialMetrics() {
  function SocialMetricsIncrementalBonus (line 293) | function SocialMetricsIncrementalBonus({
  function VariableBonusAmountInput (line 472) | function VariableBonusAmountInput({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-criteria.tsx
  constant BOUNTY_SUBMISSION_TYPES (line 22) | const BOUNTY_SUBMISSION_TYPES = [
  type BountySubmissionType (line 33) | type BountySubmissionType = (typeof BOUNTY_SUBMISSION_TYPES)[number]["va...
  function BountyCriteria (line 35) | function BountyCriteria() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-form-context.tsx
  type CreateBountyInputExtended (line 6) | type CreateBountyInputExtended = CreateBountyInput & {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-logic.tsx
  function BountyLogic (line 16) | function BountyLogic({ className }: { className?: string }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/confirm-create-bounty-modal.tsx
  type ConfirmCreateBountyModalProps (line 25) | type ConfirmCreateBountyModalProps = {
  function ConfirmCreateBountyModal (line 40) | function ConfirmCreateBountyModal({
  function useConfirmCreateBountyModal (line 242) | function useConfirmCreateBountyModal(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/use-add-edit-bounty-form.ts
  constant ACCORDION_ITEMS (line 23) | const ACCORDION_ITEMS = [
  function useAddEditBountyForm (line 33) | function useAddEditBountyForm({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/bounty-action-button.tsx
  type BountyActionButtonProps (line 19) | interface BountyActionButtonProps {
  function BountyActionButton (line 25) | function BountyActionButton({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/bounty-card.tsx
  function BountyCard (line 14) | function BountyCard({ bounty }: { bounty: BountyListProps }) {
  function SubmissionsCountBadge (line 166) | function SubmissionsCountBadge({ count }: { count: number }) {
  function BountyEndedBadge (line 174) | function BountyEndedBadge({ endsAt }: { endsAt: Date }) {
  function BountyCardSkeleton (line 182) | function BountyCardSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/bounty-list.tsx
  function BountyList (line 13) | function BountyList() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/create-bounty-button.tsx
  function CreateBountyButton (line 6) | function CreateBountyButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/page.tsx
  function Page (line 6) | function Page() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-action-bar.tsx
  type CampaignActionBarProps (line 9) | interface CampaignActionBarProps extends PropsWithChildren {
  function CampaignActionBar (line 16) | function CampaignActionBar({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-controls.tsx
  type CampaignControlsProps (line 31) | interface CampaignControlsProps {
  function CampaignControls (line 35) | function CampaignControls({ campaign }: CampaignControlsProps) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-editor-skeleton.tsx
  function CampaignEditorSkeleton (line 7) | function CampaignEditorSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-editor.tsx
  function CampaignEditor (line 88) | function CampaignEditor({ campaign }: { campaign: Campaign }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-events-modal.tsx
  function CampaignEventsModal (line 14) | function CampaignEventsModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-events.tsx
  type EventStatus (line 14) | type EventStatus = "delivered" | "opened" | "bounced";
  type CampaignEvent (line 16) | type CampaignEvent = z.infer<typeof campaignEventSchema>;
  constant MAX_EVENTS (line 18) | const MAX_EVENTS = 10;
  function CampaignEvents (line 20) | function CampaignEvents() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-groups-selector.tsx
  constant MAX_DISPLAYED_GROUPS (line 10) | const MAX_DISPLAYED_GROUPS = 1;
  type CampaignGroupsSelectorProps (line 12) | interface CampaignGroupsSelectorProps {
  function CampaignGroupsSelector (line 17) | function CampaignGroupsSelector({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/campaign-metrics.tsx
  function CampaignMetrics (line 13) | function CampaignMetrics() {
  function CampaignMetricsLoadingSkeleton (line 93) | function CampaignMetricsLoadingSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/duplicate-logic-warning.tsx
  function DuplicateLogicWarning (line 14) | function DuplicateLogicWarning() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/page-client.tsx
  function ProgramCampaignPageClient (line 8) | function ProgramCampaignPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/page.tsx
  function ProgramCampaignPage (line 3) | function ProgramCampaignPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/send-email-preview-modal.tsx
  type SendEmailPreviewModalProps (line 11) | interface SendEmailPreviewModalProps {
  function SendEmailPreviewModal (line 17) | function SendEmailPreviewModal({
  function useSendEmailPreviewModal (line 130) | function useSendEmailPreviewModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/transactional-campaign-logic.tsx
  function TransactionalCampaignLogic (line 14) | function TransactionalCampaignLogic() {
  function DropdownValueInput (line 90) | function DropdownValueInput({
  function ValueInput (line 131) | function ValueInput({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/use-campaign-confirmation-modals.tsx
  type UseCampaignConfirmationModalsProps (line 15) | interface UseCampaignConfirmationModalsProps {
  function useCampaignConfirmationModals (line 19) | function useCampaignConfirmationModals({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/[campaignId]/utils.ts
  function isValidTriggerCondition (line 4) | function isValidTriggerCondition(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaign-stats.tsx
  type StatsFilterProps (line 14) | interface StatsFilterProps {
  type CampaignsCountByType (line 24) | interface CampaignsCountByType {
  function CampaignStats (line 29) | function CampaignStats() {
  function StatsFilter (line 100) | function StatsFilter({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaign-status-badges.tsx
  constant CAMPAIGN_STATUS_BADGES (line 9) | const CAMPAIGN_STATUS_BADGES = {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaign-type-badges.tsx
  constant CAMPAIGN_TYPE_BADGES (line 3) | const CAMPAIGN_TYPE_BADGES = {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaign-type-icon.tsx
  function CampaignTypeIcon (line 4) | function CampaignTypeIcon({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaigns-page-content.tsx
  function CampaignsPageContent (line 4) | function CampaignsPageContent({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaigns-table.tsx
  type PartnersCountByGroup (line 38) | interface PartnersCountByGroup {
  function CampaignsTable (line 43) | function CampaignsTable() {
  function RowMenuButton (line 210) | function RowMenuButton({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/campaigns-upsell.tsx
  function CampaignsUpsell (line 10) | function CampaignsUpsell() {
  constant EXAMPLE_CAMPAIGNS (line 55) | const EXAMPLE_CAMPAIGNS: {
  function ExampleCampaignCell (line 77) | function ExampleCampaignCell({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/create-campaign-button.tsx
  function CreateCampaignButton (line 23) | function CreateCampaignButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/delete-campaign-modal.tsx
  type DeleteCampaignModalProps (line 13) | interface DeleteCampaignModalProps {
  function useDeleteCampaignModal (line 129) | function useDeleteCampaignModal(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/layout.tsx
  function CampaignsLayout (line 9) | function CampaignsLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/page.tsx
  function ProgramCampaignsPage (line 7) | function ProgramCampaignsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/use-campaign.tsx
  function useCampaign (line 7) | function useCampaign() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/use-campaigns-count.tsx
  type UseCampaignsCountProps (line 8) | interface UseCampaignsCountProps
  function useCampaignsCount (line 13) | function useCampaignsCount<T>({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/campaigns/use-campaigns-filters.tsx
  type CampaignsCountByType (line 12) | interface CampaignsCountByType {
  type CampaignsCountByStatus (line 17) | interface CampaignsCountByStatus {
  function useCampaignsFilters (line 22) | function useCampaignsFilters() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/coming-soon-page.tsx
  function ComingSoonPage (line 6) | function ComingSoonPage({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/[commissionId]/page-client.tsx
  function CommissionDetailsPageClient (line 38) | function CommissionDetailsPageClient() {
  function CommissionDetailsContent (line 101) | function CommissionDetailsContent({
  function CommissionActivity (line 311) | function CommissionActivity({
  function CommissionDetailSkeleton (line 510) | function CommissionDetailSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/[commissionId]/page.tsx
  function CommissionDetailsPage (line 3) | function CommissionDetailsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/commission-popover-buttons.tsx
  function CommissionPopoverButtons (line 9) | function CommissionPopoverButtons() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/commissions-stats.tsx
  function CommissionsStats (line 10) | function CommissionsStats() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/commissions-table.tsx
  function CommissionsTable (line 68) | function CommissionsTable() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/create-clawback-sheet.tsx
  type CreateClawbackSheetProps (line 18) | interface CreateClawbackSheetProps {
  type FormData (line 24) | type FormData = z.infer<typeof createClawbackSchema>;
  function CreateClawbackSheetContent (line 26) | function CreateClawbackSheetContent(
  function CreateClawbackSheet (line 235) | function CreateClawbackSheet({
  function useCreateClawbackSheet (line 247) | function useCreateClawbackSheet(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/create-commission-button.tsx
  function CreateCommissionButton (line 6) | function CreateCommissionButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/create-commission-sheet.tsx
  type CreateCommissionSheetProps (line 37) | interface CreateCommissionSheetProps {
  type FormData (line 41) | type FormData = z.infer<typeof createCommissionSchema>;
  type StripeInvoiceFromApi (line 43) | type StripeInvoiceFromApi = z.infer<typeof StripeCustomerInvoiceSchema>;
  function fetcherStripeInvoices (line 45) | async function fetcherStripeInvoices(url: string): Promise<{
  function CreateCommissionSheetContent (line 65) | function CreateCommissionSheetContent({
  function CreateCommissionSheet (line 1020) | function CreateCommissionSheet({
  function useCreateCommissionSheet (line 1035) | function useCreateCommissionSheet(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/page.tsx
  function ProgramCommissions (line 10) | function ProgramCommissions() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/commissions/use-commission-filters.tsx
  function useCommissionFilters (line 19) | function useCommissionFilters() {
  function usePartnerFilterOptions (line 188) | function usePartnerFilterOptions(search: string) {
  function useCustomerFilterOptions (line 223) | function useCustomerFilterOptions(search: string) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/(index)/layout.tsx
  function PartnerCustomersLayout (line 16) | function PartnerCustomersLayout({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/(index)/page.tsx
  function ProgramCustomersPage (line 6) | function ProgramCustomersPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/(index)/referrals/page.tsx
  function PartnerCustomersReferralsPage (line 5) | function PartnerCustomersReferralsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/[customerId]/earnings/page-client.tsx
  function CustomerEarningsPageClient (line 16) | function CustomerEarningsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/[customerId]/earnings/page.tsx
  function CustomerEarningsPage (line 3) | function CustomerEarningsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/[customerId]/layout.tsx
  function ProgramCustomerLayout (line 26) | function ProgramCustomerLayout({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/[customerId]/page.tsx
  function ProgramCustomerPage (line 4) | async function ProgramCustomerPage({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/[customerId]/sales/page-client.tsx
  function CustomerSalesPageClient (line 13) | function CustomerSalesPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/[customerId]/sales/page.tsx
  function CustomerSalesPage (line 3) | function CustomerSalesPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/customers/customers-dropdown-menu.tsx
  function CustomersDropdownMenu (line 10) | function CustomersDropdownMenu() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/example-fraud-events.tsx
  constant EXAMPLE_FRAUD_EVENTS (line 7) | const EXAMPLE_FRAUD_EVENTS: {
  type ExampleFraudEventProps (line 24) | interface ExampleFraudEventProps {
  function ExampleFraudEvents (line 30) | function ExampleFraudEvents() {
  function ExampleFraudEvent (line 43) | function ExampleFraudEvent({ event }: { event: ExampleFraudEventProps }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/fraud-group-table.tsx
  function FraudGroupTable (line 38) | function FraudGroupTable() {
  function RowMenuButton (line 410) | function RowMenuButton({ row }: { row: Row<FraudGroupProps> }) {
  function MenuItem (line 486) | function MenuItem({
  function useCurrentFraudGroup (line 526) | function useCurrentFraudGroup({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/fraud-paid-traffic-settings.tsx
  type FormData (line 24) | type FormData = z.infer<
  constant PAID_TRAFFIC_PLATFORM_ICONS (line 28) | const PAID_TRAFFIC_PLATFORM_ICONS: Record<
  type FraudPaidTrafficSettingsProps (line 41) | interface FraudPaidTrafficSettingsProps {
  function FraudPaidTrafficSettings (line 45) | function FraudPaidTrafficSettings({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/fraud-referral-source-settings.tsx
  type FormData (line 10) | type FormData = z.infer<
  type FraudReferralSourceSettingsProps (line 14) | interface FraudReferralSourceSettingsProps {
  function FraudReferralSourceSettings (line 18) | function FraudReferralSourceSettings({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/fraud-rule-toggle-settings.tsx
  type FraudRuleToggleSettingsProps (line 7) | interface FraudRuleToggleSettingsProps {
  function FraudRuleToggleSettings (line 14) | function FraudRuleToggleSettings({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/fraud-upsell.tsx
  function FraudUpsell (line 9) | function FraudUpsell() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/layout.tsx
  function FraudRiskLayout (line 9) | function FraudRiskLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/page.tsx
  function ProgramFraudRiskPage (line 7) | function ProgramFraudRiskPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/program-fraud-actions-menu.tsx
  function ProgramFraudActionsMenu (line 9) | function ProgramFraudActionsMenu() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/program-fraud-settings-button.tsx
  function ProgramFraudSettingsButton (line 6) | function ProgramFraudSettingsButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/program-fraud-settings-sheet.tsx
  constant RULES_WITH_CUSTOM_UI (line 32) | const RULES_WITH_CUSTOM_UI = new Set([
  constant TOGGLE_ONLY_RULES (line 38) | const TOGGLE_ONLY_RULES = CONFIGURABLE_FRAUD_RULES.filter(
  type ProgramFraudSettingsSheetProps (line 43) | interface ProgramFraudSettingsSheetProps {
  function ProgramFraudSettingsSheetContent (line 47) | function ProgramFraudSettingsSheetContent({
  function ProgramFraudSettingsSheet (line 226) | function ProgramFraudSettingsSheet({
  function useProgramFraudSettingsSheet (line 239) | function useProgramFraudSettingsSheet() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/resolved/page.tsx
  function ResolvedFraudGroupsPage (line 5) | async function ResolvedFraudGroupsPage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/resolved/resolved-fraud-group-table.tsx
  function ResolvedFraudGroupTable (line 27) | function ResolvedFraudGroupTable() {
  function useCurrentFraudGroup (line 313) | function useCurrentFraudGroup({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/fraud/use-fraud-group-filters.tsx
  function useFraudGroupFilters (line 13) | function useFraudGroupFilters({
  function usePartnerFilterOptions (line 123) | function usePartnerFilterOptions(search: string) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/branding/page.tsx
  function GroupBrandingPage (line 3) | function GroupBrandingPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/discounts/page.tsx
  function GroupDiscountsPage (line 3) | function GroupDiscountsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header.tsx
  function GroupHeaderTitle (line 29) | function GroupHeaderTitle() {
  function GroupHeaderTabs (line 79) | function GroupHeaderTabs() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/layout.tsx
  function GroupLayout (line 5) | function GroupLayout({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-additional-link-modal.tsx
  type AdditionalLinkFormData (line 21) | type AdditionalLinkFormData = {
  constant URL_VALIDATION_MODES (line 27) | const URL_VALIDATION_MODES = [
  function partnerLinkToFormData (line 45) | function partnerLinkToFormData(
  function formDataToPartnerLink (line 64) | function formDataToPartnerLink(
  type AddDestinationUrlModalProps (line 92) | interface AddDestinationUrlModalProps {
  function AddDestinationUrlModalContent (line 99) | function AddDestinationUrlModalContent({
  function AddDestinationUrlModal (line 399) | function AddDestinationUrlModal({
  function useAddDestinationUrlModal (line 420) | function useAddDestinationUrlModal(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/add-edit-group-default-link-sheet.tsx
  type DefaultPartnerLinkSheetProps (line 30) | interface DefaultPartnerLinkSheetProps {
  type FormData (line 35) | type FormData = z.infer<typeof createOrUpdateDefaultLinkSchema>;
  function DefaultPartnerLinkSheetContent (line 37) | function DefaultPartnerLinkSheetContent({
  function LinkSettingsCard (line 241) | function LinkSettingsCard({
  function DefaultPartnerLinkSheet (line 259) | function DefaultPartnerLinkSheet({
  function useDefaultPartnerLinkSheet (line 272) | function useDefaultPartnerLinkSheet(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/change-program-domain-modal.tsx
  type ChangeProgramDomainModalProps (line 12) | type ChangeProgramDomainModalProps = {
  function ChangeProgramDomainModal (line 19) | function ChangeProgramDomainModal(props: ChangeProgramDomainModalProps) {
  function ChangeProgramDomainModalInner (line 30) | function ChangeProgramDomainModalInner({
  function useChangeProgramDomainModal (line 150) | function useChangeProgramDomainModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/group-additional-links.tsx
  type FormData (line 29) | type FormData = Pick<
  function GroupAdditionalLinks (line 34) | function GroupAdditionalLinks() {
  function GroupAdditionalLinksForm (line 68) | function GroupAdditionalLinksForm({ group }: { group: GroupProps }) {
  function SettingsRow (line 230) | function SettingsRow({
  function LinkFormat (line 252) | function LinkFormat({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/group-default-links.tsx
  function GroupDefaultLinks (line 20) | function GroupDefaultLinks() {
  function CreateDefaultLinkButton (line 71) | function CreateDefaultLinkButton({
  function DefaultLinkPreview (line 99) | function DefaultLinkPreview({ link }: { link: PartnerGroupDefaultLink }) {
  function DefaultLinkPreviewSkeleton (line 211) | function DefaultLinkPreviewSkeleton() {
  function NoDefaultLinks (line 234) | function NoDefaultLinks() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/group-link-settings.tsx
  type FormData (line 19) | type FormData = {
  function GroupLinkSettings (line 30) | function GroupLinkSettings() {
  function GroupLinkSettingsForm (line 57) | function GroupLinkSettingsForm({ group }: { group: GroupProps }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/page.tsx
  function GroupDefaultLinksPage (line 5) | function GroupDefaultLinksPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/links/partner-link-preview.tsx
  function PartnerLinkPreview (line 8) | function PartnerLinkPreview({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/rewards/group-rewards.tsx
  constant REWARD_EVENT_DESCRIPTIONS (line 20) | const REWARD_EVENT_DESCRIPTIONS: Record<
  function GroupRewards (line 38) | function GroupRewards() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/rewards/page.tsx
  function GroupRewardsPage (line 3) | function GroupRewardsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/settings/group-additional-settings.tsx
  type FormData (line 22) | type FormData = z.infer<typeof updateGroupSchema>;
  function GroupAdditionalSettings (line 24) | function GroupAdditionalSettings() {
  function GroupAdditionalSettingsForm (line 31) | function GroupAdditionalSettingsForm({
  function ConfirmAutoApproveModal (line 281) | function ConfirmAutoApproveModal({
  function ConfirmHoldingPeriodModal (line 348) | function ConfirmHoldingPeriodModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/settings/group-move-rules.tsx
  constant ATTRIBUTES (line 20) | const ATTRIBUTES = [
  type Attribute (line 27) | type Attribute = (typeof ATTRIBUTES)[number];
  type AttributeType (line 28) | type AttributeType = (typeof ATTRIBUTES)[number]["type"];
  type RangeValue (line 29) | type RangeValue = { min: number; max?: number };
  type ValueType (line 30) | type ValueType = number | RangeValue | undefined;
  constant ATTRIBUTE_BY_KEY (line 32) | const ATTRIBUTE_BY_KEY = Object.fromEntries(
  constant RANGE_SELECTOR_OPTIONS (line 36) | const RANGE_SELECTOR_OPTIONS = [
  function GroupMoveRules (line 41) | function GroupMoveRules() {
  function GroupRule (line 143) | function GroupRule({
  function GroupMoveTarget (line 297) | function GroupMoveTarget() {
  function NoGroupRule (line 327) | function NoGroupRule() {
  function GroupMoveRuleUpsell (line 338) | function GroupMoveRuleUpsell() {
  function ValueInput (line 360) | function ValueInput({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/settings/group-settings.tsx
  type FormData (line 23) | type FormData = z.input<typeof updateGroupSchema>;
  constant GROUP_NAME_DESCRIPTION (line 25) | const GROUP_NAME_DESCRIPTION =
  constant GROUP_SLUG_DESCRIPTION (line 27) | const GROUP_SLUG_DESCRIPTION =
  constant GROUP_ID_DESCRIPTION (line 29) | const GROUP_ID_DESCRIPTION =
  function GroupSettings (line 32) | function GroupSettings() {
  function GroupSettingsForm (line 37) | function GroupSettingsForm({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/settings/page.tsx
  function GroupSettingsPage (line 4) | function GroupSettingsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/create-group-button.tsx
  function CreateGroupButton (line 10) | function CreateGroupButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/create-group-modal.tsx
  type CreateGroupModalProps (line 16) | interface CreateGroupModalProps {
  type FormData (line 20) | type FormData = z.input<typeof createGroupSchema>;
  function CreateGroupModalContent (line 22) | function CreateGroupModalContent({ setIsOpen }: CreateGroupModalProps) {
  function CreateGroupModal (line 163) | function CreateGroupModal({
  function useCreateGroupModal (line 176) | function useCreateGroupModal(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/groups-table.tsx
  function GroupsTable (line 53) | function GroupsTable() {
  function RowMenuButton (line 244) | function RowMenuButton({
  function MenuItem (line 369) | function MenuItem({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/page.tsx
  function ProgramPartnersGroups (line 6) | function ProgramPartnersGroups() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/layout.tsx
  function ProgramLayout (line 4) | function ProgramLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/[partnerId]/page-client.tsx
  function ProgramMessagesPartnerPageClient (line 30) | function ProgramMessagesPartnerPageClient() {
  function PartnerInfoSectionSkeleton (line 265) | function PartnerInfoSectionSkeleton() {
  function PartnerInfoGroupSkeleton (line 282) | function PartnerInfoGroupSkeleton() {
  function PartnerInfoStatsSkeleton (line 294) | function PartnerInfoStatsSkeleton({ className }: { className?: string }) {
  function ViewPartnerButton (line 312) | function ViewPartnerButton({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/[partnerId]/page.tsx
  function ProgramMessagesPartnerPage (line 3) | function ProgramMessagesPartnerPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/layout.tsx
  function MessagesLayout (line 18) | function MessagesLayout({ children }: { children: ReactNode }) {
  function CapableLayout (line 30) | function CapableLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/messages-disabled.tsx
  function MessagesDisabled (line 8) | function MessagesDisabled() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/messages-upsell.tsx
  function MessagesUpsell (line 8) | function MessagesUpsell() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/page-client.tsx
  function ProgramMessagesPageClient (line 8) | function ProgramMessagesPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/page.tsx
  function ProgramMessages (line 3) | function ProgramMessages() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/network/layout.tsx
  function PartnerNetworkLayout (line 10) | function PartnerNetworkLayout({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/network/network-empty-state.tsx
  function NetworkEmptyState (line 6) | function NetworkEmptyState({
  function DemoAvatar (line 62) | function DemoAvatar(props: SVGProps<SVGSVGElement>) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/network/network-upsell.tsx
  function NetworkUpsell (line 8) | function NetworkUpsell({ contactUs }: { contactUs?: boolean }) {
  constant EXAMPLE_PARTNERS (line 47) | const EXAMPLE_PARTNERS = [
  function ExamplePartnerCell (line 70) | function ExamplePartnerCell({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/network/page-client.tsx
  function ProgramPartnerNetworkPageClient (line 62) | function ProgramPartnerNetworkPageClient() {
  function PartnerCard (line 319) | function PartnerCard({
  function ListRow (line 553) | function ListRow({
  function ListPill (line 654) | function ListPill({ icon: Icon, label }: { icon?: Icon; label: string }) {
  function useCurrentPartner (line 666) | function useCurrentPartner({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/network/page.tsx
  function ProgramPartnerNetwork (line 6) | function ProgramPartnerNetwork() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/network/use-partner-network-filters.tsx
  function usePartnerNetworkFilters (line 18) | function usePartnerNetworkFilters({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/overview-chart.tsx
  type ViewType (line 17) | type ViewType = "sales" | "leads" | "commissions";
  function OverviewChart (line 30) | function OverviewChart() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/overview-links.tsx
  function OverviewLinks (line 22) | function OverviewLinks() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/overview-tasks.tsx
  function OverviewTasks (line 11) | function OverviewTasks() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/page-client.tsx
  constant BLOCKS (line 27) | const BLOCKS = [
  function ProgramOverviewPageClient (line 37) | function ProgramOverviewPageClient() {
  function FinishSetupWrapper (line 116) | function FinishSetupWrapper({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/page.tsx
  function ProgramOverviewPage (line 5) | async function ProgramOverviewPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-graphic.tsx
  function PartnersGraphic (line 3) | function PartnersGraphic() {
  constant EXAMPLE_PARTNERS (line 16) | const EXAMPLE_PARTNERS = [
  function ExamplePartnerCell (line 47) | function ExamplePartnerCell({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-upgrade-cta.tsx
  function PartnersUpgradeCTA (line 10) | function PartnersUpgradeCTA({
  constant EXAMPLE_PARTNERS (line 77) | const EXAMPLE_PARTNERS = [
  function ExamplePartnerCell (line 108) | function ExamplePartnerCell({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/comments/page.tsx
  function ProgramPartnerCommentsPage (line 6) | function ProgramPartnerCommentsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/customers/page.tsx
  function ProgramPartnerCustomersPage (line 19) | function ProgramPartnerCustomersPage() {
  function PartnerCustomers (line 38) | function PartnerCustomers({ partner }: { partner: EnrolledPartnerProps }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx
  function ProgramPartnerLayout (line 65) | function ProgramPartnerLayout({
  function PartnerProfileButton (line 138) | function PartnerProfileButton({
  function PageControls (line 170) | function PageControls({ partner }: { partner: EnrolledPartnerProps }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page.tsx
  function ProgramPartnerLinksPage (line 28) | function ProgramPartnerLinksPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-nav.tsx
  function PartnerNav (line 17) | function PartnerNav() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-stats.tsx
  function PartnerStats (line 7) | function PartnerStats({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/payouts/page.tsx
  function ProgramPartnerPayoutsPage (line 21) | function ProgramPartnerPayoutsPage() {
  function PartnerPayouts (line 40) | function PartnerPayouts({ partner }: { partner: EnrolledPartnerProps }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/applications/applications-menu.tsx
  function ApplicationsMenu (line 13) | function ApplicationsMenu() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/applications/page-client.tsx
  function ProgramPartnersApplicationsPageClient (line 63) | function ProgramPartnersApplicationsPageClient() {
  function RowMenuButton (line 508) | function RowMenuButton({
  function useCurrentPartner (line 564) | function useCurrentPartner({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/applications/page.tsx
  function ProgramPartnersApplications (line 6) | function ProgramPartnersApplications() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/applications/rejected/page-client.tsx
  function ProgramPartnersRejectedApplicationsPageClient (line 64) | function ProgramPartnersRejectedApplicationsPageClient() {
  function PartnerRowMenuButton (line 451) | function PartnerRowMenuButton({
  function useCurrentPartner (line 528) | function useCurrentPartner({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/applications/rejected/page.tsx
  function ProgramPartnersRejectedApplications (line 5) | async function ProgramPartnersRejectedApplications(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/import-export-buttons.tsx
  function ImportExportButtons (line 15) | function ImportExportButtons() {
  function ImportOption (line 103) | function ImportOption({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/invite-partner-button.tsx
  function InvitePartnerButton (line 6) | function InvitePartnerButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/invite-partner-sheet.tsx
  type InvitePartnerSheetProps (line 42) | interface InvitePartnerSheetProps {
  type InvitePartnerFormData (line 46) | type InvitePartnerFormData = {
  type EmailContent (line 54) | type EmailContent = {
  function InvitePartnerSheetContent (line 60) | function InvitePartnerSheetContent({ setIsOpen }: InvitePartnerSheetProp...
  function EmailPreview (line 442) | function EmailPreview({
  function InvitePartnerSheet (line 671) | function InvitePartnerSheet({
  function useInvitePartnerSheet (line 684) | function useInvitePartnerSheet() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/page.tsx
  function ProgramPartners (line 7) | function ProgramPartners() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/partners-table.tsx
  function PartnersTable (line 114) | function PartnersTable() {
  function BulkActionsMenu (line 622) | function BulkActionsMenu({
  function RowMenuButton (line 690) | function RowMenuButton({
  function MenuItem (line 924) | function MenuItem({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/use-partner-filters.tsx
  function usePartnerFilters (line 12) | function usePartnerFilters(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/[payoutId]/page-client.tsx
  type PayoutActivityItem (line 52) | type PayoutActivityItem = {
  function PayoutDetailsPageClient (line 58) | function PayoutDetailsPageClient() {
  function PayoutDetailsContent (line 128) | function PayoutDetailsContent({
  function PayoutDetailsskeleton (line 479) | function PayoutDetailsskeleton() {
  function PayoutConfirmButton (line 493) | function PayoutConfirmButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/[payoutId]/page.tsx
  function PayoutDetailsPage (line 3) | function PayoutDetailsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/page-client.tsx
  function ProgramPayoutsPageClient (line 6) | function ProgramPayoutsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/page.tsx
  function ProgramPayoutsPage (line 6) | function ProgramPayoutsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/payout-paid-cell.tsx
  type PayoutPaidCellUser (line 7) | type PayoutPaidCellUser = {
  type PayoutPaidCellProps (line 14) | type PayoutPaidCellProps = {
  function PayoutPaidCell (line 20) | function PayoutPaidCell({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/payout-stats.tsx
  function PayoutStats (line 19) | function PayoutStats() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/payout-table.tsx
  function PayoutTable (line 36) | function PayoutTable() {
  function AmountRowItem (line 271) | function AmountRowItem({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/program-payout-methods.tsx
  type PayoutMethodCardProps (line 15) | interface PayoutMethodCardProps {
  function ProgramPayoutMethods (line 26) | function ProgramPayoutMethods() {
  function PayoutMethodCard (line 154) | function PayoutMethodCard({
  function ExternalPayoutMethods (line 187) | function ExternalPayoutMethods() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/program-payout-mode-section.tsx
  function ProgramPayoutModeSection (line 9) | function ProgramPayoutModeSection() {
  function WebhookInfo (line 69) | function WebhookInfo() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/program-payout-settings-button.tsx
  function ProgramPayoutSettingsButton (line 6) | function ProgramPayoutSettingsButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/program-payout-settings-sheet.tsx
  type ProgramPayoutSettingsSheetProps (line 22) | type ProgramPayoutSettingsSheetProps = {
  type FormData (line 26) | type FormData = Pick<ProgramProps, "minPayoutAmount">;
  function ProgramPayoutSettingsSheetContent (line 28) | function ProgramPayoutSettingsSheetContent({
  function ProgramPayoutSettingsSheet (line 208) | function ProgramPayoutSettingsSheet({
  function useProgramPayoutSettingsSheet (line 221) | function useProgramPayoutSettingsSheet() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/success/page-client.tsx
  function PayoutsSuccessPageClient (line 22) | function PayoutsSuccessPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/success/page.tsx
  function PayoutsSuccessPage (line 3) | function PayoutsSuccessPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/payouts/use-payout-filters.tsx
  function usePayoutFilters (line 12) | function usePayoutFilters() {
  function usePartnerFilterOptions (line 134) | function usePartnerFilterOptions(search: string) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/program-settings-row.tsx
  function SettingsRow (line 3) | function SettingsRow({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/page.tsx
  function ProgramResourcesPage (line 6) | function ProgramResourcesPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-brand-assets/add-color-modal.tsx
  type ColorModalProps (line 24) | type ColorModalProps = {
  type ColorFormData (line 35) | type ColorFormData = z.infer<typeof colorFormSchema>;
  function ColorModal (line 37) | function ColorModal(props: ColorModalProps) {
  constant DEFAULT_COLORS (line 48) | const DEFAULT_COLORS = ["#dc2626", "#84cc16", "#14b8a6", "#0ea5e9", "#d9...
  function ColorModalInner (line 50) | function ColorModalInner({
  function useColorModal (line 246) | function useColorModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-brand-assets/add-file-modal.tsx
  type FileModalProps (line 24) | type FileModalProps = {
  type FileFormData (line 36) | type FileFormData = z.infer<typeof fileFormSchema>;
  function FileModal (line 38) | function FileModal(props: FileModalProps) {
  function FileModalInner (line 49) | function FileModalInner({
  function useFileModal (line 288) | function useFileModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-brand-assets/add-link-modal.tsx
  type LinkModalProps (line 22) | type LinkModalProps = {
  type LinkFormData (line 33) | type LinkFormData = z.infer<typeof linkFormSchema>;
  function LinkModal (line 35) | function LinkModal(props: LinkModalProps) {
  function LinkModalInner (line 46) | function LinkModalInner({
  function useLinkModal (line 216) | function useLinkModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-brand-assets/add-logo-modal.tsx
  type LogoModalProps (line 24) | type LogoModalProps = {
  type LogoFormData (line 37) | type LogoFormData = z.infer<typeof logoFormSchema>;
  function LogoModal (line 39) | function LogoModal(props: LogoModalProps) {
  function LogoModalInner (line 50) | function LogoModalInner({
  function useLogoModal (line 290) | function useLogoModal({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-brand-assets/index.tsx
  function ProgramBrandAssets (line 31) | function ProgramBrandAssets() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-brand-assets/use-upload-program-resource.ts
  function useUploadProgramResource (line 6) | function useUploadProgramResource(workspaceId: string) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/resources/program-help-and-support.tsx
  type FormData (line 17) | type FormData = Pick<
  function ProgramHelpAndSupport (line 22) | function ProgramHelpAndSupport() {
  function ProgramHelpAndSupportContent (line 41) | function ProgramHelpAndSupportContent({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/invoices/page-client.tsx
  constant INVOICE_TYPES (line 21) | const INVOICE_TYPES = [
  function WorkspaceInvoicesClient (line 27) | function WorkspaceInvoicesClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/invoices/page.tsx
  function WorkspaceInvoices (line 4) | function WorkspaceInvoices() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/layout.tsx
  function BillingLayout (line 5) | function BillingLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/page.tsx
  function WorkspaceBilling (line 4) | function WorkspaceBilling() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/payment-methods.tsx
  function PaymentMethods (line 17) | function PaymentMethods() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx
  function PlanUsage (line 44) | function PlanUsage() {
  function UsageTabCard (line 272) | function UsageTabCard({
  function UsageCategory (line 464) | function UsageCategory(data: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/upgrade/adjust-usage-row.tsx
  function AdjustUsageRow (line 14) | function AdjustUsageRow({
  function UsageSlider (line 60) | function UsageSlider({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/upgrade/page-client.tsx
  constant COMPARE_FEATURE_ICONS (line 36) | const COMPARE_FEATURE_ICONS: Record<
  function WorkspaceBillingUpgradePageClient (line 49) | function WorkspaceBillingUpgradePageClient() {
  function BillingCompareSection (line 312) | function BillingCompareSection({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/upgrade/page.tsx
  function WorkspaceBillingUpgrade (line 4) | function WorkspaceBillingUpgrade() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/usage-chart.tsx
  constant BAR_COLORS (line 32) | const BAR_COLORS = [
  constant RESOURCES (line 44) | const RESOURCES = ["links", "events"] as const;
  function UsageChart (line 61) | function UsageChart() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/default/page-client.tsx
  function DubDomainsIcon (line 23) | function DubDomainsIcon(domain: string) {
  function DefaultDomains (line 44) | function DefaultDomains() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/default/page.tsx
  function DefaultDomainsPage (line 3) | function DefaultDomainsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/email/constants.ts
  constant EMAIL_DOMAIN_STATUS_TO_VARIANT (line 3) | const EMAIL_DOMAIN_STATUS_TO_VARIANT: Record<EmailDomainStatus, string> =

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/email/email-domain-card.tsx
  type EmailDomainCardProps (line 26) | interface EmailDomainCardProps {
  function EmailDomainCard (line 30) | function EmailDomainCard({ domain }: EmailDomainCardProps) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/email/email-domain-dns-records.tsx
  type EmailDomainDnsRecordsProps (line 9) | interface EmailDomainDnsRecordsProps {
  type DomainRecord (line 13) | interface DomainRecord {
  type DnsRecordsTableProps (line 28) | interface DnsRecordsTableProps {
  function DnsRecordsTable (line 36) | function DnsRecordsTable({
  function EmailDomainDnsRecords (line 171) | function EmailDomainDnsRecords({ domain }: EmailDomainDnsRecordsProps) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/email/page-client.tsx
  function EmailDomains (line 15) | function EmailDomains() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/email/page.tsx
  function EmailDomainsPage (line 3) | function EmailDomainsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/header.tsx
  function DomainsHeader (line 8) | function DomainsHeader({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/layout.tsx
  function DomainsLayout (line 6) | function DomainsLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/page-client.tsx
  function CustomDomains (line 34) | function CustomDomains() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/domains/page.tsx
  function CustomDomainsPage (line 3) | function CustomDomainsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/[integrationSlug]/loading.tsx
  function IntegrationPageLoading (line 3) | function IntegrationPageLoading() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/[integrationSlug]/manage/page.tsx
  function IntegrationManagePage (line 9) | async function IntegrationManagePage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/[integrationSlug]/page-client.tsx
  function IntegrationPageClient (line 67) | function IntegrationPageClient({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/[integrationSlug]/page.tsx
  function IntegrationPage (line 8) | async function IntegrationPage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/enabled-integrations.tsx
  function EnabledIntegrations (line 14) | function EnabledIntegrations({
  function IntegrationRow (line 63) | function IntegrationRow({ integration }: { integration: Integration }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/enabled/page.tsx
  function EnabledIntegrationsPage (line 16) | async function EnabledIntegrationsPage(props: {
  function EnabledIntegrationsPageRSC (line 35) | async function EnabledIntegrationsPageRSC({ slug }: { slug: string }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/featured-integrations.tsx
  constant FEATURED_SLUGS (line 20) | const FEATURED_SLUGS = ["make", "zapier", "stripe", "shopify"];
  function FeaturedIntegrations (line 22) | function FeaturedIntegrations({
  function CarouselNavBar (line 109) | function CarouselNavBar({
  function FeaturedIntegrationsLoader (line 170) | function FeaturedIntegrationsLoader() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/integrations-cards.tsx
  constant CATEGORY_ORDER (line 11) | const CATEGORY_ORDER = [
  constant PRESENCE_ANIMATION (line 23) | const PRESENCE_ANIMATION = {
  function IntegrationsCards (line 30) | function IntegrationsCards({
  function IntegrationsCardsLoader (line 127) | function IntegrationsCardsLoader() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/integrations-list.tsx
  function IntegrationsList (line 15) | async function IntegrationsList() {
  type IntegrationsWithInstallations (line 33) | type IntegrationsWithInstallations = (Integration & {
  function IntegrationsListRSC (line 37) | async function IntegrationsListRSC() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/layout.tsx
  function IntegrationsLayout (line 5) | function IntegrationsLayout({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/new/page.tsx
  function NewIntegrationsPage (line 6) | async function NewIntegrationsPage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/integrations/page.tsx
  function IntegrationsPage (line 5) | function IntegrationsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/members/page-client.tsx
  function WorkspaceMembersClient (line 47) | function WorkspaceMembersClient() {
  function RoleCell (line 331) | function RoleCell({
  function RowMenuButton (line 413) | function RowMenuButton({
  function MenuItem (line 491) | function MenuItem({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/members/page.tsx
  function WorkspaceMembers (line 3) | function WorkspaceMembers() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/notifications/layout.tsx
  function NotificationsLayout (line 5) | function NotificationsLayout({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/notifications/page-client.tsx
  type PreferenceType (line 14) | type PreferenceType = z.infer<typeof notificationTypes>;
  type Preferences (line 15) | type Preferences = Record<PreferenceType, boolean>;
  function NotificationsSettingsPageClient (line 17) | function NotificationsSettingsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/notifications/page.tsx
  function NotificationsSettingsPage (line 3) | function NotificationsSettingsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/[appId]/page-client.tsx
  function OAuthAppManagePageClient (line 23) | function OAuthAppManagePageClient({ appId }: { appId: string }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/[appId]/page.tsx
  function OAuthAppManagePage (line 3) | async function OAuthAppManagePage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/create-oauth-app-button.tsx
  function CreateOAuthAppButton (line 9) | function CreateOAuthAppButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/layout.tsx
  function OAuthAppsLayout (line 6) | function OAuthAppsLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/new/page-client.tsx
  function NewOAuthAppPageClient (line 10) | function NewOAuthAppPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/new/page.tsx
  function NewOAuthAppPage (line 3) | async function NewOAuthAppPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/page-client.tsx
  function OAuthAppsPageClient (line 12) | function OAuthAppsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/oauth-apps/page.tsx
  function OAuthAppsPage (line 3) | async function OAuthAppsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/page-client.tsx
  function WorkspaceSettingsClient (line 13) | function WorkspaceSettingsClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/page.tsx
  function WorkspaceSettings (line 5) | function WorkspaceSettings() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/security/audit-logs.tsx
  function AuditLogs (line 12) | function AuditLogs() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/security/layout.tsx
  function SecurityLayout (line 5) | function SecurityLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/security/page-client.tsx
  function WorkspaceSecurityClient (line 7) | function WorkspaceSecurityClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/security/page.tsx
  function WorkspaceSecurity (line 3) | function WorkspaceSecurity() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/security/saml.tsx
  function SAML (line 23) | function SAML() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/security/scim.tsx
  function SCIM (line 14) | function SCIM() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tokens/page.tsx
  function TokensPage (line 32) | function TokensPage() {
  function RowMenuButton (line 213) | function RowMenuButton({
  function MenuItem (line 270) | function MenuItem({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/add-hostname-modal.tsx
  type AddHostnameModalProps (line 121) | interface AddHostnameModalProps {
  function useAddHostnameModal (line 151) | function useAddHostnameModal() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/base-script-section.tsx
  function BaseScriptSection (line 7) | function BaseScriptSection() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/connection-instructions.tsx
  function ConnectionInstructions (line 10) | function ConnectionInstructions() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/conversion-tracking-section.tsx
  function ConversionTrackingSection (line 11) | function ConversionTrackingSection() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/conversion-tracking-toggle.tsx
  function ConversionTrackingToggle (line 18) | function ConversionTrackingToggle() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/guide.tsx
  function GuideMarkdown (line 6) | function GuideMarkdown({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/hostname-menu.tsx
  function HostnameMenu (line 6) | function HostnameMenu({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/outbound-domain-tracking-section.tsx
  function OutboundDomainTrackingSection (line 9) | function OutboundDomainTrackingSection() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/page-client.tsx
  function WorkspaceTrackingSettingsPageClient (line 144) | function WorkspaceTrackingSettingsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/page.tsx
  function WorkspaceTrackingSettingsPage (line 7) | function WorkspaceTrackingSettingsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/publishable-key-menu.tsx
  function PublishableKeyMenu (line 6) | function PublishableKeyMenu({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/site-visit-tracking-section.tsx
  function SiteVisitTrackingSection (line 12) | function SiteVisitTrackingSection() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/step.tsx
  type Step (line 10) | type Step = "connect" | "lead" | "sale";
  type BaseStepProps (line 12) | type BaseStepProps = {
  type StepProps (line 17) | type StepProps = BaseStepProps & {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/track-lead-guides-section.tsx
  function TrackLeadsGuidesSection (line 10) | function TrackLeadsGuidesSection() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/track-sales-guides-section.tsx
  function TrackSalesGuidesSection (line 11) | function TrackSalesGuidesSection() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/use-dynamic-guide.ts
  function useDynamicGuide (line 8) | function useDynamicGuide(

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/use-selected-guide.ts
  function useSelectedGuide (line 5) | function useSelectedGuide({ guides }: { guides: IntegrationGuide[] }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/tracking/verify-install.tsx
  type VerifyStatus (line 12) | type VerifyStatus = "pending" | "success" | "error";
  type VerificationResponse (line 29) | type VerificationResponse = {
  method onSuccess (line 47) | async onSuccess(response) {
  method onError (line 57) | onError({ error }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/[webhookId]/edit/page-client.tsx
  function UpdateWebhookPageClient (line 11) | function UpdateWebhookPageClient({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/[webhookId]/edit/page.tsx
  function UpdateWebhookPage (line 3) | async function UpdateWebhookPage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/[webhookId]/layout.tsx
  function WebhookLayout (line 4) | async function WebhookLayout(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/[webhookId]/page-client.tsx
  function WebhookLogsPageClient (line 15) | function WebhookLogsPageClient({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/[webhookId]/page.tsx
  function WebhookEventsPage (line 3) | async function WebhookEventsPage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/create-webhook-button.tsx
  function CreateWebhookButton (line 10) | function CreateWebhookButton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/layout.tsx
  function WebhooksLayout (line 6) | function WebhooksLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/new/page-client.tsx
  function NewWebhookPageClient (line 7) | function NewWebhookPageClient({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/new/page.tsx
  function NewWebhookPage (line 4) | async function NewWebhookPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/page-client.tsx
  function WebhooksPageClient (line 10) | function WebhooksPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/webhooks/page.tsx
  function WebhooksPage (line 3) | function WebhooksPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/analytics/client.tsx
  function AnalyticsClient (line 8) | function AnalyticsClient({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/analytics/page.tsx
  function WorkspaceAnalytics (line 7) | function WorkspaceAnalytics() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/auth.tsx
  function WorkspaceAuth (line 9) | function WorkspaceAuth({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/layout.tsx
  function WorkspaceLayout (line 4) | function WorkspaceLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/[...link]/page-client.tsx
  function LinkPageClient (line 47) | function LinkPageClient() {
  function LinkBuilder (line 93) | function LinkBuilder({ link }: { link: ExpandedLinkProps }) {
  function LoadingSkeleton (line 309) | function LoadingSkeleton() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/[...link]/page.tsx
  function LinkPage (line 4) | function LinkPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/domains/layout.tsx
  function DomainsLayout (line 6) | function DomainsLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/folders/[folderId]/members/page.tsx
  function FolderMembersPage (line 5) | async function FolderMembersPage(props: {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/folders/page-client.tsx
  function FoldersPageControls (line 87) | function FoldersPageControls() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/folders/page.tsx
  function FoldersPage (line 5) | async function FoldersPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/page-client.tsx
  function WorkspaceLinksClient (line 42) | function WorkspaceLinksClient() {
  function WorkspaceLinksPageControls (line 70) | function WorkspaceLinksPageControls() {
  function WorkspaceLinks (line 83) | function WorkspaceLinks() {
  function ImportOption (line 400) | function ImportOption({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/page.tsx
  function WorkspaceLinks (line 3) | function WorkspaceLinks() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/tags/page-client.tsx
  function WorkspaceTagsClient (line 28) | function WorkspaceTagsClient() {
  function TagsPageControls (line 105) | function TagsPageControls() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/tags/page.tsx
  function TagsPage (line 6) | function TagsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/tags/tag-card-placeholder.tsx
  function TagCardPlaceholder (line 3) | function TagCardPlaceholder() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/tags/tag-card.tsx
  function TagCard (line 32) | function TagCard({
  function TagCardKeyboardShortcuts (line 224) | function TagCardKeyboardShortcuts({

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/utm/page-client.tsx
  function WorkspaceUtmTemplatesClient (line 22) | function WorkspaceUtmTemplatesClient() {
  function UTMPageControls (line 81) | function UTMPageControls() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/utm/page.tsx
  function WorkspaceUtmTemplates (line 6) | function WorkspaceUtmTemplates() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/utm/template-card-placeholder.tsx
  function TemplateCardPlaceholder (line 3) | function TemplateCardPlaceholder() {

FILE: apps/web/app/app.dub.co/(dashboard)/[slug]/links/utm/template-card.tsx
  function TemplateCard (line 24) | function TemplateCard({
  function TemplateCardKeyboardShortcuts (line 195) | function TemplateCardKeyboardShortcuts({
  function UserTemplateAvatar (line 209) | function UserTemplateAvatar({

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/page-client.tsx
  function SettingsPageClient (line 14) | function SettingsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/page.tsx
  function SettingsPage (line 4) | function SettingsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/referrals/page-client.tsx
  function ReferralsPageClient (line 11) | function ReferralsPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/referrals/page.tsx
  function ReferralsPage (line 3) | function ReferralsPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/security/page-client.tsx
  function SecurityPageClient (line 9) | function SecurityPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/security/page.tsx
  function SecurityPage (line 5) | async function SecurityPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/tokens/page-client.tsx
  function TokensPageClient (line 12) | function TokensPageClient() {

FILE: apps/web/app/app.dub.co/(dashboard)/account/settings/tokens/page.tsx
  function TokensPage (line 5) | function TokensPage() {

FILE: apps/web/app/app.dub.co/(dashboard)/layout.tsx
  function Layout (line 14) | async function Layout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(deeplink)/deeplink/[domain]/[[...key]]/action-buttons.tsx
  function DeepLinkActionButtons (line 8) | function DeepLinkActionButtons({

FILE: apps/web/app/app.dub.co/(deeplink)/deeplink/[domain]/[[...key]]/brand-logo-badge.tsx
  function BrandLogoBadge (line 7) | function BrandLogoBadge({

FILE: apps/web/app/app.dub.co/(deeplink)/deeplink/[domain]/[[...key]]/page.tsx
  function DeepLinkPreviewPage (line 17) | async function DeepLinkPreviewPage(props: {

FILE: apps/web/app/app.dub.co/(deeplink)/deeplink/[domain]/[[...key]]/translations.ts
  type Language (line 37) | type Language = keyof typeof translations;
  function getLanguage (line 39) | function getLanguage(acceptLanguage?: string | null): Language {
  function getTranslations (line 61) | function getTranslations(language: Language) {

FILE: apps/web/app/app.dub.co/(invites)/[slug]/invite/accept-invite-button.tsx
  function AcceptInviteButton (line 10) | function AcceptInviteButton() {

FILE: apps/web/app/app.dub.co/(invites)/[slug]/invite/close-invite-button.tsx
  function CloseInviteButton (line 5) | function CloseInviteButton({

FILE: apps/web/app/app.dub.co/(invites)/[slug]/invite/page.tsx
  constant MAX_TEAM_DISPLAY (line 23) | const MAX_TEAM_DISPLAY = 4;
  function WorkspaceInvitePage (line 25) | async function WorkspaceInvitePage({
  function Hero (line 291) | function Hero({

FILE: apps/web/app/app.dub.co/(invites)/layout.tsx
  function InvitesLayout (line 3) | function InvitesLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/app.dub.co/(onboarding)/[slug]/wrapped/[year]/client.tsx
  function WrappedPageClient (line 13) | function WrappedPageClient() {

FILE: apps/web/app/app.dub.co/(onboarding)/[slug]/wrapped/[year]/page.tsx
  function WrappedPage (line 6) | async function WrappedPage(props: {

FILE: apps/web/app/app.dub.co/(onboarding)/[slug]/wrapped/page.tsx
  function WrappedParentPage (line 3) | async function WrappedParentPage(props: {

FILE: apps/web/app/app.dub.co/(onboarding)/layout.tsx
  function Layout (line 5) | function Layout({ children }: PropsWithChildren) {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/domain/custom/form.tsx
  function Form (line 8) | function Form() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/domain/custom/page.tsx
  function Custom (line 4) | function Custom() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/domain/default-domain-selector.tsx
  function DefaultDomainSelector (line 12) | function DefaultDomainSelector() {
  function DomainOption (line 64) | function DomainOption({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/domain/page.tsx
  function Domain (line 4) | function Domain() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/domain/register/form.tsx
  function Form (line 8) | function Form() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/domain/register/page.tsx
  function Register (line 8) | function Register() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/layout.tsx
  function Layout (line 6) | function Layout({ children }: PropsWithChildren) {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/plan/enterprise-link.tsx
  function EnterpriseLink (line 6) | function EnterpriseLink() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/plan/free-plan-button.tsx
  function FreePlanButton (line 8) | function FreePlanButton({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/plan/page.tsx
  function Plan (line 12) | function Plan() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/plan/plan-selector.tsx
  function PlanSelector (line 29) | function PlanSelector({ product }: { product: OnboardingProduct }) {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/products/page.tsx
  function Products (line 4) | function Products() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/products/product-selector.tsx
  function ProductSelector (line 28) | function ProductSelector() {
  function ProductOption (line 58) | function ProductOption({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/program/form.tsx
  function Form (line 14) | function Form() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/program/page-client.tsx
  function ProgramPageClient (line 9) | function ProgramPageClient({ domain }: { domain: string }) {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/program/page.tsx
  function ProgramPage (line 7) | async function ProgramPage({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/program/reward/form.tsx
  constant DEFAULT_REWARD_TYPES (line 17) | const DEFAULT_REWARD_TYPES = [
  constant PAYOUT_MODELS (line 32) | const PAYOUT_MODELS = [
  function Form (line 47) | function Form() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/program/reward/page.tsx
  function ProgramReward (line 9) | function ProgramReward() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/program/use-onboarding-program.tsx
  function useOnboardingProgram (line 5) | function useOnboardingProgram({ domain }: { domain?: string } = {}) {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/step-page.tsx
  function StepPage (line 6) | function StepPage({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/success/page-client.tsx
  function SuccessPageClient (line 31) | function SuccessPageClient({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/success/page.tsx
  function SuccessPage (line 6) | async function SuccessPage({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/workspace/form.tsx
  function Form (line 6) | function Form() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/workspace/page.tsx
  function Workspace (line 4) | function Workspace() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/later-button.tsx
  function LaterButton (line 9) | function LaterButton({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/next-button.tsx
  function NextButton (line 7) | function NextButton({

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/use-onboarding-product.ts
  constant ONBOARDING_PRODUCTS (line 6) | const ONBOARDING_PRODUCTS = ["links", "partners"] as const;
  type OnboardingProduct (line 7) | type OnboardingProduct = (typeof ONBOARDING_PRODUCTS)[number];
  function useOnboardingProduct (line 9) | function useOnboardingProduct(): OnboardingProduct {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/use-onboarding-progress.ts
  constant PRE_WORKSPACE_STEPS (line 10) | const PRE_WORKSPACE_STEPS = ["workspace"];
  function useOnboardingProgress (line 12) | function useOnboardingProgress() {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/welcome/page.tsx
  function Welcome (line 7) | function Welcome() {
  function Gradient (line 35) | function Gradient({ className }: { className?: string }) {

FILE: apps/web/app/app.dub.co/(onboarding)/onboarding/welcome/track-signup.tsx
  function TrackSignup (line 7) | function TrackSignup() {

FILE: apps/web/app/app.dub.co/(onboarding)/signed-in-hint.tsx
  function SignedInHint (line 7) | function SignedInHint() {

FILE: apps/web/app/app.dub.co/(redirects)/[slug]/domains/page.tsx
  function OldWorkspaceDomains (line 3) | async function OldWorkspaceDomains(props: {

FILE: apps/web/app/app.dub.co/(redirects)/[slug]/settings/referrals/page.tsx
  function OldWorkspaceReferrals (line 3) | function OldWorkspaceReferrals() {

FILE: apps/web/app/app.dub.co/(redirects)/[slug]/settings/tags/page.tsx
  function OldWorkspaceTags (line 3) | async function OldWorkspaceTags(props: {

FILE: apps/web/app/app.dub.co/(redirects)/analytics/page.tsx
  function OldLinksAnalytics (line 4) | async function OldLinksAnalytics(props: {

FILE: apps/web/app/app.dub.co/(redirects)/loading.tsx
  function Loading (line 3) | function Loading() {

FILE: apps/web/app/app.dub.co/(share)/share/[dashboardId]/action.ts
  function verifyPassword (line 6) | async function verifyPassword(_prevState: any, data: FormData) {

FILE: apps/web/app/app.dub.co/(share)/share/[dashboardId]/form.tsx
  function DashboardPasswordForm (line 14) | function DashboardPasswordForm() {

FILE: apps/web/app/app.dub.co/(share)/share/[dashboardId]/page.tsx
  function generateMetadata (line 13) | async function generateMetadata(props: {
  function DashboardPage (line 31) | async function DashboardPage(props: {

FILE: apps/web/app/app.dub.co/embed/support-chat/dynamic-height-messenger.tsx
  function SupportChatDynamicHeightMessenger (line 5) | function SupportChatDynamicHeightMessenger() {

FILE: apps/web/app/app.dub.co/embed/support-chat/layout.tsx
  function SupportChatEmbedLayout (line 1) | function SupportChatEmbedLayout({

FILE: apps/web/app/app.dub.co/embed/support-chat/page.tsx
  function SupportChatEmbedPage (line 6) | async function SupportChatEmbedPage(props: {

FILE: apps/web/app/app.dub.co/layout.tsx
  function AppLayout (line 7) | function AppLayout({ children }: { children: ReactNode }) {

FILE: apps/web/app/banned/page.tsx
  constant UTM_PARAMS (line 17) | const UTM_PARAMS = {
  function BannedPage (line 22) | async function BannedPage(props: {

FILE: apps/web/app/cloaked/[url]/page.tsx
  function generateMetadata (line 11) | async function generateMetadata(props: {
  function CloakedPage (line 30) | async function CloakedPage(props: {

FILE: apps/web/app/custom-uri-scheme/[url]/page.tsx
  function CustomURISchemePage (line 3) | async function CustomURISchemePage(props: {

FILE: apps/web/app/expired/[domain]/page.tsx
  constant UTM_PARAMS (line 20) | const UTM_PARAMS = {
  function ExpiredLinkPage (line 25) | async function ExpiredLinkPage(props: {

FILE: apps/web/app/inspect/[domain]/[key]/card.tsx
  function LinkInspectorCard (line 6) | function LinkInspectorCard({

FILE: apps/web/app/inspect/[domain]/[key]/page.tsx
  function generateMetadata (line 22) | async function generateMetadata(props: {
  function InspectPage (line 46) | async function InspectPage(props: {

FILE: apps/web/app/layout.tsx
  function RootLayout (line 9) | function RootLayout({

FILE: apps/web/app/manifest.ts
  function manifest (line 3) | function manifest(): MetadataRoute.Manifest {

FILE: apps/web/app/not-found-hint.tsx
  function NotFoundHint (line 8) | function NotFoundHint() {
  function NotFoundHintChild (line 16) | function NotFoundHintChild() {

FILE: apps/web/app/not-found.tsx
  function NotFound (line 6) | function NotFound() {

FILE: apps/web/app/password/[linkId]/action.ts
  function verifyPassword (line 6) | async function verifyPassword(_prevState: any, data: FormData) {

FILE: apps/web/app/password/[linkId]/form.tsx
  function Password
Copy disabled (too large) Download .json
Condensed preview — 3991 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (13,658K chars).
[
  {
    "path": ".github/workflows/apply-issue-labels-to-pr.yml",
    "chars": 2196,
    "preview": "name: \"Apply issue labels to PR\"\n\non:\n  pull_request_target:\n    types:\n      - opened\n\njobs:\n  label_on_pr:\n    runs-on"
  },
  {
    "path": ".github/workflows/deploy-embed-script.yml",
    "chars": 891,
    "preview": "name: \"Deploy embed script\"\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"packages/embeds/core/**\"\n  workf"
  },
  {
    "path": ".github/workflows/e2e.yaml",
    "chars": 1274,
    "preview": "name: Public API Tests\n\non:\n  deployment_status:\n\njobs:\n  api-tests:\n    timeout-minutes: 30\n    if: github.event_name ="
  },
  {
    "path": ".github/workflows/playwright.yaml",
    "chars": 4288,
    "preview": "name: Playwright E2E Tests\n\non:\n  pull_request:\n    branches: [main]\n    paths:\n      - \"apps/web/**\"\n      - \"packages/"
  },
  {
    "path": ".github/workflows/prettier.yaml",
    "chars": 503,
    "preview": "name: Prettier Check\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n  workflow_dispa"
  },
  {
    "path": ".gitignore",
    "chars": 557,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\ndist/"
  },
  {
    "path": ".prettierignore",
    "chars": 45,
    "preview": "node_modules\npnpm-lock.yaml\n.next\n.turbo\ndist"
  },
  {
    "path": "LICENSE.md",
    "chars": 35090,
    "preview": "Copyright (c) 2024-present Dub Technologies, Inc.\n\nPortions of this software – namely all files that reside under the fo"
  },
  {
    "path": "README.md",
    "chars": 4881,
    "preview": "<a href=\"https://dub.co\">\n  <img alt=\"Dub is the modern, open-source link attribution platform for short links, conversi"
  },
  {
    "path": "SECURITY.md",
    "chars": 359,
    "preview": "# Security Policy\n\n## Supported Versions\n\nAll versions of Dub are currently being supported with security updates.\n\n## R"
  },
  {
    "path": "apps/web/app/(ee)/LICENSE.md",
    "chars": 2765,
    "preview": "The Dub.co Commercial License (the “Commercial License”)\nCopyright (c) 2024-present Dub Technologies, Inc\n\nWith regard t"
  },
  {
    "path": "apps/web/app/(ee)/README.md",
    "chars": 1099,
    "preview": "<!-- PROJECT LOGO -->\n<div align=\"center\">\n  <a href=\"https://dub.co/enterprise\">\n    <img src=\"https://github.com/user-"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(auth)/layout.tsx",
    "chars": 298,
    "preview": "import { Background } from \"@dub/ui\";\n\nexport default function AdminAuthLayout({\n  children,\n}: {\n  children: React.Reac"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(auth)/login/page.tsx",
    "chars": 68,
    "preview": "export { default } from \"../../../../app.dub.co/(auth)/login/page\";\n"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/analytics/page.tsx",
    "chars": 325,
    "preview": "import Analytics from \"@/ui/analytics\";\nimport LayoutLoader from \"@/ui/layout/layout-loader\";\nimport { Suspense } from \""
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/commissions/client.tsx",
    "chars": 12165,
    "preview": "\"use client\";\n\nimport { formatDateTooltip } from \"@/lib/analytics/format-date-tooltip\";\nimport { AnalyticsLoadingSpinner"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/commissions/page.tsx",
    "chars": 212,
    "preview": "import { Suspense } from \"react\";\nimport CommissionsPageClient from \"./client\";\n\nexport default async function Commissio"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/ban-link.tsx",
    "chars": 2551,
    "preview": "\"use client\";\n\nimport { LoadingSpinner } from \"@dub/ui\";\nimport { cn } from \"@dub/utils\";\nimport { useState } from \"reac"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/delete-partner-account.tsx",
    "chars": 3357,
    "preview": "\"use client\";\n\nimport { LoadingSpinner } from \"@dub/ui\";\nimport { cn } from \"@dub/utils\";\nimport { useFormStatus } from "
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/impersonate-user.tsx",
    "chars": 3097,
    "preview": "\"use client\";\n\nimport { Button, LoadingSpinner } from \"@dub/ui\";\nimport { cn } from \"@dub/utils\";\nimport { useState } fr"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/impersonate-workspace.tsx",
    "chars": 1901,
    "preview": "\"use client\";\n\nimport { LoadingSpinner } from \"@dub/ui\";\nimport { cn } from \"@dub/utils\";\nimport { useState } from \"reac"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/refresh-domain.tsx",
    "chars": 1557,
    "preview": "\"use client\";\n\nimport { LoadingSpinner } from \"@dub/ui\";\nimport { cn } from \"@dub/utils\";\nimport { useFormStatus } from "
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/reset-login-attempts.tsx",
    "chars": 1578,
    "preview": "\"use client\";\n\nimport { LoadingSpinner } from \"@dub/ui\";\nimport { cn } from \"@dub/utils\";\nimport { useFormStatus } from "
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/components/user-info.tsx",
    "chars": 6276,
    "preview": "\"use client\";\nimport { PartnerStatusBadges } from \"@/ui/partners/partner-status-badges\";\nimport { Badge, Copy, StatusBad"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/events/page.tsx",
    "chars": 546,
    "preview": "import Events from \"@/ui/analytics/events\";\nimport { EventsProvider } from \"@/ui/analytics/events/events-provider\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/layout-nav-client.tsx",
    "chars": 3553,
    "preview": "\"use client\";\n\nimport {\n  ClientOnly,\n  MaxWidthWrapper,\n  NavWordmark,\n  Popover,\n  useMediaQuery,\n} from \"@dub/ui\";\nim"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/layout.tsx",
    "chars": 416,
    "preview": "import { constructMetadata } from \"@dub/utils\";\nimport { ReactNode } from \"react\";\nimport { AdminNav } from \"./layout-na"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/links/page.tsx",
    "chars": 234,
    "preview": "import AdminLinksClient from \"app/app.dub.co/(dashboard)/[slug]/links/page-client\";\nimport { Suspense } from \"react\";\n\ne"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/page.tsx",
    "chars": 2728,
    "preview": "import { constructMetadata } from \"@dub/utils\";\nimport { BanLink } from \"./components/ban-link\";\nimport { DeletePartnerA"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/client.tsx",
    "chars": 14036,
    "preview": "\"use client\";\n\nimport { formatDateTooltip } from \"@/lib/analytics/format-date-tooltip\";\nimport { AnalyticsLoadingSpinner"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/page.tsx",
    "chars": 200,
    "preview": "import { Suspense } from \"react\";\nimport PayoutsPageClient from \"./client\";\n\nexport default async function PayoutsPage()"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/paypal/client.tsx",
    "chars": 7555,
    "preview": "\"use client\";\n\nimport type { PaypalPayoutResponse } from \"@/lib/paypal/get-pending-payouts\";\nimport { PartnerAvatar } fr"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/payouts/paypal/page.tsx",
    "chars": 218,
    "preview": "import { Suspense } from \"react\";\nimport PaypalPayoutsPageClient from \"./client\";\n\nexport default async function PaypalP"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/revenue/client.tsx",
    "chars": 5443,
    "preview": "\"use client\";\n\nimport SimpleDateRangePicker from \"@/ui/shared/simple-date-range-picker\";\nimport {\n  CrownSmall,\n  Table,"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/(dashboard)/revenue/page.tsx",
    "chars": 200,
    "preview": "import { Suspense } from \"react\";\nimport RevenuePageClient from \"./client\";\n\nexport default async function RevenuePage()"
  },
  {
    "path": "apps/web/app/(ee)/admin.dub.co/layout.tsx",
    "chars": 237,
    "preview": "\"use client\";\n\nimport { SessionProvider } from \"next-auth/react\";\nimport { ReactNode } from \"react\";\n\nexport default fun"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/analytics/route.ts",
    "chars": 482,
    "preview": "import { getAnalytics } from \"@/lib/analytics/get-analytics\";\nimport { withAdmin } from \"@/lib/auth\";\nimport { parseAnal"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/ban/route.ts",
    "chars": 1604,
    "preview": "import { deleteWorkspaceAdmin } from \"@/lib/api/workspaces/delete-workspace\";\nimport { withAdmin } from \"@/lib/auth\";\nim"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/commissions/get-commissions-timeseries.ts",
    "chars": 1980,
    "preview": "import { sqlGranularityMap } from \"@/lib/planetscale/granularity\";\nimport { TZDate } from \"@date-fns/tz\";\nimport { prism"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/commissions/get-top-program-by-commissions.ts",
    "chars": 1527,
    "preview": "import { prisma } from \"@dub/prisma\";\nimport { ACME_PROGRAM_ID } from \"@dub/utils\";\n\nexport async function getTopProgram"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/commissions/route.ts",
    "chars": 1531,
    "preview": "import { getStartEndDates } from \"@/lib/analytics/utils/get-start-end-dates\";\nimport { withAdmin } from \"@/lib/auth\";\nim"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/delete-partner-account/route.ts",
    "chars": 3683,
    "preview": "import { withAdmin } from \"@/lib/auth\";\nimport { conn } from \"@/lib/planetscale\";\nimport { stripe } from \"@/lib/stripe\";"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/events/route.ts",
    "chars": 469,
    "preview": "import { getEvents } from \"@/lib/analytics/get-events\";\nimport { withAdmin } from \"@/lib/auth\";\nimport { eventsQuerySche"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/impersonate/route.ts",
    "chars": 3154,
    "preview": "import { hashToken, withAdmin } from \"@/lib/auth\";\nimport { prisma } from \"@dub/prisma\";\nimport { APP_DOMAIN, PARTNERS_D"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/links/[linkId]/route.ts",
    "chars": 553,
    "preview": "import { transformLink } from \"@/lib/api/links\";\nimport { withAdmin } from \"@/lib/auth\";\nimport { prisma } from \"@dub/pr"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/links/ban/route.ts",
    "chars": 1226,
    "preview": "import { linkCache } from \"@/lib/api/links/cache\";\nimport { withAdmin } from \"@/lib/auth\";\nimport { updateConfig } from "
  },
  {
    "path": "apps/web/app/(ee)/api/admin/links/count/route.ts",
    "chars": 1878,
    "preview": "import { withAdmin } from \"@/lib/auth\";\nimport { prisma } from \"@dub/prisma\";\nimport { DUB_DOMAINS_ARRAY, LEGAL_USER_ID "
  },
  {
    "path": "apps/web/app/(ee)/api/admin/links/route.ts",
    "chars": 1834,
    "preview": "import { transformLink } from \"@/lib/api/links\";\nimport { withAdmin } from \"@/lib/auth\";\nimport { prisma } from \"@dub/pr"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/payouts/paypal/route.ts",
    "chars": 424,
    "preview": "import { withAdmin } from \"@/lib/auth/admin\";\nimport { getPendingPaypalPayouts } from \"@/lib/paypal/get-pending-payouts\""
  },
  {
    "path": "apps/web/app/(ee)/api/admin/payouts/route.ts",
    "chars": 4140,
    "preview": "import { getStartEndDates } from \"@/lib/analytics/utils/get-start-end-dates\";\nimport { withAdmin } from \"@/lib/auth\";\nim"
  },
  {
    "path": "apps/web/app/(ee)/api/admin/refresh-domain/route.ts",
    "chars": 735,
    "preview": "import { addDomainToVercel } from \"@/lib/api/domains/add-domain-vercel\";\nimport { withAdmin } from \"@/lib/auth\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/admin/reset-login-attempts/route.ts",
    "chars": 979,
    "preview": "import { withAdmin } from \"@/lib/auth\";\nimport { prisma } from \"@dub/prisma\";\nimport { NextResponse } from \"next/server\""
  },
  {
    "path": "apps/web/app/(ee)/api/admin/revenue/get-top-programs-by-sales.ts",
    "chars": 1554,
    "preview": "import { formatUTCDateTimeClickhouse } from \"@/lib/analytics/utils/format-utc-datetime-clickhouse\";\nimport { tb } from \""
  },
  {
    "path": "apps/web/app/(ee)/api/admin/revenue/route.ts",
    "chars": 810,
    "preview": "import { getStartEndDates } from \"@/lib/analytics/utils/get-start-end-dates\";\nimport { withAdmin } from \"@/lib/auth\";\nim"
  },
  {
    "path": "apps/web/app/(ee)/api/audit-logs/export/route.ts",
    "chars": 1690,
    "preview": "import { convertToCSV } from \"@/lib/analytics/utils\";\nimport { getAuditLogs } from \"@/lib/api/audit-logs/get-audit-logs\""
  },
  {
    "path": "apps/web/app/(ee)/api/auth/saml/authorize/route.ts",
    "chars": 704,
    "preview": "import { jackson } from \"@/lib/jackson\";\nimport { getSearchParams } from \"@dub/utils\";\nimport { NextResponse } from \"nex"
  },
  {
    "path": "apps/web/app/(ee)/api/auth/saml/callback/route.ts",
    "chars": 664,
    "preview": "import { jackson } from \"@/lib/jackson\";\nimport { NextResponse } from \"next/server\";\n\nexport async function POST(req: Re"
  },
  {
    "path": "apps/web/app/(ee)/api/auth/saml/token/route.ts",
    "chars": 761,
    "preview": "import { jackson } from \"@/lib/jackson\";\nimport * as jose from \"jose\";\nimport { NextResponse } from \"next/server\";\nimpor"
  },
  {
    "path": "apps/web/app/(ee)/api/auth/saml/userinfo/route.ts",
    "chars": 461,
    "preview": "import { jackson } from \"@/lib/jackson\";\nimport { NextResponse } from \"next/server\";\n\nexport async function GET(req: Req"
  },
  {
    "path": "apps/web/app/(ee)/api/auth/saml/verify/route.tsx",
    "chars": 999,
    "preview": "import { jackson } from \"@/lib/jackson\";\nimport { prisma } from \"@dub/prisma\";\nimport { NextResponse } from \"next/server"
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/[bountyId]/route.ts",
    "chars": 10870,
    "preview": "import { recordAuditLog } from \"@/lib/api/audit-logs/record-audit-log\";\nimport { DubApiError } from \"@/lib/api/errors\";\n"
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/[bountyId]/submissions/[submissionId]/approve/route.ts",
    "chars": 1421,
    "preview": "import { getDefaultProgramIdOrThrow } from \"@/lib/api/programs/get-default-program-id-or-throw\";\nimport { parseRequestBo"
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/[bountyId]/submissions/[submissionId]/reject/route.ts",
    "chars": 1462,
    "preview": "import { getDefaultProgramIdOrThrow } from \"@/lib/api/programs/get-default-program-id-or-throw\";\nimport { parseRequestBo"
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts",
    "chars": 2241,
    "preview": "import { getDefaultProgramIdOrThrow } from \"@/lib/api/programs/get-default-program-id-or-throw\";\nimport { withWorkspace "
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/[bountyId]/sync-social-metrics/route.ts",
    "chars": 5782,
    "preview": "import { DubApiError } from \"@/lib/api/errors\";\nimport { getDefaultProgramIdOrThrow } from \"@/lib/api/programs/get-defau"
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/count/submissions/route.ts",
    "chars": 1721,
    "preview": "import { getDefaultProgramIdOrThrow } from \"@/lib/api/programs/get-default-program-id-or-throw\";\nimport { withWorkspace "
  },
  {
    "path": "apps/web/app/(ee)/api/bounties/route.ts",
    "chars": 9996,
    "preview": "import { recordAuditLog } from \"@/lib/api/audit-logs/record-audit-log\";\nimport { createId } from \"@/lib/api/create-id\";\n"
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/[campaignId]/duplicate/route.ts",
    "chars": 2602,
    "preview": "import { DEFAULT_CAMPAIGN_BODY } from \"@/lib/api/campaigns/constants\";\nimport { getCampaignOrThrow } from \"@/lib/api/cam"
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/[campaignId]/events/count/route.ts",
    "chars": 1376,
    "preview": "import { getCampaignOrThrow } from \"@/lib/api/campaigns/get-campaign-or-throw\";\nimport { getDefaultProgramIdOrThrow } fr"
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/[campaignId]/events/route.ts",
    "chars": 952,
    "preview": "import { getCampaignEvents } from \"@/lib/api/campaigns/get-campaign-events\";\nimport { getCampaignOrThrow } from \"@/lib/a"
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/[campaignId]/preview/route.ts",
    "chars": 3441,
    "preview": "import { getCampaignOrThrow } from \"@/lib/api/campaigns/get-campaign-or-throw\";\nimport { DubApiError } from \"@/lib/api/e"
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/[campaignId]/route.ts",
    "chars": 6707,
    "preview": "import { getCampaignOrThrow } from \"@/lib/api/campaigns/get-campaign-or-throw\";\nimport {\n  scheduleMarketingCampaign,\n  "
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/[campaignId]/summary/route.ts",
    "chars": 792,
    "preview": "import { getCampaignOrThrow } from \"@/lib/api/campaigns/get-campaign-or-throw\";\nimport { getCampaignSummary } from \"@/li"
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/count/route.ts",
    "chars": 2267,
    "preview": "import { getDefaultProgramIdOrThrow } from \"@/lib/api/programs/get-default-program-id-or-throw\";\nimport { withWorkspace "
  },
  {
    "path": "apps/web/app/(ee)/api/campaigns/route.ts",
    "chars": 3894,
    "preview": "import { DEFAULT_CAMPAIGN_BODY } from \"@/lib/api/campaigns/constants\";\nimport { createId } from \"@/lib/api/create-id\";\ni"
  },
  {
    "path": "apps/web/app/(ee)/api/commissions/[commissionId]/route.ts",
    "chars": 8460,
    "preview": "import { convertCurrency } from \"@/lib/analytics/convert-currency\";\nimport { recordAuditLog } from \"@/lib/api/audit-logs"
  },
  {
    "path": "apps/web/app/(ee)/api/commissions/count/route.ts",
    "chars": 899,
    "preview": "import { getCommissionsCount } from \"@/lib/api/commissions/get-commissions-count\";\nimport { getDefaultProgramIdOrThrow }"
  },
  {
    "path": "apps/web/app/(ee)/api/commissions/export/route.ts",
    "chars": 2214,
    "preview": "import { convertToCSV } from \"@/lib/analytics/utils\";\nimport { formatCommissionsForExport } from \"@/lib/api/commissions/"
  },
  {
    "path": "apps/web/app/(ee)/api/commissions/route.ts",
    "chars": 1914,
    "preview": "import { getCommissions } from \"@/lib/api/commissions/get-commissions\";\nimport { transformCustomerForCommission } from \""
  },
  {
    "path": "apps/web/app/(ee)/api/commissions/timeseries/route.ts",
    "chars": 2696,
    "preview": "import { getStartEndDates } from \"@/lib/analytics/utils/get-start-end-dates\";\nimport { getDefaultProgramIdOrThrow } from"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/aggregate-clicks/resolve-click-reward-amount.ts",
    "chars": 1236,
    "preview": "import { serializeReward } from \"@/lib/api/partners/serialize-reward\";\nimport { evaluateRewardConditions } from \"@/lib/p"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/aggregate-clicks/route.ts",
    "chars": 7198,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts",
    "chars": 6236,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/bounties/notify-partners/route.ts",
    "chars": 6712,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/bounties/queue-sync-social-metrics/route.ts",
    "chars": 1452,
    "preview": "import { enqueueBatchJobs } from \"@/lib/cron/enqueue-batch-jobs\";\nimport { withCron } from \"@/lib/cron/with-cron\";\nimpor"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/bounties/sync-social-metrics/route.ts",
    "chars": 5213,
    "preview": "import { getSocialMetricsUpdates } from \"@/lib/bounty/api/get-social-metrics-updates\";\nimport { resolveBountyDetails } f"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/campaigns/broadcast/route.ts",
    "chars": 10214,
    "preview": "import { validateCampaignFromAddress } from \"@/lib/api/campaigns/validate-campaign\";\nimport { createId } from \"@/lib/api"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/cleanup/demo-embed-partners/route.ts",
    "chars": 2339,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { bulkDeletePartners } from \"@/lib/api/partners/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/cleanup/e2e-tests/route.ts",
    "chars": 4238,
    "preview": "import { markDomainAsDeleted } from \"@/lib/api/domains/mark-domain-deleted\";\nimport { handleAndReturnErrorResponse } fro"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/cleanup/expired-tokens/route.ts",
    "chars": 1833,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/cleanup/link-retention/route.ts",
    "chars": 4031,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { qstash } from \"@/lib/cron\";\nimport { verifyQst"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts",
    "chars": 2014,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/cleanup/unenrolled-partners/route.ts",
    "chars": 1818,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { bulkDeletePartners } from \"@/lib/api/partners/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/discount-codes/create/queue-batches/route.ts",
    "chars": 3341,
    "preview": "import { CRON_BATCH_SIZE, qstash } from \"@/lib/cron\";\nimport { enqueueBatchJobs } from \"@/lib/cron/enqueue-batch-jobs\";\n"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/discount-codes/create/route.ts",
    "chars": 2317,
    "preview": "import { createDiscountCode } from \"@/lib/api/discounts/create-discount-code\";\nimport { withCron } from \"@/lib/cron/with"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/discount-codes/delete/route.ts",
    "chars": 1118,
    "preview": "import { withCron } from \"@/lib/cron/with-cron\";\nimport { disableStripeDiscountCode } from \"@/lib/stripe/disable-stripe-"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/disposable-emails/route.ts",
    "chars": 1440,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/delete/route.ts",
    "chars": 3665,
    "preview": "import { queueDomainDeletion } from \"@/lib/api/domains/queue-domain-update\";\nimport { handleAndReturnErrorResponse } fro"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/renewal-payments/route.ts",
    "chars": 4822,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/renewal-reminders/route.ts",
    "chars": 3648,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyVercelSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/transfer/route.ts",
    "chars": 3517,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { linkCache } from \"@/lib/api/links/cache\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/transfer/utils.ts",
    "chars": 1227,
    "preview": "import { sendEmail } from \"@dub/email\";\nimport DomainTransferred from \"@dub/email/templates/domain-transferred\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/update/route.ts",
    "chars": 3575,
    "preview": "import {\n  linkDomainUpdateSchema,\n  queueDomainUpdate,\n} from \"@/lib/api/domains/queue-domain-update\";\nimport { handleA"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/verify/route.ts",
    "chars": 3293,
    "preview": "import { getConfigResponse } from \"@/lib/api/domains/get-config-response\";\nimport { getDomainResponse } from \"@/lib/api/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/domains/verify/utils.ts",
    "chars": 5210,
    "preview": "import { markDomainAsDeleted } from \"@/lib/api/domains/mark-domain-deleted\";\nimport { sendBatchEmail } from \"@dub/email\""
  },
  {
    "path": "apps/web/app/(ee)/api/cron/email-domains/update/route.ts",
    "chars": 1409,
    "preview": "import { withCron } from \"@/lib/cron/with-cron\";\nimport { resend } from \"@dub/email/resend/client\";\nimport { prisma } fr"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/email-domains/verify/route.ts",
    "chars": 3320,
    "preview": "import { getWorkspaceUsers } from \"@/lib/api/get-workspace-users\";\nimport { withCron } from \"@/lib/cron/with-cron\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/commissions/fetch-commissions-batch.ts",
    "chars": 748,
    "preview": "import { getCommissions } from \"@/lib/api/commissions/get-commissions\";\nimport { getCommissionsQuerySchema } from \"@/lib"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/commissions/route.ts",
    "chars": 3286,
    "preview": "import { convertToCSV } from \"@/lib/analytics/utils/convert-to-csv\";\nimport { formatCommissionsForExport } from \"@/lib/a"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/customers/route.ts",
    "chars": 2853,
    "preview": "import { convertToCSV } from \"@/lib/analytics/utils/convert-to-csv\";\nimport { createDownloadableExport } from \"@/lib/api"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/events/fetch-events-batch.ts",
    "chars": 551,
    "preview": "import { getEvents } from \"@/lib/analytics/get-events\";\nimport { EventsFilters } from \"@/lib/analytics/types\";\n\nexport a"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/events/partner/route.ts",
    "chars": 6475,
    "preview": "import {\n  eventsExportColumnAccessors,\n  eventsExportColumnNames,\n} from \"@/lib/analytics/events-export-helpers\";\nimpor"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/events/workspace/route.ts",
    "chars": 3539,
    "preview": "import {\n  eventsExportColumnAccessors,\n  eventsExportColumnNames,\n} from \"@/lib/analytics/events-export-helpers\";\nimpor"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/links/fetch-links-batch.ts",
    "chars": 566,
    "preview": "import {\n  getLinksForWorkspace,\n  GetLinksForWorkspaceProps,\n} from \"@/lib/api/links/get-links-for-workspace\";\n\nexport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/links/route.ts",
    "chars": 4435,
    "preview": "import { convertToCSV } from \"@/lib/analytics/utils/convert-to-csv\";\nimport { getStartEndDates } from \"@/lib/analytics/u"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/partners/fetch-partners-batch.ts",
    "chars": 702,
    "preview": "import { getPartners } from \"@/lib/api/partners/get-partners\";\nimport { partnersExportQuerySchema } from \"@/lib/zod/sche"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/export/partners/route.ts",
    "chars": 3192,
    "preview": "import { convertToCSV } from \"@/lib/analytics/utils/convert-to-csv\";\nimport { createDownloadableExport } from \"@/lib/api"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/folders/delete/route.ts",
    "chars": 2391,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { queueFolderDeletion } from \"@/lib/api/folders/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/framer/backfill-leads-batch/route.ts",
    "chars": 11497,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { DubApiError, handleAndReturnErrorResponse } from \"@/lib/api/err"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/fraud/summary/route.ts",
    "chars": 5059,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { FRAUD_RULES_BY_TYPE } from \"@/lib/api/fraud/co"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/fx-rates/route.ts",
    "chars": 1446,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/groups/create-default-links/route.ts",
    "chars": 5413,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { bulkCreateLinks } from \"@/lib/api/links\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/groups/remap-default-links/route.ts",
    "chars": 8213,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { bulkCreateLinks } from \"@/lib/api/links\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/groups/remap-default-links/utils.ts",
    "chars": 2217,
    "preview": "import { Link, PartnerGroupDefaultLink } from \"@dub/prisma/client\";\nimport { normalizeUrl } from \"@dub/utils\";\n\n// Add a"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/groups/remap-discount-codes/route.ts",
    "chars": 4876,
    "preview": "import { createDiscountCode } from \"@/lib/api/discounts/create-discount-code\";\nimport { deleteDiscountCodes } from \"@/li"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/groups/sync-utm/route.ts",
    "chars": 4192,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { linkCache } from \"@/lib/api/links/cache\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/groups/update-default-links/route.ts",
    "chars": 3983,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { linkCache } from \"@/lib/api/links/cache\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/bitly/fetch-utils.ts",
    "chars": 6110,
    "preview": "/**\n * Utilities for fetching links from Bitly API\n */\n\nimport { sanitizeBitlyJson } from \"./sanitize-json\";\n\ninterface "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/bitly/queue-import.ts",
    "chars": 665,
    "preview": "import { qstash } from \"@/lib/cron\";\nimport { APP_DOMAIN_WITH_NGROK } from \"@dub/utils\";\n\n// Queue a Bitly import\nexport"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/bitly/rate-limit.ts",
    "chars": 1173,
    "preview": "import { queueBitlyImport } from \"./queue-import\";\n\n/**\n * Check if we're rate limited and handle accordingly\n */\nexport"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/bitly/route.ts",
    "chars": 3230,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { DubApiError, handleAndReturnErrorResponse } from \"@/lib/api/err"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/bitly/sanitize-json.ts",
    "chars": 1350,
    "preview": "export function sanitizeBitlyJson(body: string): string {\n  try {\n    // if body is already valid JSON, return it\n    JS"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/bitly/utils.ts",
    "chars": 7286,
    "preview": "import { bulkCreateLinks } from \"@/lib/api/links\";\nimport { redis } from \"@/lib/upstash\";\nimport { sendEmail } from \"@du"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/csv/route.ts",
    "chars": 10562,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { addDomainToVercel } from \"@/lib/api/domains/add-domain-vercel\";"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/csv/utils.ts",
    "chars": 2050,
    "preview": "import { sendEmail } from \"@dub/email\";\nimport LinksImportErrors from \"@dub/email/templates/links-import-errors\";\nimport"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/firstpromoter/route.ts",
    "chars": 1582,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/partnerstack/route.ts",
    "chars": 1703,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/rebrandly/route.ts",
    "chars": 2520,
    "preview": "import { DubApiError, handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/l"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/rebrandly/utils.ts",
    "chars": 6681,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { bulkCreateLinks } from \"@/lib/api/links\";\nimport { qstash } fro"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/rewardful/route.ts",
    "chars": 1459,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/short/route.ts",
    "chars": 1664,
    "preview": "import { DubApiError, handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/l"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/short/utils.ts",
    "chars": 5871,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { bulkCreateLinks } from \"@/lib/api/links\";\nimport { qstash } fro"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/import/tolt/route.ts",
    "chars": 1566,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/invoices/retry-failed/route.ts",
    "chars": 2394,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/links/[linkId]/complete-tests/route.ts",
    "chars": 1476,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { completeABTests } from \"@/lib/api/links/comple"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/links/delete/route.ts",
    "chars": 1049,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { deleteLink } from \"@/lib/api/links\";\nimport { "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/links/invalidate-for-discounts/route.ts",
    "chars": 2378,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { linkCache } from \"@/lib/api/links/cache\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/links/invalidate-for-partners/route.ts",
    "chars": 1380,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { linkCache } from \"@/lib/api/links/cache\";\nimpo"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/messages/notify-partner/route.ts",
    "chars": 5028,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/messages/notify-program/route.ts",
    "chars": 4879,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/network/calculate-program-similarities/calculate-category-similarity.ts",
    "chars": 1016,
    "preview": "import { prisma } from \"@dub/prisma\";\n\n// Calculate category similarity using Jaccard similarity\nexport async function c"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/network/calculate-program-similarities/calculate-partner-similarity.ts",
    "chars": 1404,
    "preview": "import { prisma } from \"@dub/prisma\";\n\ninterface PartnerSimilarityResult {\n  sharedPartnersCount: bigint;\n  program1Part"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/network/calculate-program-similarities/calculate-performance-similarity.ts",
    "chars": 1532,
    "preview": "import { prisma } from \"@dub/prisma\";\n\nconst METRIC_KEYS = [\n  \"totalClicks\",\n  \"totalLeads\",\n  \"totalConversions\",\n  \"t"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/network/calculate-program-similarities/route.ts",
    "chars": 6563,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { PROGRAM_SIMILARITY_SCORE_THRESHOLD } from \"@/l"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/network/update-partner-discoverability/route.ts",
    "chars": 2193,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { EXCLUDED_PROGRAM_IDS } from \"@/lib/constants/p"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partner-platforms/route.ts",
    "chars": 4128,
    "preview": "import {\n  AccountNotFoundError,\n  getSocialProfile,\n} from \"@/lib/api/scrape-creators/get-social-profile\";\nimport { qst"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partner-platforms/youtube/route.ts",
    "chars": 3055,
    "preview": "import { withCron } from \"@/lib/cron/with-cron\";\nimport { prisma } from \"@dub/prisma\";\nimport { PlatformType } from \"@du"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partner-platforms/youtube/youtube-channel-schema.ts",
    "chars": 751,
    "preview": "import * as z from \"zod/v4\";\n\nexport const youtubeChannelSchema = z.object({\n  id: z.string(),\n  statistics: z.object({\n"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partner-program-summary/process/route.ts",
    "chars": 9109,
    "preview": "import { getAnalytics } from \"@/lib/analytics/get-analytics\";\nimport { qstash } from \"@/lib/cron\";\nimport { withCron } f"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partner-program-summary/route.ts",
    "chars": 1527,
    "preview": "import { enqueueBatchJobs } from \"@/lib/cron/enqueue-batch-jobs\";\nimport { withCron } from \"@/lib/cron/with-cron\";\nimpor"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partners/auto-approve/route.ts",
    "chars": 3624,
    "preview": "import { getPartnerApplicationRisks } from \"@/lib/api/fraud/get-partner-application-risks\";\nimport { withCron } from \"@/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partners/auto-reject/route.ts",
    "chars": 3674,
    "preview": "import { resolveFraudGroups } from \"@/lib/api/fraud/resolve-fraud-groups\";\nimport { withCron } from \"@/lib/cron/with-cro"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partners/ban/cancel-commissions.ts",
    "chars": 1942,
    "preview": "import { prisma } from \"@dub/prisma\";\n\n// Mark the commissions as canceled\nexport async function cancelCommissions({\n  p"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partners/ban/route.ts",
    "chars": 4911,
    "preview": "import { deleteDiscountCodes } from \"@/lib/api/discounts/delete-discount-code\";\nimport { reportCrossProgramBanToNetwork "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partners/deactivate/route.ts",
    "chars": 2977,
    "preview": "import { deleteDiscountCodes } from \"@/lib/api/discounts/delete-discount-code\";\nimport { linkCache } from \"@/lib/api/lin"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/partners/merge-accounts/route.ts",
    "chars": 13322,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { resolveFraudGroups } from \"@/lib/api/fraud/res"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/aggregate-due-commissions/route.ts",
    "chars": 9574,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/balance-available/route.ts",
    "chars": 7522,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { BANK_ACCOUNT_STATUS_DESCRIPTIONS } from \"@/lib"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/charge-succeeded/queue-external-payouts.ts",
    "chars": 3964,
    "preview": "import { queueBatchEmail } from \"@/lib/email/queue-batch-email\";\nimport { sendWorkspaceWebhook } from \"@/lib/webhook/pub"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/charge-succeeded/queue-stripe-payouts.ts",
    "chars": 3390,
    "preview": "import { qstash } from \"@/lib/cron\";\nimport { prisma } from \"@dub/prisma\";\nimport { Invoice, PartnerPayoutMethod } from "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/charge-succeeded/route.ts",
    "chars": 4211,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { MIN_WITHDRAWAL_AMOUNT_CENTS } from \"@/lib/cons"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/charge-succeeded/send-paypal-payouts.ts",
    "chars": 2008,
    "preview": "import { queueBatchEmail } from \"@/lib/email/queue-batch-email\";\nimport { createPayPalBatchPayout } from \"@/lib/paypal/c"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/charge-succeeded/utils.ts",
    "chars": 2581,
    "preview": "import { qstash } from \"@/lib/cron\";\nimport { stripe } from \"@/lib/stripe\";\nimport { APP_DOMAIN_WITH_NGROK } from \"@dub/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/force-withdrawals/route.ts",
    "chars": 4143,
    "preview": "import { forceWithdrawal } from \"@/lib/actions/partners/force-withdrawal\";\nimport { handleAndReturnErrorResponse } from "
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/payout-failed/route.ts",
    "chars": 2673,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/payout-paid/route.ts",
    "chars": 2657,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/process/process-payouts.ts",
    "chars": 9169,
    "preview": "import { getPayoutEligibilityFilter } from \"@/lib/api/payouts/payout-eligibility-filter\";\nimport { FAST_ACH_FEE_CENTS, F"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/process/route.ts",
    "chars": 3079,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/process/split-payouts.ts",
    "chars": 3468,
    "preview": "import { createId } from \"@/lib/api/create-id\";\nimport { getPayoutEligibilityFilter } from \"@/lib/api/payouts/payout-eli"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/process/updates/route.ts",
    "chars": 4553,
    "preview": "import { recordAuditLog } from \"@/lib/api/audit-logs/record-audit-log\";\nimport { handleAndReturnErrorResponse } from \"@/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/reminders/partners/route.ts",
    "chars": 6460,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { MIN_PAYOUT_AMOUNT_FOR_REMINDERS } from \"@/lib/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/reminders/program-owners/route.ts",
    "chars": 6148,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { INVOICE_MIN_PAYOUT_AMOUNT_CENTS } from \"@/lib/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/payouts/send-stripe-payout/route.ts",
    "chars": 2127,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/pending-applications-summary/route.ts",
    "chars": 7259,
    "preview": "import { qstash } from \"@/lib/cron\";\nimport { withCron } from \"@/lib/cron/with-cron\";\nimport { sendBatchEmail } from \"@d"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/program-application-reminder/route.ts",
    "chars": 3196,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { qstash } from \"@/lib/cron\";\nimport { verifyQst"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/programs/deactivate/route.ts",
    "chars": 2442,
    "preview": "import { bulkDeactivatePartners } from \"@/lib/api/partners/bulk-deactivate-partners\";\nimport { CRON_BATCH_SIZE, qstash }"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/send-batch-email/route.ts",
    "chars": 5546,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/shopify/order-paid/route.ts",
    "chars": 1943,
    "preview": "import { DubApiError, handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/l"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/streams/update-partner-stats/route.ts",
    "chars": 12335,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyVercelSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/streams/update-workspace-clicks/route.ts",
    "chars": 6528,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyVercelSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts",
    "chars": 2590,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyVercelSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/usage/route.ts",
    "chars": 1052,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/usage/utils.ts",
    "chars": 6919,
    "preview": "import { getAnalytics } from \"@/lib/analytics/get-analytics\";\nimport { qstash } from \"@/lib/cron\";\nimport { sendLimitEma"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/utils.ts",
    "chars": 255,
    "preview": "export function logAndRespond(\n  message: string,\n  {\n    status = 200,\n    logLevel = \"info\",\n  }: {\n    status?: numbe"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/welcome-user/route.ts",
    "chars": 3188,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { verifyQstashSignature } from \"@/lib/cron/verif"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/workflows/[workflowId]/route.ts",
    "chars": 1688,
    "preview": "import { handleAndReturnErrorResponse } from \"@/lib/api/errors\";\nimport { executeSendCampaignWorkflow } from \"@/lib/api/"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-customers.ts",
    "chars": 1501,
    "preview": "import { isStored, storage } from \"@/lib/storage\";\nimport { prisma } from \"@dub/prisma\";\nimport { R2_URL } from \"@dub/ut"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-domains.ts",
    "chars": 1613,
    "preview": "import { removeDomainFromVercel } from \"@/lib/api/domains/remove-domain-vercel\";\nimport { prisma } from \"@dub/prisma\";\ni"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-folders.ts",
    "chars": 1069,
    "preview": "import { prisma } from \"@dub/prisma\";\nimport {\n  DeleteWorkspacePayload,\n  enqueueNextWorkspaceDeleteStep,\n} from \"./uti"
  },
  {
    "path": "apps/web/app/(ee)/api/cron/workspaces/delete/delete-workspace-links.ts",
    "chars": 1143,
    "preview": "import { bulkDeleteLinks } from \"@/lib/api/links/bulk-delete-links\";\nimport { prisma } from \"@dub/prisma\";\nimport {\n  De"
  }
]

// ... and 3791 more files (download for full content)

About this extraction

This page contains the full source code of the dubinc/dub GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 3991 files (12.1 MB), approximately 3.4M tokens, and a symbol index with 5941 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!