Files
drone-detector/server/scripts/setup-database.js
2025-09-20 23:12:53 +02:00

318 lines
9.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.

const { Sequelize } = re // Models are already initialized through the imports
console.log('📋 Models loaded and ready...');
// For fresh database, just sync to create tables first
console.log('🏗️ Creating database tables...');
await sequelize.sync({ force: true }); // WARNING: This will drop existing tables
console.log('✅ Database tables created successfully.\n');sequelize');
const bcrypt = require('bcryptjs');
// 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('<EFBFBD> Models loaded and ready...');
// 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 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([
{
device_id: 1941875381,
name: 'Drone Detector Alpha',
location: 'Stockholm Central',
geo_lat: 59.3293,
geo_lon: 18.0686,
status: 'online',
last_seen: new Date(),
tenant_id: defaultTenant.id
},
{
device_id: 1941875382,
name: 'Drone Detector Beta',
location: 'Gothenburg Port',
geo_lat: 57.7089,
geo_lon: 11.9746,
status: 'online',
last_seen: new Date(),
tenant_id: defaultTenant.id
},
{
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
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: 1941875381,
status: 'active',
timestamp: new Date()
},
{
device_id: 1941875382,
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,
tenant_id: defaultTenant.id
},
{
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,
tenant_id: defaultTenant.id
},
{
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,
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,
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,
tenant_id: defaultTenant.id
},
{
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,
tenant_id: defaultTenant.id
},
{
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,
tenant_id: defaultTenant.id
}
]);
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;