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

117 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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