Admin Control Panel: - Add full AdminControl.vue with 3 sections (Voting, Lottery, Global) - Add AdminLogin.vue with access code gate (20268888) - Add admin.ts store with state persistence - Add admin.types.ts with state machine types - Add router guards for /admin/director-console Voting System Fixes: - Add voting status check before accepting votes (VOTING_CLOSED error) - Fix client to display server error messages - Fix button disabled logic to prevent ambiguity in paused state - Auto-generate userId on connect to fix UNAUTHORIZED error Big Screen Enhancements: - Add LiveVotingView.vue with particle system - Add LotteryMachine.ts with 3-stage animation (Galaxy/Storm/Reveal) - Add useSocketClient.ts composable - Fix MainDisplay.vue SCSS syntax error - Add admin state sync listener in display store Server Updates: - Add admin.service.ts for state management - Add isVotingOpen() and getVotingStatus() methods - Add admin socket event handlers Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { createServer } from 'http';
|
|
import { app, logger } from './app';
|
|
import { config } from './config';
|
|
import { connectRedis } from './config/redis';
|
|
import { initializeSocket } from './socket';
|
|
import { loadLuaScripts } from './services/vote.service';
|
|
import { loadVotingScripts } from './services/voting.engine';
|
|
|
|
async function main(): Promise<void> {
|
|
try {
|
|
// Connect to Redis
|
|
logger.info('Connecting to Redis...');
|
|
await connectRedis();
|
|
|
|
// Load Lua scripts
|
|
logger.info('Loading Lua scripts...');
|
|
await loadLuaScripts();
|
|
await loadVotingScripts();
|
|
|
|
// Create HTTP server
|
|
const httpServer = createServer(app);
|
|
|
|
// Initialize Socket.io
|
|
logger.info('Initializing Socket.io...');
|
|
await initializeSocket(httpServer);
|
|
|
|
// Start server
|
|
httpServer.listen(config.port, () => {
|
|
logger.info({ port: config.port, env: config.nodeEnv }, 'Server started');
|
|
logger.info(`Health check: http://localhost:${config.port}/health`);
|
|
});
|
|
|
|
// Graceful shutdown
|
|
const shutdown = async (signal: string) => {
|
|
logger.info({ signal }, 'Shutdown signal received');
|
|
|
|
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();
|