Initial commit: Korea Tourism Agency website with AdminJS

- 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
This commit is contained in:
2025-11-29 18:13:17 +09:00
commit 409e6c146b
53 changed files with 16195 additions and 0 deletions

75
database/migrate.js Normal file
View File

@@ -0,0 +1,75 @@
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 };