const { Sequelize } = require('sequelize'); const bcrypt = require('bcrypt'); // Import models const Device = require('../models/Device'); const DroneDetection = require('../models/DroneDetection'); const Heartbeat = require('../models/Heartbeat'); const User = require('../models/User'); const AlertRule = require('../models/AlertRule'); const AlertLog = require('../models/AlertLog'); const setupDatabase = async () => { try { console.log('πŸš€ Starting database setup...\n'); // Load environment variables require('dotenv').config(); // Create Sequelize instance const sequelize = new Sequelize( process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, { host: process.env.DB_HOST, port: process.env.DB_PORT, dialect: 'postgres', logging: console.log, } ); // Test database connection console.log('πŸ“‘ Testing database connection...'); await sequelize.authenticate(); console.log('βœ… Database connection established successfully.\n'); // Initialize models console.log('πŸ“‹ Initializing models...'); Device.init(Device.getAttributes(), { sequelize, modelName: 'Device' }); DroneDetection.init(DroneDetection.getAttributes(), { sequelize, modelName: 'DroneDetection' }); Heartbeat.init(Heartbeat.getAttributes(), { sequelize, modelName: 'Heartbeat' }); User.init(User.getAttributes(), { sequelize, modelName: 'User' }); AlertRule.init(AlertRule.getAttributes(), { sequelize, modelName: 'AlertRule' }); AlertLog.init(AlertLog.getAttributes(), { sequelize, modelName: 'AlertLog' }); // Define associations console.log('πŸ”— Setting up model associations...'); // Device associations Device.hasMany(DroneDetection, { foreignKey: 'device_id', as: 'detections' }); Device.hasMany(Heartbeat, { foreignKey: 'device_id', as: 'heartbeats' }); // Detection associations DroneDetection.belongsTo(Device, { foreignKey: 'device_id', as: 'device' }); // Heartbeat associations Heartbeat.belongsTo(Device, { foreignKey: 'device_id', as: 'device' }); // User associations User.hasMany(AlertRule, { foreignKey: 'user_id', as: 'alertRules' }); User.hasMany(AlertLog, { foreignKey: 'user_id', as: 'alertLogs' }); // Alert associations AlertRule.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); AlertRule.hasMany(AlertLog, { foreignKey: 'alert_rule_id', as: 'logs' }); AlertLog.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); AlertLog.belongsTo(AlertRule, { foreignKey: 'alert_rule_id', as: 'alertRule' }); AlertLog.belongsTo(DroneDetection, { foreignKey: 'detection_id', as: 'detection' }); // Sync database (create tables) console.log('πŸ—οΈ Creating database tables...'); await sequelize.sync({ force: true }); // WARNING: This will drop existing tables console.log('βœ… Database tables created successfully.\n'); // Create sample data console.log('πŸ“Š Creating sample data...\n'); // Create admin user console.log('πŸ‘€ Creating admin user...'); const adminUser = await User.create({ username: 'admin', email: 'admin@example.com', password: await bcrypt.hash('admin123', 10), role: 'admin' }); 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: await bcrypt.hash('operator123', 10), role: 'operator' }); console.log(`βœ… Operator user created: ${operatorUser.username}`); // Create sample devices console.log('πŸ“‘ Creating sample devices...'); const devices = await Device.bulkCreate([ { device_id: 1941875381, name: 'Drone Detector Alpha', location: 'Stockholm Central', geo_lat: 59.3293, geo_lon: 18.0686, status: 'online', last_seen: new Date() }, { device_id: 1941875382, name: 'Drone Detector Beta', location: 'Gothenburg Port', geo_lat: 57.7089, geo_lon: 11.9746, status: 'online', last_seen: new Date() }, { device_id: 1941875383, name: 'Drone Detector Gamma', location: 'MalmΓΆ Airport', geo_lat: 55.6050, geo_lon: 13.0038, status: 'offline', last_seen: new Date(Date.now() - 2 * 60 * 60 * 1000) // 2 hours ago } ]); console.log(`βœ… Created ${devices.length} sample devices`); // Create sample heartbeats console.log('πŸ’“ Creating sample heartbeats...'); const heartbeats = await Heartbeat.bulkCreate([ { device_id: 1941875381, battery_level: 85, signal_strength: -45, temperature: 22.5, status: 'active', timestamp: new Date() }, { device_id: 1941875382, battery_level: 72, signal_strength: -38, temperature: 24.1, status: 'active', timestamp: new Date() } ]); console.log(`βœ… Created ${heartbeats.length} sample heartbeats`); // Create sample drone detections console.log('🚁 Creating sample drone detections...'); const detections = await DroneDetection.bulkCreate([ { device_id: 1941875381, 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 }, { device_id: 1941875382, 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 }, { device_id: 1941875381, 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 } ]); 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, name: 'Critical Security Threat', description: 'Immediate alert for critical and high threats to government facilities', conditions: { min_threat_level: 'high', rssi_threshold: -55, max_distance: 200, drone_types: [0, 1, 2], device_ids: [] }, actions: { sms: true, phone_number: '+46701234567', email: true, channels: ['sms', 'email'] }, cooldown_minutes: 2, is_active: true }, { user_id: operatorUser.id, name: 'Medium Threat Monitoring', description: 'Monitor medium threat drones in facility vicinity', conditions: { min_threat_level: 'medium', rssi_threshold: -70, max_distance: 1000, drone_types: [1, 2], device_ids: [1941875381, 1941875382] }, actions: { sms: true, phone_number: '+46709876543', channels: ['sms'] }, cooldown_minutes: 10, is_active: true }, { user_id: adminUser.id, name: 'Device Offline Alert', description: 'Alert when security devices go offline', conditions: { device_offline: true, device_ids: [1941875381, 1941875382, 1941875383] }, actions: { sms: true, phone_number: '+46701234567', channels: ['sms'] }, cooldown_minutes: 30, is_active: true } ]); 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 1941875383 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 "DroneDetections" (device_id, timestamp); `); await sequelize.query(` CREATE INDEX IF NOT EXISTS idx_heartbeats_device_timestamp ON "Heartbeats" (device_id, timestamp); `); await sequelize.query(` CREATE INDEX IF NOT EXISTS idx_alert_logs_user_created ON "AlertLogs" (user_id, "createdAt"); `); 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;