#!/usr/bin/env node /** * Production database setup script for DigitalOcean * This script sets up the initial database structure and creates a default admin user */ import { drizzle } from 'drizzle-orm/mysql2'; import mysql from 'mysql2/promise'; import { migrate } from 'drizzle-orm/mysql2/migrator'; import bcrypt from 'bcrypt'; import { nanoid } from 'nanoid'; import { config } from 'dotenv'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import * as schema from '../src/lib/db/schema.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Load environment variables config(); async function setupProductionDatabase() { console.log('🚀 Setting up production database...'); if (!process.env.DATABASE_URL) { console.error('❌ DATABASE_URL environment variable is required'); process.exit(1); } let connection; try { // Parse DATABASE_URL for DigitalOcean managed database const dbUrl = new URL(process.env.DATABASE_URL); // Create connection to MySQL connection = await mysql.createConnection({ host: dbUrl.hostname, port: parseInt(dbUrl.port) || 25060, user: dbUrl.username, password: dbUrl.password, database: dbUrl.pathname.slice(1), // Remove leading slash ssl: { rejectUnauthorized: false // DigitalOcean managed databases use SSL }, connectTimeout: 60000, acquireTimeout: 60000, timeout: 60000, }); console.log('✅ Connected to database'); // Create drizzle instance const db = drizzle(connection, { schema }); // Run migrations console.log('🔄 Running migrations...'); await migrate(db, { migrationsFolder: join(__dirname, '../drizzle') }); console.log('✅ Migrations completed'); // Create default admin user console.log('👤 Creating default admin user...'); const adminEmail = process.env.ADMIN_EMAIL || 'admin@scriptshare.com'; const adminPassword = process.env.ADMIN_PASSWORD || 'admin123'; const adminUsername = process.env.ADMIN_USERNAME || 'admin'; // Check if admin user already exists const existingAdmin = await db.query.users.findFirst({ where: (users, { eq }) => eq(users.email, adminEmail) }); if (existingAdmin) { console.log('â„šī¸ Admin user already exists, skipping creation'); } else { const hashedPassword = await bcrypt.hash(adminPassword, 10); await db.insert(schema.users).values({ id: nanoid(), email: adminEmail, username: adminUsername, displayName: 'System Administrator', isAdmin: true, isModerator: true, avatarUrl: null, bio: 'Default system administrator account' }); console.log('✅ Default admin user created'); console.log(`📧 Email: ${adminEmail}`); console.log(`👤 Username: ${adminUsername}`); console.log(`🔑 Password: ${adminPassword}`); console.log('âš ī¸ Please change the default password after first login!'); } console.log('🎉 Production database setup completed successfully!'); } catch (error) { console.error('❌ Setup failed:', error); process.exit(1); } finally { if (connection) { await connection.end(); console.log('🔌 Database connection closed'); } } } // Run setup if this script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { setupProductionDatabase().catch(console.error); } export { setupProductionDatabase };