- Full-stack Node.js/Express application with PostgreSQL - Modern ES modules architecture - AdminJS admin panel with Sequelize ORM - Tourism routes, guides, articles, bookings management - Responsive Bootstrap 5 frontend - Docker containerization with docker-compose - Complete database schema with migrations - Authentication system for admin panel - Dynamic placeholder images for tour categories
75 lines
2.6 KiB
JavaScript
75 lines
2.6 KiB
JavaScript
const fs = require('fs');
|
||
const path = require('path');
|
||
const db = require('../src/config/database');
|
||
|
||
async function runMigrations() {
|
||
try {
|
||
console.log('💾 Starting database migration...');
|
||
|
||
// Check if database is connected
|
||
await db.query('SELECT 1');
|
||
console.log('✅ Database connection successful');
|
||
|
||
// Read and execute schema
|
||
const schemaPath = path.join(__dirname, 'schema.sql');
|
||
const schema = fs.readFileSync(schemaPath, 'utf8');
|
||
|
||
await db.query(schema);
|
||
console.log('✅ Database schema created successfully');
|
||
|
||
// Insert default admin user
|
||
const bcrypt = require('bcryptjs');
|
||
const hashedPassword = await bcrypt.hash('admin123', 10);
|
||
|
||
try {
|
||
await db.query(`
|
||
INSERT INTO admins (username, password, name, email, role)
|
||
VALUES ($1, $2, $3, $4, $5)
|
||
ON CONFLICT (username) DO NOTHING
|
||
`, ['admin', hashedPassword, 'Administrator', 'admin@example.com', 'admin']);
|
||
console.log('✅ Default admin user created');
|
||
} catch (error) {
|
||
console.log('ℹ️ Admin user already exists');
|
||
}
|
||
|
||
// Insert default site settings
|
||
const defaultSettings = [
|
||
['site_name', 'Korea Tourism Agency', 'text', 'Website name'],
|
||
['site_description', 'Discover Korea\'s hidden gems with our guided tours', 'text', 'Site description'],
|
||
['contact_email', 'info@koreatourism.com', 'text', 'Contact email'],
|
||
['contact_phone', '+82-2-1234-5678', 'text', 'Contact phone'],
|
||
['contact_address', 'Seoul, South Korea', 'text', 'Contact address'],
|
||
['facebook_url', '', 'text', 'Facebook page URL'],
|
||
['instagram_url', '', 'text', 'Instagram profile URL'],
|
||
['twitter_url', '', 'text', 'Twitter profile URL'],
|
||
['booking_enabled', 'true', 'boolean', 'Enable online booking'],
|
||
['maintenance_mode', 'false', 'boolean', 'Maintenance mode']
|
||
];
|
||
|
||
for (const [key, value, type, description] of defaultSettings) {
|
||
try {
|
||
await db.query(`
|
||
INSERT INTO site_settings (setting_key, setting_value, setting_type, description)
|
||
VALUES ($1, $2, $3, $4)
|
||
ON CONFLICT (setting_key) DO NOTHING
|
||
`, [key, value, type, description]);
|
||
} catch (error) {
|
||
console.log(`ℹ️ Setting ${key} already exists`);
|
||
}
|
||
}
|
||
console.log('✅ Default site settings inserted');
|
||
|
||
console.log('✨ Migration completed successfully!');
|
||
process.exit(0);
|
||
|
||
} catch (error) {
|
||
console.error('❌ Migration failed:', error);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
if (require.main === module) {
|
||
runMigrations();
|
||
}
|
||
|
||
module.exports = { runMigrations }; |