Files
scriptshare-cursor/scripts/setup-production-db.js

117 lines
3.6 KiB
JavaScript
Raw Normal View History

#!/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 };