update
This commit is contained in:
244
app.js
Normal file
244
app.js
Normal file
@@ -0,0 +1,244 @@
|
||||
const express = require('express');
|
||||
const helmet = require('helmet');
|
||||
const cors = require('cors');
|
||||
const compression = require('compression');
|
||||
const morgan = require('morgan');
|
||||
require('express-async-errors'); // Handle async errors
|
||||
const config = require('./config/config.json');
|
||||
|
||||
// Import configurations
|
||||
const { initializeDatabase } = require('./config/database');
|
||||
const { setupRelationships } = require('./models');
|
||||
const { redisClient } = require('./config/redis');
|
||||
|
||||
// Import middleware
|
||||
const { errorHandler, notFoundHandler } = require('./middleware/errorHandler');
|
||||
|
||||
// Import routes
|
||||
const authRoutes = require('./routes/authRoutes');
|
||||
const schoolRoutes = require('./routes/schoolRoutes');
|
||||
const classRoutes = require('./routes/classRoutes');
|
||||
const academicYearRoutes = require('./routes/academicYearRoutes');
|
||||
const subjectRoutes = require('./routes/subjectRoutes');
|
||||
const userRoutes = require('./routes/userRoutes');
|
||||
const studentRoutes = require('./routes/studentRoutes');
|
||||
const teacherRoutes = require('./routes/teacherRoutes');
|
||||
const roomRoutes = require('./routes/roomRoutes');
|
||||
const attendanceRoutes = require('./routes/attendanceRoutes');
|
||||
const gradeRoutes = require('./routes/gradeRoutes');
|
||||
const subscriptionRoutes = require('./routes/subscriptionRoutes');
|
||||
const trainingRoutes = require('./routes/trainingRoutes');
|
||||
const parentTaskRoutes = require('./routes/parentTaskRoutes');
|
||||
const chapterRoutes = require('./routes/chapterRoutes');
|
||||
const gameRoutes = require('./routes/gameRoutes');
|
||||
|
||||
/**
|
||||
* Initialize Express Application
|
||||
*/
|
||||
const app = express();
|
||||
|
||||
/**
|
||||
* Security Middleware
|
||||
*/
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
scriptSrc: ["'self'"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'"],
|
||||
imgSrc: ["'self'", "data:", "https:"],
|
||||
connectSrc: ["'self'"],
|
||||
fontSrc: ["'self'"],
|
||||
objectSrc: ["'none'"],
|
||||
mediaSrc: ["'self'"],
|
||||
frameSrc: ["'none'"],
|
||||
},
|
||||
},
|
||||
}));
|
||||
app.use(cors({
|
||||
origin: config.cors.origin,
|
||||
credentials: true,
|
||||
}));
|
||||
|
||||
/**
|
||||
* Body Parsing Middleware
|
||||
*/
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||
|
||||
/**
|
||||
* Static Files Middleware
|
||||
*/
|
||||
app.use(express.static('public'));
|
||||
|
||||
/**
|
||||
* Compression Middleware
|
||||
*/
|
||||
app.use(compression());
|
||||
|
||||
/**
|
||||
* Logging Middleware
|
||||
*/
|
||||
if (config.server.env === 'development') {
|
||||
app.use(morgan('dev'));
|
||||
} else {
|
||||
app.use(morgan('combined'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Health Check Endpoint
|
||||
*/
|
||||
app.get('/health', async (req, res) => {
|
||||
try {
|
||||
// Check database connection
|
||||
await require('./config/database').testConnection();
|
||||
|
||||
// Check Redis connection
|
||||
await redisClient.ping();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: process.uptime(),
|
||||
environment: config.server.env,
|
||||
services: {
|
||||
database: 'connected',
|
||||
redis: 'connected',
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(503).json({
|
||||
success: false,
|
||||
status: 'unhealthy',
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* API Info Endpoint
|
||||
*/
|
||||
app.get('/api', (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
name: 'Sena School Management API',
|
||||
version: '1.0.0',
|
||||
description: 'API for managing 200 schools with Redis caching and BullMQ job processing',
|
||||
enauth: '/api/auth',
|
||||
dpoints: {
|
||||
schools: '/api/schools',
|
||||
classes: '/api/classes',
|
||||
academicYears: '/api/academic-years',
|
||||
subjects: '/api/subjects',
|
||||
users: '/api/users',
|
||||
students: '/api/students',
|
||||
teachers: '/api/teachers',
|
||||
rooms: '/api/rooms',
|
||||
attendance: '/api/attendance',
|
||||
grades: '/api/grades',
|
||||
subscriptions: '/api/subscriptions',
|
||||
training: '/api/training',
|
||||
parentTasks: '/api/parent-tasks',
|
||||
chapters: '/api/chapters',
|
||||
games: '/api/games',
|
||||
},
|
||||
documentation: '/api/docs',
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* API Routes
|
||||
*/
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/schools', schoolRoutes);
|
||||
app.use('/api/classes', classRoutes);
|
||||
app.use('/api/academic-years', academicYearRoutes);
|
||||
app.use('/api/subjects', subjectRoutes);
|
||||
app.use('/api/users', userRoutes);
|
||||
app.use('/api/students', studentRoutes);
|
||||
app.use('/api/teachers', teacherRoutes);
|
||||
app.use('/api/rooms', roomRoutes);
|
||||
app.use('/api/attendance', attendanceRoutes);
|
||||
app.use('/api/grades', gradeRoutes);
|
||||
app.use('/api/subscriptions', subscriptionRoutes);
|
||||
app.use('/api/training', trainingRoutes);
|
||||
app.use('/api/parent-tasks', parentTaskRoutes);
|
||||
app.use('/api/chapters', chapterRoutes);
|
||||
app.use('/api/games', gameRoutes);
|
||||
|
||||
/**
|
||||
* Queue Status Endpoint
|
||||
*/
|
||||
app.get('/api/queues/status', async (req, res) => {
|
||||
try {
|
||||
const { getQueueMetrics, QueueNames } = require('./config/bullmq');
|
||||
|
||||
const metrics = await Promise.all(
|
||||
Object.values(QueueNames).map(queueName => getQueueMetrics(queueName))
|
||||
);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: metrics,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cache Stats Endpoint
|
||||
*/
|
||||
app.get('/api/cache/stats', async (req, res) => {
|
||||
try {
|
||||
const info = await redisClient.info('stats');
|
||||
const dbSize = await redisClient.dbsize();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
dbSize,
|
||||
stats: info,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 404 Handler
|
||||
*/
|
||||
app.use(notFoundHandler);
|
||||
|
||||
/**
|
||||
* Global Error Handler
|
||||
*/
|
||||
app.use(errorHandler);
|
||||
|
||||
/**
|
||||
* Initialize Application
|
||||
*/
|
||||
const initializeApp = async () => {
|
||||
try {
|
||||
// Initialize database connection
|
||||
await initializeDatabase();
|
||||
|
||||
// Setup model relationships
|
||||
setupRelationships();
|
||||
|
||||
console.log('✅ Application initialized successfully');
|
||||
} catch (error) {
|
||||
console.error('❌ Application initialization failed:', error.message);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { app, initializeApp };
|
||||
Reference in New Issue
Block a user