204 lines
5.8 KiB
TypeScript
204 lines
5.8 KiB
TypeScript
import { PrismaClient, BillingInterval, Role } from "@prisma/client";
|
||
import bcrypt from "bcryptjs";
|
||
import { defaultLandingContent } from "../lib/landing";
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
async function main() {
|
||
const passwordHash = await bcrypt.hash("devpassword", 10);
|
||
|
||
const admin = await prisma.user.upsert({
|
||
where: { email: "admin@akademie.local" },
|
||
update: {},
|
||
create: {
|
||
email: "admin@akademie.local",
|
||
name: "MatzeFix",
|
||
passwordHash,
|
||
role: Role.ADMIN,
|
||
},
|
||
});
|
||
|
||
const instructor = await prisma.user.upsert({
|
||
where: { email: "matze@akademie.local" },
|
||
update: {},
|
||
create: {
|
||
email: "matze@akademie.local",
|
||
name: "MatzeFix",
|
||
passwordHash,
|
||
role: Role.INSTRUCTOR,
|
||
},
|
||
});
|
||
|
||
const learner = await prisma.user.upsert({
|
||
where: { email: "lernender@akademie.local" },
|
||
update: {},
|
||
create: {
|
||
email: "lernender@akademie.local",
|
||
name: "Demo Lernender",
|
||
passwordHash,
|
||
role: Role.LEARNER,
|
||
},
|
||
});
|
||
|
||
const catKostenlos = await prisma.category.upsert({
|
||
where: { slug: "kostenlos" },
|
||
update: {},
|
||
create: { slug: "kostenlos", name: "kostenlos" },
|
||
});
|
||
const catModul1 = await prisma.category.upsert({
|
||
where: { slug: "modul-1" },
|
||
update: {},
|
||
create: { slug: "modul-1", name: "Modul 1" },
|
||
});
|
||
const catUebung = await prisma.category.upsert({
|
||
where: { slug: "uebung-der-woche" },
|
||
update: {},
|
||
create: { slug: "uebung-der-woche", name: "Übung der Woche" },
|
||
});
|
||
|
||
const courseSlug = "modul-1-die-fahrschule";
|
||
let course = await prisma.course.findUnique({ where: { slug: courseSlug } });
|
||
|
||
if (!course) {
|
||
course = await prisma.course.create({
|
||
data: {
|
||
slug: courseSlug,
|
||
title: "Modul 1 – Die Fahrschule",
|
||
description:
|
||
"Von der Fahrschulauswahl bis zu den ersten Übungen – strukturiert und praxisnah.",
|
||
published: true,
|
||
priceCents: 0,
|
||
billingInterval: BillingInterval.NONE,
|
||
ratingAverage: 4.8,
|
||
ratingCount: 12,
|
||
authorId: instructor.id,
|
||
authorName: "MatzeFix",
|
||
categories: {
|
||
create: [
|
||
{ categoryId: catKostenlos.id },
|
||
{ categoryId: catModul1.id },
|
||
],
|
||
},
|
||
modules: {
|
||
create: [
|
||
{
|
||
title: "Einstieg",
|
||
sortOrder: 0,
|
||
lessons: {
|
||
create: [
|
||
{
|
||
slug: "wie-waehle-ich-die-richtige-fahrschule-aus",
|
||
title: "Wie wähle ich die richtige Fahrschule aus?",
|
||
sortOrder: 0,
|
||
contentHtml: `
|
||
<p>Die Wahl der Fahrschule prägt deinen gesamten Lernweg. Achte auf:</p>
|
||
<ul>
|
||
<li>Kommunikation und Transparenz bei Kosten</li>
|
||
<li>Motorrad-spezifische Erfahrung der Trainer</li>
|
||
<li>Übungsflächen und realistische Sonderfahrten</li>
|
||
</ul>
|
||
`,
|
||
},
|
||
{
|
||
slug: "ausruestung-und-erste-schritte",
|
||
title: "Ausrüstung und erste Schritte",
|
||
sortOrder: 1,
|
||
contentHtml:
|
||
"<p>Helm, Handschuhe, Protektoren – passend zur Jahreszeit und zum Übungsplatz.</p>",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
{
|
||
title: "Grundlagen auf dem Platz",
|
||
sortOrder: 1,
|
||
lessons: {
|
||
create: [
|
||
{
|
||
slug: "langsames-fahren-und-balance",
|
||
title: "Langsames Fahren und Balance",
|
||
sortOrder: 0,
|
||
contentHtml:
|
||
"<p>Übe Schrittgeschwindigkeit, Kupplungsfeinfühlen und Blickführung.</p>",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
}
|
||
|
||
const demoPaidSlug = "demo-ubung-der-woche";
|
||
let paid = await prisma.course.findUnique({ where: { slug: demoPaidSlug } });
|
||
if (!paid) {
|
||
paid = await prisma.course.create({
|
||
data: {
|
||
slug: demoPaidSlug,
|
||
title: "Demo – Übung der Woche",
|
||
description: "Beispiel für wiederkehrende Inhalte (Preisfeld für späteres Abo).",
|
||
published: true,
|
||
priceCents: 2396,
|
||
billingInterval: BillingInterval.QUARTER,
|
||
ratingAverage: 4,
|
||
ratingCount: 1,
|
||
authorId: instructor.id,
|
||
authorName: "MatzeFix",
|
||
categories: {
|
||
create: [
|
||
{ categoryId: catKostenlos.id },
|
||
{ categoryId: catUebung.id },
|
||
],
|
||
},
|
||
modules: {
|
||
create: [
|
||
{
|
||
title: "Woche 1",
|
||
sortOrder: 0,
|
||
lessons: {
|
||
create: [
|
||
{
|
||
slug: "uebung-saubere-blickfuehrung",
|
||
title: "Übung: Saubere Blickführung",
|
||
sortOrder: 0,
|
||
contentHtml:
|
||
"<p>Blick früh in die Kurve, Kurveneinlage planen, ruhige Handgelenke.</p>",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
}
|
||
|
||
await prisma.enrollment.upsert({
|
||
where: {
|
||
userId_courseId: { userId: learner.id, courseId: course.id },
|
||
},
|
||
update: {},
|
||
create: { userId: learner.id, courseId: course.id },
|
||
});
|
||
|
||
await prisma.landingPage.upsert({
|
||
where: { id: "default" },
|
||
update: {},
|
||
create: {
|
||
id: "default",
|
||
content: defaultLandingContent() as object,
|
||
},
|
||
});
|
||
|
||
console.log("Seed OK:", { admin: admin.email, learner: learner.email });
|
||
}
|
||
|
||
main()
|
||
.then(() => prisma.$disconnect())
|
||
.catch(async (e) => {
|
||
console.error(e);
|
||
await prisma.$disconnect();
|
||
process.exit(1);
|
||
});
|