diff --git a/apps/web/scripts/backfill-missing-sales.ts b/apps/web/scripts/backfill-missing-sales.ts index ba1bc9a055..3bbd995574 100644 --- a/apps/web/scripts/backfill-missing-sales.ts +++ b/apps/web/scripts/backfill-missing-sales.ts @@ -1,20 +1,27 @@ +import { getEvents } from "@/lib/analytics/get-events"; import { prisma } from "@/lib/prisma"; +import { getLeadEvent, recordSale } from "@/lib/tinybird"; +import { clickEventSchemaTB } from "@/lib/zod/schemas/clicks"; +import { nanoid } from "@dub/utils"; import "dotenv-flow/config"; +import { SaleEvent } from "dub/models/components"; import * as fs from "fs"; import * as Papa from "papaparse"; -const projectId = "xxx"; +const workspaceId = "xxx"; let customerSpend: { email: string; - spend: number; + amount: number; + date: string; }[] = []; async function main() { const customers = await prisma.customer.findMany({ where: { - projectId, + projectId: workspaceId, }, select: { + id: true, email: true, externalId: true, }, @@ -30,23 +37,85 @@ async function main() { data: { email: string; net_volume: string; + created: string; }; }) => { customerSpend.push({ email: result.data.email, - spend: parseFloat(result.data.net_volume), + amount: parseFloat(result.data.net_volume), + date: result.data.created, }); }, - complete: () => { - console.table(customerSpend); + complete: async () => { + const alreadyLogged = (await getEvents({ + workspaceId, + event: "sales", + interval: "all", + page: 1, + limit: 1000, + order: "desc", + sortBy: "timestamp", + })) as unknown as SaleEvent[]; - // overlap + const toBackfill = await Promise.all( + customerSpend.map(async (cs) => { + const customer = customers.find((c) => c.email === cs.email); + if (!customer) return null; + // if the sale has already been logged, skip + if ( + alreadyLogged.some( + (e) => e.customer["externalId"] === customer.externalId, + ) + ) + return null; - const overlap = customers.filter((c) => - customerSpend.some((cs) => cs.email === c.email), - ); + const eventId = nanoid(16); - console.table(overlap); + const leadEvent = await getLeadEvent({ + customerId: customer.id, + }); + + const clickData = clickEventSchemaTB + .omit({ timestamp: true }) + .parse(leadEvent.data[0]); + + const saleAmount = cs.amount * 100; + + const data = { + ...clickData, + timestamp: new Date(cs.date).toISOString(), + event_id: eventId, + event_name: "Subscription creation", + customer_id: customer.id, + payment_processor: "stripe", + amount: saleAmount, + currency: "usd", + invoice_id: "", + metadata: "", + }; + + const tbRes = await recordSale(data); + console.log(tbRes); + const prismaRes = prisma.link.update({ + where: { + id: clickData.link_id, + }, + data: { + sales: { + increment: 1, + }, + saleAmount: { + increment: saleAmount, + }, + }, + }); + console.log(prismaRes); + + return data; + }), + ).then((res) => res.filter(Boolean)); + + console.log(JSON.stringify(toBackfill, null, 2)); }, }); } diff --git a/apps/web/scripts/backfill-programId.ts b/apps/web/scripts/backfill-programId.ts index 051bb03bdf..ae958826fb 100644 --- a/apps/web/scripts/backfill-programId.ts +++ b/apps/web/scripts/backfill-programId.ts @@ -11,7 +11,8 @@ const enrollmentIds = [ // "cm3ghlajq00002tvj5b72vvgj", // "cm3ghqh1300012tvjbeyeo5ec", // "cm3gofygs000011simcw9kcqd", - "cm3goiy8q0000rcpha96y0vhj", + // "cm3goiy8q0000rcpha96y0vhj", + "cm2v7e3780000d1efwh8b63y5", ]; async function main() { diff --git a/apps/web/scripts/backfill-sales.ts b/apps/web/scripts/backfill-sales.ts index f30dd02a46..a5dd011ed3 100644 --- a/apps/web/scripts/backfill-sales.ts +++ b/apps/web/scripts/backfill-sales.ts @@ -5,7 +5,7 @@ import z from "@/lib/zod"; import { saleEventResponseSchema } from "@/lib/zod/schemas/sales"; import "dotenv-flow/config"; -const enrollmentId = "cm3goiy8q0000rcpha96y0vhj"; +const enrollmentId = "cm2v7e3780000d1efwh8b63y5"; async function main() { const programEnrollment = await prisma.programEnrollment.findUnique({