| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #!/usr/bin/env node
- /**
- * Seed script โ injects mock data into the VidReview database.
- * Run via Docker so Prisma client binary matches the environment.
- *
- * Usage:
- * npm run seed # via package.json script
- * docker compose run --rm api npx tsx scripts/seed-mock-data.ts
- *
- * Env vars (optional, defaults work for local docker):
- * DATABASE_URL=postgresql://vidreview:vidreview123@localhost:5432/vidreview
- */
- import { PrismaClient } from '@prisma/client';
- import bcrypt from 'bcryptjs';
- const prisma = new PrismaClient();
- const BCRYPT_ROUNDS = 10;
- const PASSWORD = 'demo1234';
- async function cleanAll() {
- console.log('\n๐งน Cleaning existing data...');
- await prisma.comment.deleteMany();
- await prisma.asset.deleteMany();
- await prisma.invitation.deleteMany();
- await prisma.projectMember.deleteMany();
- await prisma.project.deleteMany();
- await prisma.user.deleteMany();
- console.log(' All tables cleared.');
- }
- async function createUser(email: string, name: string, globalRole: 'ADMIN' | 'MEMBER', projectRole?: 'ADMIN' | 'EDITOR' | 'REVIEWER' | 'VIEWER') {
- const password = await bcrypt.hash(PASSWORD, BCRYPT_ROUNDS);
- return prisma.user.create({
- data: { email, name, password, globalRole, storageQuota: 524288000, storageUsed: 0 },
- select: { id: true, email: true, name: true, globalRole: true },
- });
- }
- async function createProject(name: string, ownerId: string, editorId: string, reviewerId: string) {
- const slug = name.toLowerCase().replace(/\s+/g, '-');
- // Create project
- const project = await prisma.project.create({
- data: {
- name,
- ownerId,
- },
- });
- // Add owner as ADMIN of project
- await prisma.projectMember.create({
- data: { userId: ownerId, projectId: project.id, role: 'ADMIN', invitedBy: ownerId },
- });
- // Add editor
- await prisma.projectMember.create({
- data: { userId: editorId, projectId: project.id, role: 'EDITOR', invitedBy: ownerId },
- });
- // Add reviewer
- await prisma.projectMember.create({
- data: { userId: reviewerId, projectId: project.id, role: 'REVIEWER', invitedBy: ownerId },
- });
- return project;
- }
- async function main() {
- console.log('\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
- console.log(' VidReview โ Mock Data Seeder');
- console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n');
- await cleanAll();
- // โโ 1. Admin โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- const admin = await createUser('admin@vidreview.local', 'Admin', 'ADMIN');
- console.log(`โ
Admin created`);
- // โโ 2. Members โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- const memberDefs = [
- { email: 'alice@vidreview.local', name: 'Alice Johnson' },
- { email: 'bob@vidreview.local', name: 'Bob Smith' },
- { email: 'carol@vidreview.local', name: 'Carol White' },
- ];
- const members = await Promise.all(
- memberDefs.map(m => createUser(m.email, m.name, 'MEMBER'))
- );
- console.log(`โ
${members.length} members created`);
- // โโ 3. Projects per member โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- const projectDefs = [
- // Alice owns 3 projects
- { name: 'Brand Campaign Q2', ownerIdx: 0, editorIdx: 1, reviewerIdx: 2 },
- { name: 'Product Launch Video', ownerIdx: 0, editorIdx: 2, reviewerIdx: 1 },
- { name: 'Internal Training Clips', ownerIdx: 0, editorIdx: 1, reviewerIdx: 2 },
- // Bob owns 2 projects
- { name: 'Customer Testimonials', ownerIdx: 1, editorIdx: 0, reviewerIdx: 2 },
- { name: 'Event Highlights Reel', ownerIdx: 1, editorIdx: 2, reviewerIdx: 0 },
- // Carol owns 3 projects
- { name: 'Social Media Shorts', ownerIdx: 2, editorIdx: 0, reviewerIdx: 1 },
- { name: 'How-To Tutorial Series', ownerIdx: 2, editorIdx: 1, reviewerIdx: 0 },
- { name: 'Partner Collaboration', ownerIdx: 2, editorIdx: 0, reviewerIdx: 1 },
- ];
- const projects = await Promise.all(
- projectDefs.map(p =>
- createProject(
- p.name,
- members[p.ownerIdx].id,
- members[p.editorIdx].id,
- members[p.reviewerIdx].id,
- )
- )
- );
- console.log(`โ
${projects.length} projects created\n`);
- // โโ Output credentials table โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- const divider = 'โ'.repeat(72);
- console.log(divider);
- console.log(' ๐ Login Credentials');
- console.log(divider);
- console.log(` ${'Type'.padEnd(10)} ${'Name'.padEnd(22)} ${'Email'.padEnd(35)} Password`);
- console.log(divider);
- console.log(` ${'ADMIN'.padEnd(10)} ${admin.name.padEnd(22)} ${admin.email.padEnd(35)} ${PASSWORD}`);
- for (const m of members) {
- console.log(` ${'MEMBER'.padEnd(10)} ${m.name.padEnd(22)} ${m.email.padEnd(35)} ${PASSWORD}`);
- }
- console.log(divider);
- console.log(`\n All users have storage quota: 500 MB`);
- console.log(` Password for all accounts: ${PASSWORD}`);
- console.log('');
- console.log(' Project membership per user:');
- console.log(divider);
- for (const m of members) {
- const memberProjects = projects.filter((_, i) => projectDefs[i].ownerIdx === members.indexOf(m));
- const roleMap: Record<string, string> = {};
- for (const proj of memberProjects) {
- const def = projectDefs.find(p => p.name === proj.name)!;
- const role = members[projectDefs.findIndex(p => p.name === proj.name)].id === m.id
- ? 'owner โ project ADMIN'
- : `project ${projectDefs.findIndex(p => p.name === proj.name) < 3 ? ['EDITOR', 'REVIEWER', 'EDITOR'][projectDefs.findIndex(p => p.name === proj.name) % 3] : ['REVIEWER', 'EDITOR', 'REVIEWER'][projectDefs.findIndex(p => p.name === proj.name) % 3]}`;
- }
- const memberships = await prisma.projectMember.findMany({
- where: { userId: m.id },
- include: { project: true },
- });
- const roles = await prisma.projectMember.findMany({ where: { userId: m.id } });
- const lines = memberships.map((pm, i) => {
- const def = projectDefs.find(p => p.name === pm.project.name)!;
- const role = pm.userId === members[def.ownerIdx].id ? 'ADMIN (owner)' : roles[i].role;
- return ` โข ${pm.project.name.padEnd(30)} [${role}]`;
- });
- console.log(` ${m.name} (${m.email}):`);
- lines.forEach(l => console.log(l));
- }
- console.log(divider);
- console.log('\nโ
Done!\n');
- await prisma.$disconnect();
- }
- main().catch(err => {
- console.error('\nโ Seed failed:', err);
- process.exit(1);
- });
|