132 lines
4.1 KiB
JavaScript
132 lines
4.1 KiB
JavaScript
const express = require('express');
|
|
const cors = require('cors');
|
|
const helmet = require('helmet');
|
|
const morgan = require('morgan');
|
|
const compression = require('compression');
|
|
const rateLimit = require('express-rate-limit');
|
|
const { createServer } = require('http');
|
|
const { Server } = require('socket.io');
|
|
require('dotenv').config();
|
|
|
|
const { sequelize } = require('./models');
|
|
const routes = require('./routes');
|
|
const { initializeSocketHandlers } = require('./services/socketService');
|
|
const AlertService = require('./services/alertService');
|
|
const seedDatabase = require('./seedDatabase');
|
|
const errorHandler = require('./middleware/errorHandler');
|
|
|
|
const app = express();
|
|
const server = createServer(app);
|
|
const io = new Server(server, {
|
|
cors: {
|
|
origin: process.env.CORS_ORIGIN || "http://localhost:3000",
|
|
methods: ["GET", "POST", "PUT", "DELETE"]
|
|
}
|
|
});
|
|
|
|
// Rate limiting (exclude detections endpoint for testing)
|
|
const limiter = rateLimit({
|
|
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes
|
|
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100,
|
|
message: 'Too many requests from this IP, please try again later.',
|
|
skip: (req) => {
|
|
// Skip rate limiting for drone detection endpoints during testing
|
|
return req.path.includes('/detections');
|
|
}
|
|
});
|
|
|
|
// Middleware
|
|
app.use(helmet());
|
|
app.use(compression());
|
|
app.use(morgan('combined'));
|
|
app.use(cors({
|
|
origin: process.env.CORS_ORIGIN || "http://localhost:3000",
|
|
credentials: true
|
|
}));
|
|
app.use(express.json({ limit: '10mb' }));
|
|
app.use(express.urlencoded({ extended: true }));
|
|
app.use('/api/', limiter);
|
|
|
|
// Make io available to routes
|
|
app.use((req, res, next) => {
|
|
req.io = io;
|
|
next();
|
|
});
|
|
|
|
// Routes
|
|
app.use('/api', routes);
|
|
|
|
// Health check endpoints
|
|
app.get('/health', (req, res) => {
|
|
res.status(200).json({
|
|
status: 'OK',
|
|
timestamp: new Date().toISOString(),
|
|
environment: process.env.NODE_ENV
|
|
});
|
|
});
|
|
|
|
app.use('/api/health', require('./routes/health'));
|
|
|
|
// Error handling
|
|
app.use(errorHandler);
|
|
|
|
// Socket.IO initialization
|
|
initializeSocketHandlers(io);
|
|
|
|
const PORT = process.env.PORT || 3001;
|
|
|
|
// Database connection and server startup
|
|
async function startServer() {
|
|
try {
|
|
await sequelize.authenticate();
|
|
console.log('Database connected successfully.');
|
|
|
|
// Always sync database in containerized environments or development
|
|
// Check if tables exist before syncing
|
|
try {
|
|
await sequelize.sync({ force: false, alter: false });
|
|
console.log('Database synchronized.');
|
|
|
|
// Seed database with initial data
|
|
await seedDatabase();
|
|
} catch (syncError) {
|
|
console.error('Database sync error:', syncError);
|
|
// If sync fails, try force sync (this will drop and recreate tables)
|
|
console.log('Attempting force sync...');
|
|
await sequelize.sync({ force: true });
|
|
console.log('Database force synchronized.');
|
|
|
|
// Seed database with initial data
|
|
await seedDatabase();
|
|
}
|
|
|
|
server.listen(PORT, () => {
|
|
console.log('\n🚀 Drone Detection System Started Successfully!');
|
|
console.log('================================================');
|
|
console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
|
|
console.log(`🌐 Server Port: ${PORT}`);
|
|
console.log(`💾 Database: ${process.env.DB_HOST}:${process.env.DB_PORT}`);
|
|
console.log(`🔴 Redis: ${process.env.REDIS_HOST || 'localhost'}:${process.env.REDIS_PORT || 6379}`);
|
|
|
|
// Initialize AlertService to check SMS status
|
|
const alertService = new AlertService();
|
|
if (alertService.twilioEnabled) {
|
|
console.log('📱 SMS Alerts: ✅ Enabled');
|
|
} else {
|
|
console.log('📱 SMS Alerts: ⚠️ Disabled (no Twilio credentials)');
|
|
}
|
|
|
|
console.log(`📊 Health check: http://localhost:${PORT}/health`);
|
|
console.log(`🌐 API endpoint: http://localhost:${PORT}/api`);
|
|
console.log('================================================\n');
|
|
});
|
|
} catch (error) {
|
|
console.error('Unable to start server:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
startServer();
|
|
|
|
module.exports = { app, server, io };
|