Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const inputSchema = z.object({
programId: z.string(),
});

// POST /api/cron/partners/reactivate - reactivate partners in a program
// POST /api/cron/programs/reactivate - reactivate all partners in a program
export const POST = withCron(async ({ rawBody }) => {
const { programId } = inputSchema.parse(JSON.parse(rawBody));

Expand Down Expand Up @@ -69,7 +69,7 @@ export const POST = withCron(async ({ rawBody }) => {
// Self-queue the next batch if there are more partners to process
if (programEnrollments.length === CRON_BATCH_SIZE) {
const response = await qstash.publishJSON({
url: `${APP_DOMAIN_WITH_NGROK}/api/cron/partners/reactivate`,
url: `${APP_DOMAIN_WITH_NGROK}/api/cron/programs/reactivate`,
body: {
programId,
},
Expand Down
17 changes: 14 additions & 3 deletions apps/web/app/(ee)/api/stripe/webhook/checkout-session-completed.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { createProgram } from "@/lib/actions/partners/create-program";
import { claimDotLinkDomain } from "@/lib/api/domains/claim-dot-link-domain";
import { reactivateProgram } from "@/lib/api/programs/reactivate-program";
import { onboardingStepCache } from "@/lib/api/workspaces/onboarding-step-cache";
import { tokenCache } from "@/lib/auth/token-cache";
import { wouldGainPartnerAccess } from "@/lib/plans/has-partner-access";
import { stripe } from "@/lib/stripe";
import { WorkspaceProps } from "@/lib/types";
import { redis } from "@/lib/upstash";
Expand Down Expand Up @@ -54,7 +56,7 @@ export async function checkoutSessionCompleted(
// in the database for easy identification in future webhook events
// also update the billingCycleStart to today's date

const workspace = await prisma.project.update({
const updatedWorkspace = await prisma.project.update({
where: {
id: workspaceId,
},
Expand Down Expand Up @@ -102,14 +104,21 @@ export async function checkoutSessionCompleted(
},
});

const users = workspace.users.map(({ user }) => ({
const users = updatedWorkspace.users.map(({ user }) => ({
id: user.id,
name: user.name,
email: user.email,
}));

await Promise.allSettled([
completeOnboarding({ users, workspaceId }),
// if workspace had a program from before and is upgrading to an eligible plan, reactivate it
updatedWorkspace.defaultProgramId &&
wouldGainPartnerAccess({
currentPlan: "free",
newPlan: updatedWorkspace.plan,
}) &&
reactivateProgram(updatedWorkspace.defaultProgramId),
sendBatchEmail(
users.map((user) => ({
to: user.email as string,
Expand All @@ -135,7 +144,9 @@ export async function checkoutSessionCompleted(
}),
// expire tokens cache
tokenCache.expireMany({
hashedKeys: workspace.restrictedTokens.map(({ hashedKey }) => hashedKey),
hashedKeys: updatedWorkspace.restrictedTokens.map(
({ hashedKey }) => hashedKey,
),
}),
]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { deleteWorkspaceFolders } from "@/lib/api/folders/delete-workspace-folders";
import { deactivateProgram } from "@/lib/api/programs/deactivate-program";
import { reactivateProgram } from "@/lib/api/programs/reactivate-program";
import { tokenCache } from "@/lib/auth/token-cache";
import { qstash } from "@/lib/cron";
import { syncUserPlanToPlain } from "@/lib/plain/sync-user-plan";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import {
Expand All @@ -11,7 +11,7 @@ import {
import { WorkspaceProps } from "@/lib/types";
import { webhookCache } from "@/lib/webhook/cache";
import { prisma } from "@dub/prisma";
import { APP_DOMAIN_WITH_NGROK, getPlanAndTierFromPriceId } from "@dub/utils";
import { getPlanAndTierFromPriceId } from "@dub/utils";
import { NEW_BUSINESS_PRICE_IDS } from "@dub/utils/src";
import { waitUntil } from "@vercel/functions";

Expand Down Expand Up @@ -187,17 +187,7 @@ export async function updateWorkspacePlan({
}) &&
workspace.defaultProgramId
) {
const response = await qstash.publishJSON({
url: `${APP_DOMAIN_WITH_NGROK}/api/cron/partners/reactivate`,
body: {
programId: workspace.defaultProgramId,
},
deduplicationId: `reactivate-program-${workspace.defaultProgramId}`,
});

console.log("Reactivation job enqueued.", {
response,
});
await reactivateProgram(workspace.defaultProgramId);
}

if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ export function AnalyticsPartnersTable() {
],
pagination,
onPaginationChange: setPagination,
sortableColumns: ["clicks", "leads", "saleAmount"],
sortBy: selectedTab === "sales" ? "saleAmount" : selectedTab,
thClassName: "border-l-0",
tdClassName: "border-l-0",
Expand Down
47 changes: 47 additions & 0 deletions apps/web/lib/api/programs/reactivate-program.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { qstash } from "@/lib/cron";
import { DEFAULT_PARTNER_GROUP } from "@/lib/zod/schemas/groups";
import { prisma } from "@dub/prisma";
import { APP_DOMAIN_WITH_NGROK } from "@dub/utils";

export async function reactivateProgram(programId: string) {
if (!programId) {
throw new Error("[reactivateProgram] programId is required");
}

await prisma.$transaction([
prisma.program.update({
where: {
id: programId,
},
data: {
deactivatedAt: null,
},
}),

// republish the default group
prisma.partnerGroup.update({
where: {
programId_slug: {
programId,
slug: DEFAULT_PARTNER_GROUP.slug,
},
},
data: {
applicationFormPublishedAt: new Date(),
landerPublishedAt: new Date(),
},
}),
]);

const response = await qstash.publishJSON({
url: `${APP_DOMAIN_WITH_NGROK}/api/cron/programs/reactivate`,
body: {
programId,
},
deduplicationId: `reactivate-program-${programId}`,
});

console.log("[reactivateProgram] Reactivation job enqueued.", { response });

return response;
}
16 changes: 13 additions & 3 deletions apps/web/lib/is-generic-email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ const GENERIC_EMAIL_DOMAINS = [
"verizon.net",
"att.net",
"me.com",
"mac.com",
"msn.com",
"live.com",
"live.dk",
"web.de",
"atomicmail.io",
"protonmail.com",
"proton.me",
"pm.me",
"passinbox.com",
"passmail.net",
"163.com",
"126.com",
"duck.com",
"qq.com",
"zoho.com",
Expand All @@ -27,6 +28,10 @@ const GENERIC_EMAIL_DOMAINS = [
"tuta.com",
"privaterelay.appleid.com",
"qyver.online",
"vk.com",
"tutamail.com",
"simplelogin.com",
"volny.cz",
"naver.com",
"yeah.net",
"example.com",
Expand All @@ -39,6 +44,10 @@ const GENERIC_EMAIL_DOMAINS = [
"email.de",
"t-online.de",
"sina.com",
"foxmail.com",
"ukr.net",
"otona.uk",
"instaddr.ch",
];

const GENERIC_EMAIL_DOMAIN_PREFIXES = [
Expand All @@ -47,6 +56,7 @@ const GENERIC_EMAIL_DOMAIN_PREFIXES = [
"outlook.",
"gmx.",
"yandex.",
"live.",
];

export const isGenericEmail = (email: string) => {
Expand Down
1 change: 1 addition & 0 deletions packages/prisma/schema/fraud.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ enum FraudAlertStatus {
confirmed
dismissed
}

model FraudAlert {
id String @id @default(cuid())
partnerId String
Expand Down
4 changes: 2 additions & 2 deletions packages/prisma/schema/network.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ model DiscoveredPartner {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
partner Partner @relation(fields: [partnerId], references: [id], onDelete: Cascade)
program Program @relation(fields: [programId], references: [id], onDelete: Cascade)
partner Partner @relation(fields: [partnerId], references: [id], onDelete: Cascade)
programEnrollment ProgramEnrollment? @relation(fields: [programId, partnerId], references: [programId, partnerId])

@@unique([programId, partnerId])
Expand Down
6 changes: 3 additions & 3 deletions packages/prisma/schema/workspace.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ model Project {
referralLinkId String? @unique
referredSignups Int @default(0)

store Json? // General key-value store for things like persisting toggles, dismissing popups, etc.
store Json? // General key-value store for things like persisting toggles, dismissing popups, etc.
siteVisitTrackingSettings Json? // Site visit tracking: sitemaps, short-link domain, Site Links folder id
allowedHostnames Json?
publishableKey String? @unique // for the client-side publishable key
allowedHostnames Json?
publishableKey String? @unique // for the client-side publishable key

conversionEnabled Boolean @default(false) // Whether to enable conversion tracking for links by default
webhookEnabled Boolean @default(false)
Expand Down
Loading