feat: initialize Annual Gala Interactive System monorepo

- Set up pnpm workspace with 4 packages: shared, server, client-mobile, client-screen
- Implement Redis atomic voting with Lua scripts (HINCRBY + distributed lock)
- Add optimistic UI with IndexedDB queue for offline resilience
- Configure Socket.io with auto-reconnection (infinite retries)
- Separate mobile (Vant) and big screen (Pixi.js) dependencies

Tech stack:
- Frontend Mobile: Vue 3 + Vant + Socket.io-client
- Frontend Screen: Vue 3 + Pixi.js + GSAP
- Backend: Express + Socket.io + Redis + Prisma/MySQL

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
empty
2026-01-15 01:19:36 +08:00
commit e7397d22a9
74 changed files with 14088 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
import express, { Application } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import { config } from './config';
import { logger } from './utils/logger';
import { errorHandler } from './middleware/errorHandler';
import { requestLogger } from './middleware/requestLogger';
import voteRoutes from './routes/vote.routes';
import adminRoutes from './routes/admin.routes';
export const app: Application = express();
// Security middleware
app.use(helmet());
// CORS
app.use(
cors({
origin: config.corsOrigins,
credentials: true,
})
);
// Compression
app.use(compression());
// Body parsing
app.use(express.json({ limit: '1mb' }));
app.use(express.urlencoded({ extended: true }));
// Request logging
app.use(requestLogger);
// Health check
app.get('/health', (_req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// API routes
app.use('/api/vote', voteRoutes);
app.use('/api/admin', adminRoutes);
// 404 handler
app.use((_req, res) => {
res.status(404).json({ error: 'Not Found' });
});
// Error handler
app.use(errorHandler);
export { logger };