e8d9b1fd42
Add complete token system with Plex/Tautulli/Overseer integration: - Anchor program for SPL token mint/burn/transfer - Express backend with OAuth, webhooks, Solana integration - Next.js frontend with dashboard, admin panel, wallet management - Docker deployment for 172.20.1.0/24 infrastructure - Production configs with SSL, Nginx, health monitoring Tautulli webhooks auto-mint on watch events. Overseer integration burns for content requests.
127 lines
3.2 KiB
TypeScript
127 lines
3.2 KiB
TypeScript
import express from 'express';
|
|
import cors from 'cors';
|
|
import helmet from 'helmet';
|
|
import morgan from 'morgan';
|
|
import rateLimit from 'express-rate-limit';
|
|
import { createServer } from 'http';
|
|
import { Server } from 'socket.io';
|
|
import dotenv from 'dotenv';
|
|
|
|
dotenv.config();
|
|
|
|
import { prisma } from './utils/prisma';
|
|
import { errorHandler } from './middleware/errorHandler';
|
|
import { authRouter } from './routes/auth';
|
|
import { userRouter } from './routes/users';
|
|
import { walletRouter } from './routes/wallet';
|
|
import { transactionsRouter } from './routes/transactions';
|
|
import { adminRouter } from './routes/admin';
|
|
import { tautulliRouter } from './routes/tautulli';
|
|
import { overseerRouter } from './routes/overseer';
|
|
import { webhookRouter } from './routes/webhooks';
|
|
import { setupSocketHandlers } from './services/socket';
|
|
|
|
const app = express();
|
|
const httpServer = createServer(app);
|
|
const io = new Server(httpServer, {
|
|
cors: {
|
|
origin: process.env.FRONTEND_URL || 'http://localhost:3000',
|
|
credentials: true
|
|
}
|
|
});
|
|
|
|
// Security middleware
|
|
app.use(helmet());
|
|
app.use(cors({
|
|
origin: process.env.FRONTEND_URL || 'http://localhost:3000',
|
|
credentials: true
|
|
}));
|
|
|
|
// Rate limiting
|
|
const limiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 100 // limit each IP to 100 requests per windowMs
|
|
});
|
|
app.use(limiter);
|
|
|
|
// Body parsing
|
|
app.use(express.json({ limit: '10mb' }));
|
|
app.use(express.urlencoded({ extended: true }));
|
|
|
|
// Logging
|
|
app.use(morgan('combined'));
|
|
|
|
// Health check
|
|
app.get('/health', (_req, res) => {
|
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
});
|
|
|
|
// API routes
|
|
app.use('/api/auth', authRouter);
|
|
app.use('/api/users', userRouter);
|
|
app.use('/api/wallet', walletRouter);
|
|
app.use('/api/transactions', transactionsRouter);
|
|
app.use('/api/admin', adminRouter);
|
|
app.use('/api/tautulli', tautulliRouter);
|
|
app.use('/api/overseer', overseerRouter);
|
|
app.use('/webhooks', webhookRouter);
|
|
|
|
// Error handling
|
|
app.use(errorHandler);
|
|
|
|
// Setup WebSocket handlers
|
|
setupSocketHandlers(io);
|
|
|
|
// Start server
|
|
const PORT = process.env.PORT || 3001;
|
|
|
|
async function startServer() {
|
|
try {
|
|
// Connect to database
|
|
await prisma.$connect();
|
|
console.log('✅ Connected to database');
|
|
|
|
// Ensure default settings exist
|
|
const settings = await prisma.systemSettings.findFirst();
|
|
if (!settings) {
|
|
await prisma.systemSettings.create({
|
|
data: {
|
|
id: 'default'
|
|
}
|
|
});
|
|
console.log('✅ Created default system settings');
|
|
}
|
|
|
|
httpServer.listen(PORT, () => {
|
|
console.log(`🚀 Server running on port ${PORT}`);
|
|
console.log(`📊 API URL: ${process.env.API_URL || `http://localhost:${PORT}`}`);
|
|
});
|
|
} catch (error) {
|
|
console.error('Failed to start server:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGTERM', async () => {
|
|
console.log('SIGTERM received, shutting down gracefully');
|
|
await prisma.$disconnect();
|
|
httpServer.close(() => {
|
|
console.log('Server closed');
|
|
process.exit(0);
|
|
});
|
|
});
|
|
|
|
process.on('SIGINT', async () => {
|
|
console.log('SIGINT received, shutting down gracefully');
|
|
await prisma.$disconnect();
|
|
httpServer.close(() => {
|
|
console.log('Server closed');
|
|
process.exit(0);
|
|
});
|
|
});
|
|
|
|
startServer();
|
|
|
|
export { io };
|