const { Sequelize } = require('sequelize'); const bcrypt = require('bcryptjs'); const runMigrations = require('./migrate'); // Import models from the main models index const { sequelize, Device, DroneDetection, Heartbeat, User, AlertRule, AlertLog, Tenant } = require('../models'); const setupDatabase = async () => { try { console.log('πŸš€ Starting database setup...\n'); // Test database connection console.log('πŸ“‘ Testing database connection...'); await sequelize.authenticate(); console.log('βœ… Database connection established successfully.\n'); // Models are already initialized through the imports console.log('οΏ½ Models loaded and ready...'); // Run migrations first to create proper schema console.log('πŸ—οΈ Running database migrations...'); await runMigrations(); console.log('βœ… Database migrations completed successfully.\n'); // Check if sample data already exists const existingTenants = await Tenant.count(); if (existingTenants > 0) { console.log('πŸ“Š Sample data already exists, skipping data creation...\n'); console.log('πŸŽ‰ Database setup completed successfully!\n'); await sequelize.close(); return; } // Create sample data console.log('πŸ“Š Creating sample data...\n'); // Create default tenant console.log('🏒 Creating default tenant...'); const defaultTenant = await Tenant.create({ name: 'Default Organization', slug: 'default', subscription_type: 'enterprise', is_active: true, auth_provider: 'local', features: { max_devices: -1, max_users: -1, api_rate_limit: 50000, data_retention_days: -1, features: ['all'] } }); console.log(`βœ… Default tenant created: ${defaultTenant.name}`); // Create admin user console.log('πŸ‘€ Creating admin user...'); const adminUser = await User.create({ username: 'admin', email: 'admin@example.com', password_hash: await bcrypt.hash('admin123', 10), role: 'admin', tenant_id: defaultTenant.id }); console.log(`βœ… Admin user created: ${adminUser.username}`); // Create operator user console.log('πŸ‘€ Creating operator user...'); const operatorUser = await User.create({ username: 'operator', email: 'operator@example.com', password_hash: await bcrypt.hash('operator123', 10), role: 'operator', tenant_id: defaultTenant.id }); console.log(`βœ… Operator user created: ${operatorUser.username}`); // Create sample devices console.log('πŸ“‘ Creating sample devices...'); const devices = await Device.bulkCreate([ { id: 'device-alpha-001', name: 'Drone Detector Alpha', location_description: 'Stockholm Central', geo_lat: 59.3293, geo_lon: 18.0686, is_active: true, is_approved: false, last_heartbeat: new Date(), heartbeat_interval: 300, tenant_id: defaultTenant.id }, { id: 'device-beta-002', name: 'Drone Detector Beta', location_description: 'Gothenburg Port', geo_lat: 57.7089, geo_lon: 11.9746, is_active: true, is_approved: false, last_heartbeat: new Date(), heartbeat_interval: 300, tenant_id: defaultTenant.id }, { id: 'device-gamma-003', name: 'Drone Detector Gamma', location_description: 'MalmΓΆ Airport', geo_lat: 55.6050, geo_lon: 13.0038, is_active: false, is_approved: false, last_heartbeat: new Date(Date.now() - 2 * 60 * 60 * 1000), // 2 hours ago heartbeat_interval: 300, tenant_id: defaultTenant.id } ]); console.log(`βœ… Created ${devices.length} sample devices`); // Create sample heartbeats console.log('πŸ’“ Creating sample heartbeats...'); const heartbeats = await Heartbeat.bulkCreate([ { device_id: 'device-alpha-001', status: 'active', timestamp: new Date(), tenant_id: defaultTenant.id }, { device_id: 'device-beta-002', status: 'active', timestamp: new Date(), tenant_id: defaultTenant.id } ]); console.log(`βœ… Created ${heartbeats.length} sample heartbeats`); // Create sample drone detections console.log('🚁 Creating sample drone detections...'); const detections = await DroneDetection.bulkCreate([ { device_id: 'device-alpha-001', geo_lat: 59.3293, geo_lon: 18.0686, device_timestamp: Math.floor(Date.now() / 1000), drone_type: 0, rssi: -45, freq: 20, drone_id: 1001, timestamp: new Date(), threat_level: 'high', estimated_distance: 150, requires_action: true, tenant_id: defaultTenant.id }, { device_id: 'device-beta-002', geo_lat: 57.7089, geo_lon: 11.9746, device_timestamp: Math.floor(Date.now() / 1000) - 3600, drone_type: 1, rssi: -52, freq: 25, drone_id: 1002, timestamp: new Date(Date.now() - 60 * 60 * 1000), threat_level: 'medium', estimated_distance: 800, requires_action: false, tenant_id: defaultTenant.id }, { device_id: 'device-alpha-001', geo_lat: 59.3295, geo_lon: 18.0690, device_timestamp: Math.floor(Date.now() / 1000) - 7200, drone_type: 0, rssi: -75, freq: 22, drone_id: 1003, timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000), threat_level: 'low', estimated_distance: 2500, requires_action: false, tenant_id: defaultTenant.id } ]); console.log(`βœ… Created ${detections.length} sample drone detections`); // Create sample alert rules console.log('🚨 Creating sample alert rules...'); const alertRules = await AlertRule.bulkCreate([ { user_id: adminUser.id, tenant_id: defaultTenant.id, name: 'Critical Security Threat', description: 'Immediate alert for critical and high threats to government facilities', is_active: true, device_ids: [], drone_types: [0, 1, 2], min_rssi: -55, max_rssi: null, frequency_ranges: null, time_window: 300, min_detections: 1, cooldown_period: 120, alert_channels: ['sms', 'email'], sms_phone_number: '+46701234567', webhook_url: null, active_hours: null, active_days: [1, 2, 3, 4, 5, 6, 7], priority: 'high', min_threat_level: 'high' }, { user_id: operatorUser.id, tenant_id: defaultTenant.id, name: 'Medium Threat Monitoring', description: 'Monitor medium threat drones in facility vicinity', is_active: true, device_ids: ['device-alpha-001', 'device-beta-002'], drone_types: [1, 2], min_rssi: -70, max_rssi: null, frequency_ranges: null, time_window: 300, min_detections: 1, cooldown_period: 600, alert_channels: ['sms'], sms_phone_number: '+46709876543', webhook_url: null, active_hours: null, active_days: [1, 2, 3, 4, 5, 6, 7], priority: 'medium', min_threat_level: 'medium' }, { user_id: adminUser.id, tenant_id: defaultTenant.id, name: 'Device Offline Alert', description: 'Alert when security devices go offline', is_active: true, device_ids: ['device-alpha-001', 'device-beta-002', 'device-gamma-003'], drone_types: null, min_rssi: null, max_rssi: null, frequency_ranges: null, time_window: 300, min_detections: 1, cooldown_period: 1800, alert_channels: ['sms'], sms_phone_number: '+46701234567', webhook_url: null, active_hours: null, active_days: [1, 2, 3, 4, 5, 6, 7], priority: 'medium', min_threat_level: null } ]); console.log(`βœ… Created ${alertRules.length} sample alert rules`); // Create sample alert logs console.log('πŸ“ Creating sample alert logs...'); const alertLogs = await AlertLog.bulkCreate([ { user_id: adminUser.id, alert_rule_id: alertRules[0].id, detection_id: detections[0].id, message: 'Drone detected with strong signal', status: 'sent', sent_at: new Date() }, { user_id: operatorUser.id, alert_rule_id: alertRules[1].id, detection_id: null, message: 'Device device-gamma-003 went offline', status: 'sent', sent_at: new Date(Date.now() - 30 * 60 * 1000) } ]); console.log(`βœ… Created ${alertLogs.length} sample alert logs\n`); // Create database indexes for performance console.log('πŸš€ Creating database indexes...'); await sequelize.query(` CREATE INDEX IF NOT EXISTS idx_drone_detections_device_timestamp ON "drone_detections" (device_id, server_timestamp); `); await sequelize.query(` CREATE INDEX IF NOT EXISTS idx_heartbeats_device_timestamp ON "heartbeats" (device_id, received_at); `); await sequelize.query(` CREATE INDEX IF NOT EXISTS idx_alert_logs_rule_created ON "alert_logs" (alert_rule_id, "created_at"); `); console.log('βœ… Database indexes created\n'); console.log('πŸŽ‰ Database setup completed successfully!\n'); console.log('πŸ“‹ Summary:'); console.log(` β€’ Users created: 2 (admin, operator)`); console.log(` β€’ Devices created: ${devices.length}`); console.log(` β€’ Heartbeats created: ${heartbeats.length}`); console.log(` β€’ Detections created: ${detections.length}`); console.log(` β€’ Alert rules created: ${alertRules.length}`); console.log(` β€’ Alert logs created: ${alertLogs.length}`); console.log('\nπŸ“ Default login credentials:'); console.log(' Admin: admin / admin123'); console.log(' Operator: operator / operator123\n'); // Close connection await sequelize.close(); } catch (error) { console.error('❌ Database setup failed:', error); process.exit(1); } }; // Run setup if called directly if (require.main === module) { setupDatabase(); } module.exports = setupDatabase;