-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathdelete-discount-code.ts
More file actions
96 lines (86 loc) · 2.95 KB
/
Copy pathdelete-discount-code.ts
File metadata and controls
96 lines (86 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { prisma } from "@/lib/prisma";
import { APP_DOMAIN_WITH_NGROK, chunk } from "@dub/utils";
import { Discount, DiscountCode } from "@prisma/client";
import { enqueueBatchJobs } from "../cron/enqueue-batch-jobs";
type DeleteDiscountCodesParams = Pick<
DiscountCode,
"id" | "code" | "programId"
> & {
discount: Pick<Discount, "provider"> | null;
};
// Triggered in the following cases:
// 1. When a discount is deleted
// 2. When a link is deleted that has a discount code associated with it
// 3. When partners are banned / deactivated
// 4. When a partner is moved to a different group
export async function deleteDiscountCodes(
input: (DeleteDiscountCodesParams | null | undefined)[],
{ isSoftDelete = false }: { isSoftDelete?: boolean } = {},
) {
const discountCodes = input.filter(
(dc): dc is NonNullable<typeof dc> => dc != null,
);
if (discountCodes.length === 0) {
console.log(
"[deleteDiscountCodes] No discount codes to delete. Skipping...",
);
return;
}
if (isSoftDelete) {
// Soft delete the discount codes from the database (mark them as disabled)
const disabledDiscountCodes = await prisma.discountCode.updateMany({
where: {
id: {
in: discountCodes.map(({ id }) => id),
},
},
data: {
disabledAt: new Date(),
},
});
console.log(
`[deleteDiscountCodes] Disabled ${disabledDiscountCodes.count} discount codes.`,
);
} else {
// Delete the discount codes from the database
const deletedDiscountCodes = await prisma.discountCode.deleteMany({
where: {
id: {
in: discountCodes.map(({ id }) => id),
},
},
});
console.log(
`[deleteDiscountCodes] Deleted ${deletedDiscountCodes.count} discount codes.`,
);
}
// Only enqueue external-provider cleanup for codes whose provider is known.
// Orphaned codes (discount relation is null) still get deleted locally above
// but we can't tell which external provider to clean up, so we skip them.
const codesWithProvider = discountCodes.filter(
(dc): dc is typeof dc & { discount: Pick<Discount, "provider"> } =>
dc.discount != null,
);
const orphanedCount = discountCodes.length - codesWithProvider.length;
if (orphanedCount > 0) {
console.warn(
`[deleteDiscountCodes] Skipping external provider cleanup for ${orphanedCount} orphaned discount code(s) with no discount relation.`,
);
}
// Queue the job to remove the discount codes from provider
const chunks = chunk(codesWithProvider, 100);
for (const chunkOfCodes of chunks) {
await enqueueBatchJobs(
chunkOfCodes.map((discountCode) => ({
url: `${APP_DOMAIN_WITH_NGROK}/api/cron/discount-codes/disable`,
method: "POST",
queueName: "delete-discount-code",
body: {
code: discountCode.code,
programId: discountCode.programId,
provider: discountCode.discount.provider,
},
})),
);
}
}