Files
company-celebration/packages/server/src/index.ts
empty 83bf1d3a43 chore: sync various improvements and fixes
- Update gitignore and serena config
- Improve connection and voting stores
- Enhance admin routes and socket handling
- Update client-screen views
- Add auth middleware

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:31:38 +08:00

89 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createServer } from 'http';
import { app, logger } from './app';
import { config } from './config';
import { connectRedis } from './config/redis';
import { connectDatabase, disconnectDatabase } from './config/db';
import { initializeSocket } from './socket';
import { loadLuaScripts } from './services/vote.service';
import { loadVotingScripts } from './services/voting.engine';
import { prizeConfigService } from './services/prize-config.service';
import { programConfigService } from './services/program-config.service';
import { participantService } from './services/participant.service';
async function main(): Promise<void> {
try {
if (!config.adminAccessCode) {
logger.warn('ADMIN_ACCESS_CODE 未配置,管理员登录将被拒绝');
}
if (!config.isDev && config.jwtSecret === 'dev-secret-change-in-production') {
logger.error('生产环境禁止使用默认 JWT_SECRET请配置环境变量');
process.exit(1);
}
// Connect to Database
logger.info('Connecting to Database...');
await connectDatabase();
// Connect to Redis
logger.info('Connecting to Redis...');
await connectRedis();
// Load Lua scripts
logger.info('Loading Lua scripts...');
await loadLuaScripts();
await loadVotingScripts();
// Load prize configuration
logger.info('Loading prize configuration...');
await prizeConfigService.load();
// Load program configuration
logger.info('Loading program configuration...');
await programConfigService.load();
// Restore participants from Redis
logger.info('Restoring participants from Redis...');
await participantService.restoreFromRedis();
// Create HTTP server
const httpServer = createServer(app);
// Initialize Socket.io
logger.info('Initializing Socket.io...');
await initializeSocket(httpServer);
// Start server - listen on all interfaces for LAN access
httpServer.listen(config.port, '0.0.0.0', () => {
logger.info({ port: config.port, env: config.nodeEnv }, 'Server started');
logger.info(`Health check: http://localhost:${config.port}/health`);
logger.info(`LAN access: http://192.168.1.5:${config.port}`);
});
// Graceful shutdown
const shutdown = async (signal: string) => {
logger.info({ signal }, 'Shutdown signal received');
// Disconnect from database
await disconnectDatabase();
httpServer.close(() => {
logger.info('HTTP server closed');
process.exit(0);
});
// Force exit after 10 seconds
setTimeout(() => {
logger.error('Forced shutdown after timeout');
process.exit(1);
}, 10000);
};
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
} catch (error) {
logger.error({ error }, 'Failed to start server');
process.exit(1);
}
}
main();