appointment_system/backend/src/app.js
2025-12-20 23:19:40 +08:00

167 lines
5.9 KiB
JavaScript

const express = require('express');
const compression = require('compression');
const { applySecurityMiddleware } = require('./middleware/security.js');
const requestLogger = require('./middleware/requestLogger.js');
const metricsMiddleware = require('./middleware/metrics.js');
const { errorHandler, notFoundHandler } = require('./middleware/errorHandler.js');
const { createSessionMiddleware } = require('./config/session.js');
const { languageMiddleware } = require('./middleware/language.js');
const { setupSwagger, generatePostmanCollection } = require('./config/swagger.js');
/**
* Create and configure Express application
*/
const createApp = () => {
const app = express();
// Setup Swagger API documentation (skip in test environment)
if (process.env.NODE_ENV !== 'test') {
setupSwagger(app);
}
// Apply security middleware (helmet, cors, rate limiting)
applySecurityMiddleware(app);
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Compression middleware
app.use(compression());
// Session middleware with Redis store (skip in test environment)
if (process.env.NODE_ENV !== 'test') {
app.use(createSessionMiddleware());
}
// Request logging middleware
app.use(requestLogger);
// Metrics collection middleware
app.use(metricsMiddleware);
// Language detection middleware
app.use(languageMiddleware);
// Response formatter middleware (converts all responses to unified format)
const responseFormatter = require('./middleware/responseFormatter');
app.use(responseFormatter);
// Serve static files from uploads directory
const path = require('path');
const config = require('./config/env');
app.use('/uploads', express.static(path.resolve(config.upload.path)));
// Health check and metrics endpoints
const healthRoutes = require('./routes/healthRoutes');
app.use('/health', healthRoutes);
app.get('/metrics', (req, res, next) => {
// Forward to health routes metrics endpoint
req.url = '/metrics';
healthRoutes(req, res, next);
});
// Postman collection export endpoint
app.get('/api-docs/postman', (req, res) => {
const collection = generatePostmanCollection();
res.setHeader('Content-Type', 'application/json');
res.setHeader('Content-Disposition', 'attachment; filename="overseas-appointment-api.postman_collection.json"');
res.send(JSON.stringify(collection, null, 2));
});
// API routes
const authRoutes = require('./routes/authRoutes');
app.use('/api/v1/auth', authRoutes);
const userRoutes = require('./routes/userRoutes');
app.use('/api/v1/users', userRoutes);
const serviceRoutes = require('./routes/serviceRoutes');
app.use('/api/v1', serviceRoutes);
const appointmentRoutes = require('./routes/appointmentRoutes');
app.use('/api/v1/appointments', appointmentRoutes);
const notificationRoutes = require('./routes/notificationRoutes');
app.use('/api/v1/notifications', notificationRoutes);
const invitationRoutes = require('./routes/invitationRoutes');
app.use('/api/v1/invitations', invitationRoutes);
const commissionRoutes = require('./routes/commissionRoutes');
app.use('/api/v1/commissions', commissionRoutes);
const withdrawalRoutes = require('./routes/withdrawalRoutes');
app.use('/api/v1/withdrawals', withdrawalRoutes);
const uploadRoutes = require('./routes/uploadRoutes');
app.use('/api/v1/upload', uploadRoutes);
const qrcodeRoutes = require('./routes/qrcodeRoutes');
app.use('/api/v1/qrcode', qrcodeRoutes);
const adminAuthRoutes = require('./routes/adminAuthRoutes');
app.use('/api/v1/admin', adminAuthRoutes);
const adminUserRoutes = require('./routes/adminUserRoutes');
app.use('/api/v1/admin/users', adminUserRoutes);
const adminAppointmentRoutes = require('./routes/adminAppointmentRoutes');
app.use('/api/v1/admin/appointments', adminAppointmentRoutes);
const adminWithdrawalRoutes = require('./routes/adminWithdrawalRoutes');
app.use('/api/v1/admin/withdrawals', adminWithdrawalRoutes);
const adminServiceRoutes = require('./routes/adminServiceRoutes');
app.use('/api/v1/admin/services', adminServiceRoutes);
const adminStatisticsRoutes = require('./routes/adminStatisticsRoutes');
app.use('/api/v1/admin/statistics', adminStatisticsRoutes);
const adminTranslationRoutes = require('./routes/adminTranslationRoutes');
app.use('/api/v1/admin/translations', adminTranslationRoutes);
const adminUploadRoutes = require('./routes/adminUploadRoutes');
app.use('/api/v1/admin/upload', adminUploadRoutes);
const configRoutes = require('./routes/configRoutes');
app.use('/api/v1/config', configRoutes);
const homeRoutes = require('./routes/homeRoutes');
app.use('/api/v1/home', homeRoutes);
const bookingRuleRoutes = require('./routes/bookingRuleRoutes');
app.use('/api/v1/booking-rules', bookingRuleRoutes);
const adminConfigRoutes = require('./routes/adminConfigRoutes');
app.use('/api/v1/admin/config', adminConfigRoutes);
const adminHomeRoutes = require('./routes/adminHomeRoutes');
app.use('/api/v1/admin/home', adminHomeRoutes);
const adminCategoryRoutes = require('./routes/adminCategoryRoutes');
app.use('/api/v1/admin/categories', adminCategoryRoutes);
const adminNotificationRoutes = require('./routes/adminNotificationRoutes');
app.use('/api/v1/admin/notifications', adminNotificationRoutes);
const adminPaymentOrderRoutes = require('./routes/adminPaymentOrderRoutes');
app.use('/api/v1/admin/payment-orders', adminPaymentOrderRoutes);
const adminCommissionRoutes = require('./routes/adminCommissionRoutes');
app.use('/api/v1/admin/commissions', adminCommissionRoutes);
const adminBookingRuleRoutes = require('./routes/adminBookingRuleRoutes');
app.use('/api/v1/admin/booking-rules', adminBookingRuleRoutes);
// 404 handler
app.use(notFoundHandler);
// Global error handler (must be last)
app.use(errorHandler);
return app;
};
module.exports = createApp;