cal.pub0.org/scripts/seed.ts

341 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

import { MembershipRole, Prisma, PrismaClient, UserPlan } from "@prisma/client";
import dayjs from "dayjs";
import { uuid } from "short-uuid";
import { hashPassword } from "../lib/auth";
import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "../lib/availability";
const prisma = new PrismaClient();
async function createUserAndEventType(opts: {
user: {
email: string;
password: string;
username: string;
plan: UserPlan;
name: string;
completedOnboarding?: boolean;
timeZone?: string;
};
eventTypes: Array<
Prisma.EventTypeCreateInput & {
_bookings?: Prisma.BookingCreateInput[];
}
>;
}) {
const userData: Prisma.UserCreateArgs["data"] = {
...opts.user,
password: await hashPassword(opts.user.password),
emailVerified: new Date(),
completedOnboarding: opts.user.completedOnboarding ?? true,
locale: "en",
availability: {
createMany: {
data: getAvailabilityFromSchedule(DEFAULT_SCHEDULE),
},
},
};
const user = await prisma.user.upsert({
where: { email: opts.user.email },
update: userData,
create: userData,
});
console.log(
`👤 Upserted '${opts.user.username}' with email "${opts.user.email}" & password "${opts.user.password}". Booking page 👉 ${process.env.BASE_URL}/${opts.user.username}`
);
for (const eventTypeInput of opts.eventTypes) {
const { _bookings: bookingInputs = [], ...eventTypeData } = eventTypeInput;
eventTypeData.userId = user.id;
eventTypeData.users = { connect: { id: user.id } };
const eventType = await prisma.eventType.findFirst({
where: {
slug: eventTypeData.slug,
users: {
some: {
id: eventTypeData.userId,
},
},
},
select: {
id: true,
},
});
if (eventType) {
console.log(
`\t📆 Event type ${eventTypeData.slug} already seems seeded - ${process.env.BASE_URL}/${user.username}/${eventTypeData.slug}`
);
continue;
}
const { id } = await prisma.eventType.create({
data: eventTypeData,
});
console.log(
`\t📆 Event type ${eventTypeData.slug}, length ${eventTypeData.length}min - ${process.env.BASE_URL}/${user.username}/${eventTypeData.slug}`
);
for (const bookingInput of bookingInputs) {
await prisma.booking.create({
data: {
...bookingInput,
user: {
connect: {
email: opts.user.email,
},
},
attendees: {
create: {
email: opts.user.email,
name: opts.user.name,
timeZone: "Europe/London",
},
},
eventType: {
connect: {
id,
},
},
confirmed: bookingInput.confirmed,
},
});
console.log(
`\t\t☎ Created booking ${bookingInput.title} at ${new Date(
bookingInput.startTime
).toLocaleDateString()}`
);
}
}
return user;
}
async function createTeamAndAddUsers(
teamInput: Prisma.TeamCreateInput,
users: { id: number; username: string; role?: MembershipRole }[]
) {
const createTeam = async (team: Prisma.TeamCreateInput) => {
try {
return await prisma.team.create({
data: {
...team,
},
});
} catch (_err) {
if (_err instanceof Error && _err.message.indexOf("Unique constraint failed on the fields") !== -1) {
console.log(`Team '${team.name}' already exists, skipping.`);
return;
}
throw _err;
}
};
const team = await createTeam(teamInput);
if (!team) {
return;
}
console.log(`🏢 Created team '${teamInput.name}' - ${process.env.BASE_URL}/team/${team.slug}`);
for (const user of users) {
const { role = MembershipRole.OWNER, id, username } = user;
await prisma.membership.create({
data: {
teamId: team.id,
userId: id,
role: role,
accepted: true,
},
});
console.log(`\t👤 Added '${teamInput.name}' membership for '${username}' with role '${role}'`);
}
}
async function main() {
await createUserAndEventType({
user: {
email: "onboarding@example.com",
password: "onboarding",
username: "onboarding",
name: "onboarding",
plan: "TRIAL",
completedOnboarding: false,
},
eventTypes: [],
});
await createUserAndEventType({
user: {
email: "free-first-hidden@example.com",
password: "free-first-hidden",
username: "free-first-hidden",
name: "Free First Hidden Example",
plan: "FREE",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
hidden: true,
},
{
title: "60min",
slug: "60min",
length: 30,
},
],
});
await createUserAndEventType({
user: {
email: "pro@example.com",
name: "Pro Example",
password: "pro",
username: "pro",
plan: "PRO",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
_bookings: [
{
uid: uuid(),
title: "30min",
startTime: dayjs().add(1, "day").toDate(),
endTime: dayjs().add(1, "day").add(30, "minutes").toDate(),
},
{
uid: uuid(),
title: "30min",
startTime: dayjs().add(2, "day").toDate(),
endTime: dayjs().add(2, "day").add(30, "minutes").toDate(),
confirmed: false,
},
],
},
{
title: "60min",
slug: "60min",
length: 60,
},
],
});
await createUserAndEventType({
user: {
email: "trial@example.com",
password: "trial",
username: "trial",
name: "Trial Example",
plan: "TRIAL",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
},
{
title: "60min",
slug: "60min",
length: 60,
},
],
});
await createUserAndEventType({
user: {
email: "free@example.com",
password: "free",
username: "free",
name: "Free Example",
plan: "FREE",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
},
{
title: "60min",
slug: "60min",
length: 30,
},
],
});
await createUserAndEventType({
user: {
email: "usa@example.com",
password: "usa",
username: "usa",
name: "USA Timezone Example",
plan: "FREE",
timeZone: "America/Phoenix",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
},
],
});
const freeUserTeam = await createUserAndEventType({
user: {
email: "teamfree@example.com",
password: "teamfree",
username: "teamfree",
name: "Team Free Example",
plan: "FREE",
},
eventTypes: [],
});
const proUserTeam = await createUserAndEventType({
user: {
email: "teampro@example.com",
password: "teampro",
username: "teampro",
name: "Team Pro Example",
plan: "PRO",
},
eventTypes: [],
});
await createTeamAndAddUsers(
{
name: "Seeded Team",
slug: "seeded-team",
},
[
{
id: proUserTeam.id,
username: proUserTeam.name || "Unknown",
},
{
id: freeUserTeam.id,
username: freeUserTeam.name || "Unknown",
},
]
);
await prisma.$disconnect();
}
main()
.then(() => {
console.log("🌱 Seeded db");
})
.catch((e) => {
console.error(e);
process.exit(1);
});