init
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
password String
|
||||
name String
|
||||
phone String
|
||||
role String @default("USER") // USER or ADMIN
|
||||
createdAt DateTime @default(now())
|
||||
bookings Booking[]
|
||||
}
|
||||
|
||||
model Route {
|
||||
id Int @id @default(autoincrement())
|
||||
departureCity String
|
||||
arrivalCity String
|
||||
durationMinutes Int
|
||||
basePrice Decimal @db.Decimal(10, 2)
|
||||
createdAt DateTime @default(now())
|
||||
schedules Schedule[]
|
||||
}
|
||||
|
||||
model Schedule {
|
||||
id Int @id @default(autoincrement())
|
||||
routeId Int
|
||||
route Route @relation(fields: [routeId], references: [id], onDelete: Cascade)
|
||||
departureTime DateTime
|
||||
arrivalTime DateTime
|
||||
vehicleType String // "Toyota HiAce" or "Executive Bus"
|
||||
capacity Int
|
||||
price Decimal @db.Decimal(10, 2)
|
||||
createdAt DateTime @default(now())
|
||||
bookings Booking[]
|
||||
}
|
||||
|
||||
model Booking {
|
||||
id Int @id @default(autoincrement())
|
||||
bookingCode String @unique // e.g. "TRV-XXXXXX"
|
||||
userId Int?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
scheduleId Int
|
||||
schedule Schedule @relation(fields: [scheduleId], references: [id], onDelete: Cascade)
|
||||
passengerName String
|
||||
passengerEmail String
|
||||
passengerPhone String
|
||||
totalPrice Decimal @db.Decimal(10, 2)
|
||||
status String @default("PENDING") // PENDING, PAID, CANCELLED
|
||||
paymentMethod String?
|
||||
paymentTime DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
seats BookingSeat[]
|
||||
}
|
||||
|
||||
model BookingSeat {
|
||||
id Int @id @default(autoincrement())
|
||||
bookingId Int
|
||||
booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade)
|
||||
scheduleId Int
|
||||
seatNumber String // e.g. "1", "2A", etc.
|
||||
|
||||
@@unique([scheduleId, seatNumber])
|
||||
}
|
||||
|
||||
model SystemSetting {
|
||||
id Int @id @default(autoincrement())
|
||||
key String @unique
|
||||
value String @db.Text
|
||||
}
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
const { PrismaMariaDb } = require('@prisma/adapter-mariadb');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
dotenv.config({ override: true });
|
||||
|
||||
const adapter = new PrismaMariaDb({
|
||||
host: process.env.DB_HOST,
|
||||
port: Number(process.env.DB_PORT),
|
||||
user: process.env.DB_USERNAME,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_NAME,
|
||||
connectionLimit: 5,
|
||||
});
|
||||
|
||||
const prisma = new PrismaClient({ adapter });
|
||||
|
||||
async function main() {
|
||||
console.log('Seeding database...');
|
||||
|
||||
// 1. Clear existing data
|
||||
await prisma.bookingSeat.deleteMany({});
|
||||
await prisma.booking.deleteMany({});
|
||||
await prisma.schedule.deleteMany({});
|
||||
await prisma.route.deleteMany({});
|
||||
await prisma.user.deleteMany({});
|
||||
|
||||
console.log('Cleared existing data.');
|
||||
|
||||
// 2. Create Users
|
||||
const adminEmail = process.env.ADMIN_EMAIL || 'admin@travel.com';
|
||||
const adminPass = process.env.ADMIN_PASSWORD || 'admin123';
|
||||
const hashedPasswordAdmin = await bcrypt.hash(adminPass, 10);
|
||||
const admin = await prisma.user.create({
|
||||
data: {
|
||||
email: adminEmail,
|
||||
password: hashedPasswordAdmin,
|
||||
name: 'Super Admin',
|
||||
phone: '081234567890',
|
||||
role: 'ADMIN',
|
||||
},
|
||||
});
|
||||
|
||||
const hashedPasswordUser = await bcrypt.hash('user123', 10);
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email: 'user@travel.com',
|
||||
password: hashedPasswordUser,
|
||||
name: 'John Doe',
|
||||
phone: '089876543210',
|
||||
role: 'USER',
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Created users:', { admin: admin.email, user: user.email });
|
||||
|
||||
// 3. Create Routes
|
||||
const routesData = [
|
||||
{ departureCity: 'Jakarta', arrivalCity: 'Bandung', durationMinutes: 180, basePrice: 150000 },
|
||||
{ departureCity: 'Bandung', arrivalCity: 'Jakarta', durationMinutes: 180, basePrice: 150000 },
|
||||
{ departureCity: 'Jakarta', arrivalCity: 'Bogor', durationMinutes: 90, basePrice: 75000 },
|
||||
{ departureCity: 'Bogor', arrivalCity: 'Jakarta', durationMinutes: 90, basePrice: 75000 },
|
||||
];
|
||||
|
||||
const routes = [];
|
||||
for (const r of routesData) {
|
||||
const route = await prisma.route.create({ data: r });
|
||||
routes.push(route);
|
||||
}
|
||||
console.log(`Created ${routes.length} routes.`);
|
||||
|
||||
// 4. Create Schedules for the next 3 days
|
||||
const today = new Date();
|
||||
let schedulesCreated = 0;
|
||||
|
||||
for (let dayOffset = 0; dayOffset < 3; dayOffset++) {
|
||||
const targetDate = new Date(today);
|
||||
targetDate.setDate(today.getDate() + dayOffset);
|
||||
const dateStr = targetDate.toISOString().split('T')[0];
|
||||
|
||||
for (const route of routes) {
|
||||
// Create some schedules per route
|
||||
let hours = [];
|
||||
if (route.departureCity === 'Jakarta' && route.arrivalCity === 'Bandung') {
|
||||
hours = [7, 10, 13, 16, 19];
|
||||
} else if (route.departureCity === 'Bandung' && route.arrivalCity === 'Jakarta') {
|
||||
hours = [7, 10, 13, 16, 19];
|
||||
} else {
|
||||
hours = [8, 12, 16];
|
||||
}
|
||||
|
||||
for (let i = 0; i < hours.length; i++) {
|
||||
const hour = hours[i];
|
||||
const departureTime = new Date(`${dateStr}T${String(hour).padStart(2, '0')}:00:00.000Z`);
|
||||
const arrivalTime = new Date(departureTime.getTime() + route.durationMinutes * 60 * 1000);
|
||||
|
||||
// Alternate vehicle types
|
||||
const isHiace = i % 2 === 0;
|
||||
const vehicleType = isHiace ? 'Toyota HiAce' : 'Executive Bus';
|
||||
const capacity = isHiace ? 10 : 30;
|
||||
const price = isHiace ? Number(route.basePrice) : Number(route.basePrice) - 20000;
|
||||
|
||||
await prisma.schedule.create({
|
||||
data: {
|
||||
routeId: route.id,
|
||||
departureTime,
|
||||
arrivalTime,
|
||||
vehicleType,
|
||||
capacity,
|
||||
price,
|
||||
},
|
||||
});
|
||||
schedulesCreated++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Seeded ${schedulesCreated} schedules successfully.`);
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user