import { PrismaClient } from '@prisma/client'; import { hash } from 'argon2'; import { randomUUID } from 'node:crypto'; const prisma = new PrismaClient(); async function main() { await prisma.$transaction(async (tx) => { // region Users const password = await hash('12345678'); const admin = await tx.user.upsert({ where: { email: 'admin@mail.com' }, update: {}, create: { email: 'admin@mail.com', name: 'Admin user', role: 'ADMIN', password, emailConfirmedAt: new Date() } }); const huntMember = await tx.user.upsert({ where: { email: 'team@mail.com' }, update: {}, create: { email: 'team@mail.com', name: 'Hunt member', role: 'ADMIN', password, emailConfirmedAt: new Date() } }); const user = await tx.user.upsert({ where: { email: 'user@mail.com' }, update: {}, create: { email: 'user@mail.com', name: 'User', role: 'USER', password, emailConfirmedAt: new Date() } }); const teamMember = await tx.user.upsert({ where: { email: 'member@mail.com' }, update: {}, create: { email: 'member@mail.com', name: 'Team Member', role: 'USER', password, emailConfirmedAt: new Date() } }); const user2 = await tx.user.upsert({ where: { email: 'user2@mail.com' }, update: {}, create: { email: 'user2@mail.com', name: 'User2', role: 'USER', password, emailConfirmedAt: new Date() } }); const teamMember2 = await tx.user.upsert({ where: { email: 'member2@mail.com' }, update: {}, create: { email: 'member2@mail.com', name: 'Team Member2', role: 'USER', password, emailConfirmedAt: new Date() } }); const user3 = await tx.user.upsert({ where: { email: 'user3@mail.com' }, update: {}, create: { email: 'user3@mail.com', name: 'User3', role: 'USER', password, emailConfirmedAt: new Date() } }); const teamMember3 = await tx.user.upsert({ where: { email: 'member3@mail.com' }, update: {}, create: { email: 'member3@mail.com', name: 'Team Member3', role: 'USER', password, emailConfirmedAt: new Date() } }); // endregion const hunt = await tx.hunt.create({ include: { teams: true, quests: { orderBy: { order: 'asc' } } }, data: { name_de: 'Bremer Stadtrallye!', name_en: 'Bremer Stadtrallye!', description_de: 'DIE Rallye durch Bremen!', description_en: 'THE Rallye trough Bremen!', start: new Date('2025-08-23T10:00:00.000Z'), end: new Date('2025-08-30T10:00:00.000Z'), allowJoin: true, revealQuests: true, revealAnswers: false, quests: { create: [ { title_de: 'MOIN!', title_en: 'MOIN!', description_de: 'Finde das größte MOIN', description_en: 'Find the largest MOIN', question_de: 'Wo steht es?', question_en: 'Where is it?', order: 0, optional: false, pictureRequired: true, textRequired: false, textType: 'TEXT', textSolution: 'Am Herdentor', points: 10 }, { title_de: 'Die Musikanten', title_en: 'The Musikanten', description_de: 'Dort wo die vier Bremer Tiere musizieren, müsst ihr ihre Beine anfassen!', description_en: 'Where the four Bremen music animals are, you have to touch their legs!', question_de: 'Wie viele Beine haben die Musikanten zusammen?', question_en: 'How many legs do the musicians have altogether?', extraText_de: 'Mehr Punkte, je mehr unterschiedliche Beine ihr berührt!', extraText_en: 'The more different legs you touch, the more points you get!', points: 10, extraPoints: 5, pictureRequired: true, optional: false, textRequired: true, textType: 'INTEGER', textSolution: '14', order: 1 }, { title_de: 'Tolle Aussicht', title_en: 'Great view', description_de: 'Mache ein Bild aus einem Gebäude der Hochschule, von so weit oben wie möglich!', description_en: 'Take a picture of a university building from as high up as possible!', points: 10, extraPoints: 10, extraText_de: 'Wenn ihr das einzige Team in diesem Gebäude/Standort oder die Höchsten wart!', extraText_en: 'If you were the only team in that building/location or on the highest floor!', optional: false, pictureRequired: true, textRequired: false, question_de: 'In welchem Gebäude und Stockwerk wart ihr?', question_en: 'Which building and floor were you in?', textType: 'TEXT', order: 2 }, { title_de: 'Einfach mal abhauen', title_en: 'Just get away', description_de: 'Fahrt so weit ihr wollt und macht ein Foto vom Haltestellenschild!', description_en: 'Drive as far as you want and take a photo of the bus stop sign!', question_de: 'An welcher Haltestelle wart ihr?', question_en: 'Which stop were you at?', order: 3, pictureRequired: true, textRequired: true, textType: 'TEXT', points: 3, extraPoints: 30, extraText_de: 'Je weiter weg', extraText_en: 'The further away' } ] }, creatorId: admin.id, members: { create: [ { memberId: huntMember.id } ] }, teams: { create: [ { ownerId: user.id, name: 'Team 1', description: 'Das beste Informatik Team!', password: 'top secret', members: { create: [ { memberId: teamMember.id } ] } }, { ownerId: user2.id, name: 'Team 2', description: 'Das schlechteste Informatik Team!', password: 'top secret', members: { create: [ { memberId: teamMember2.id } ] } }, { ownerId: user3.id, name: 'Team 3', description: 'Das Informatik Team!', password: 'top secret', members: { create: [ { memberId: teamMember3.id } ] } } ] } } }); const team = hunt.teams[0]; const team2 = hunt.teams[1]; const team3 = hunt.teams[2]; const images = [ '/img/dummy/aussicht1.jpeg', 'https://pichunt.s3.swarm.syma.dev/0197ff6a-ce49-7000-a5b0-f32f1ee1b4ee', 'https://pichunt.s3.swarm.syma.dev/0197ff1a-3c8e-7000-8ba6-fa9c06548f82', 'https://pichunt.s3.swarm.syma.dev/0197ff5b-f74d-7000-864c-20f531481fcc', '/img/dummy/moin1.jpeg', '/img/dummy/musikanten1.jpg' ]; const reviews = [ { reviewerId: admin.id, score: 10, review: 'Schönes Bild!', internalNote: 'Wow!' }, { score: 17, reviewerId: huntMember.id, review: 'Höchstes Team, aber leider gabs andere im AB!', rankingValue: 10 }, { score: 13, reviewerId: admin.id, review: 'Ihr wart 612m weit weg!', rankingValue: 612, internalNote: '612m' }, { score: 21, reviewerId: admin.id, review: 'Ihr wart 2110m weit weg!', rankingValue: 2110, internalNote: 'Bisher am weitesten' }, { score: 18, reviewerId: huntMember.id, review: 'Ihr wart 945m weit weg!', rankingValue: 945, showcase: true } ]; const answers = await tx.questAnswer.createManyAndReturn({ data: [ { teamId: team.id, memberId: user.id, questId: hunt.quests[0].id, text: 'Am Herdentor', location: 'An der Haltestelle Herdentor', lat: 53.079138, lon: 8.809734, final: true }, { teamId: team.id, memberId: teamMember.id, questId: hunt.quests[2].id, text: 'Neustadtswall AB-Gebäude Etage 10', final: true }, { teamId: team.id, memberId: teamMember.id, questId: hunt.quests[3].id, text: 'Theater am Leibnizplatz', final: true }, { teamId: team2.id, memberId: teamMember2.id, questId: hunt.quests[3].id, text: 'Bürgerpark', final: true }, { teamId: team3.id, memberId: teamMember3.id, questId: hunt.quests[3].id, text: 'Am Brill', final: true }, { teamId: team.id, memberId: teamMember.id, questId: hunt.quests[1].id, text: '14', location: 'Marktplatz', final: false } ], select: { id: true, memberId: true } }); await Promise.all( answers.map((a, i) => tx.file.create({ data: { url: images[i], creatorId: a.memberId, uuid: randomUUID(), answers: { connect: { id: a.id } }, answerId: a.id } }) ) ); await Promise.all( reviews.map((r, i) => tx.review.create({ data: { answerId: answers[i].id, ...r } }) ) ); console.log(JSON.stringify(hunt, null, 2)); }); } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); });