86 lines
3.1 KiB
TypeScript
86 lines
3.1 KiB
TypeScript
import { PrismaClient } from '../src/generated/prisma/client.js';
|
|
import { PrismaLibSql } from '@prisma/adapter-libsql';
|
|
import bcrypt from 'bcryptjs';
|
|
import { randomBytes } from 'crypto';
|
|
import path from 'path';
|
|
|
|
const dbPath = path.resolve(process.cwd(), 'prisma', 'lootah.db');
|
|
const adapter = new PrismaLibSql({ url: `file:${dbPath}` });
|
|
const prisma = new PrismaClient({ adapter } as ConstructorParameters<typeof PrismaClient>[0]);
|
|
|
|
async function main() {
|
|
console.log('Seeding database...');
|
|
|
|
// Create default admin user
|
|
const existingAdmin = await prisma.adminUser.findUnique({
|
|
where: { username: 'admin' },
|
|
});
|
|
|
|
if (!existingAdmin) {
|
|
const passwordHash = await bcrypt.hash('admin123', 12);
|
|
await prisma.adminUser.create({
|
|
data: {
|
|
username: 'admin',
|
|
passwordHash,
|
|
},
|
|
});
|
|
console.log('✓ Created admin user (username: admin, password: admin123)');
|
|
console.log(' ⚠️ Change the password after first login!');
|
|
} else {
|
|
console.log('✓ Admin user already exists, skipping.');
|
|
}
|
|
|
|
// Generate and store JWT secret
|
|
const existingSecret = await prisma.appSettings.findUnique({
|
|
where: { key: 'jwt_secret' },
|
|
});
|
|
|
|
if (!existingSecret) {
|
|
const jwtSecret = randomBytes(64).toString('hex');
|
|
await prisma.appSettings.upsert({
|
|
where: { key: 'jwt_secret' },
|
|
update: { value: jwtSecret },
|
|
create: { key: 'jwt_secret', value: jwtSecret },
|
|
});
|
|
console.log('✓ Generated JWT secret and stored in database.');
|
|
} else {
|
|
console.log('✓ JWT secret already exists, skipping.');
|
|
}
|
|
|
|
// Pricing items upserted on every deploy so the code is the source of truth.
|
|
// Prices in AED. USD → AED at 3.6725 (CBUAE peg).
|
|
// Basic = Unitree G1 retail ($16k) + $5k markup = $21k ≈ 77,125 AED.
|
|
// EDU = $40k flat ≈ 146,900 AED.
|
|
// All persona attire = 5,000 AED each.
|
|
// Note: any prior admin-UI edits to these item prices/labels will be reset on each deploy.
|
|
const defaultItems = [
|
|
{ id: 'base', label: 'G1 Robot Basic', price: 77125, sortOrder: 0 },
|
|
{ id: 'edu', label: 'G1 Robot EDU', price: 146900, sortOrder: 1 },
|
|
{ id: 'emarati-kandura', label: 'Emarati Kandura', price: 5000, sortOrder: 2 },
|
|
{ id: 'industrial-vest', label: 'Industrial Vest', price: 5000, sortOrder: 3 },
|
|
{ id: 'business-suit', label: 'Business Suit', price: 5000, sortOrder: 4 },
|
|
{ id: 'custom-color', label: 'Custom Color', price: 3500, sortOrder: 5 },
|
|
{ id: 'robot-doctor', label: 'Robot Doctor', price: 5000, sortOrder: 6 },
|
|
{ id: 'security-guard', label: 'Security Guard', price: 5000, sortOrder: 7 },
|
|
];
|
|
for (const item of defaultItems) {
|
|
await prisma.pricingItem.upsert({
|
|
where: { id: item.id },
|
|
create: item,
|
|
update: { label: item.label, price: item.price, sortOrder: item.sortOrder },
|
|
});
|
|
}
|
|
console.log(`✓ Upserted ${defaultItems.length} pricing items from code defaults.`);
|
|
|
|
console.log('Seeding complete!');
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|