Files
telegram-management-system/marketing-agent/services/billing-service/src/app.js
你的用户名 237c7802e5
Some checks failed
Deploy / deploy (push) Has been cancelled
Initial commit: Telegram Management System
Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 15:37:50 +08:00

114 lines
2.8 KiB
JavaScript

import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import mongoose from 'mongoose';
import { config } from './config/index.js';
import { logger, requestLogger, errorLogger } from './utils/logger.js';
// Import routes
import subscriptionRoutes from './routes/subscriptions.js';
import invoiceRoutes from './routes/invoices.js';
import paymentMethodRoutes from './routes/payment-methods.js';
import transactionRoutes from './routes/transactions.js';
import webhookRoutes from './routes/webhooks.js';
// Create Express app
const app = express();
// Security middleware
app.use(helmet());
app.use(cors(config.cors));
// Rate limiting
const limiter = rateLimit(config.rateLimit);
app.use('/api/', limiter);
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Webhook routes (before body parsing for raw body)
app.use('/webhooks', webhookRoutes);
// Request logging
app.use(requestLogger);
// API routes
app.use('/api/subscriptions', subscriptionRoutes);
app.use('/api/invoices', invoiceRoutes);
app.use('/api/payment-methods', paymentMethodRoutes);
app.use('/api/transactions', transactionRoutes);
// Health check
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
service: 'billing-service',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: config.env
});
});
// Error handling
app.use(errorLogger);
// 404 handler
app.use((req, res) => {
res.status(404).json({
success: false,
error: 'Route not found'
});
});
// Global error handler
app.use((err, req, res, next) => {
const status = err.status || 500;
const message = err.message || 'Internal server error';
res.status(status).json({
success: false,
error: message,
...(config.env === 'development' && { stack: err.stack })
});
});
// Database connection
export async function connectDB() {
try {
await mongoose.connect(config.mongodb.uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
logger.info('MongoDB connected successfully');
} catch (error) {
logger.error('MongoDB connection error:', error);
process.exit(1);
}
}
// Graceful shutdown
export function setupGracefulShutdown(server) {
const shutdown = async (signal) => {
logger.info(`${signal} received, starting graceful shutdown`);
server.close(() => {
logger.info('HTTP server closed');
});
try {
await mongoose.connection.close();
logger.info('MongoDB connection closed');
process.exit(0);
} catch (error) {
logger.error('Error during shutdown:', error);
process.exit(1);
}
};
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
}
export default app;