165 lines
4.8 KiB
JavaScript
165 lines
4.8 KiB
JavaScript
const express = require('express');
|
||
const cors = require('cors');
|
||
const helmet = require('helmet');
|
||
const compression = require('compression');
|
||
const morgan = require('morgan');
|
||
const rateLimit = require('express-rate-limit');
|
||
const session = require('express-session');
|
||
const { createServer } = require('http');
|
||
const { Server } = require('socket.io');
|
||
require('dotenv').config();
|
||
|
||
const passport = require('./config/passport');
|
||
|
||
const { PrismaClient } = require('@prisma/client');
|
||
const authRoutes = require('./routes/auth');
|
||
const userRoutes = require('./routes/users');
|
||
const listRoutes = require('./routes/lists');
|
||
const itemRoutes = require('./routes/items');
|
||
const productRoutes = require('./routes/products');
|
||
const categoryRoutes = require('./routes/categories');
|
||
const notificationRoutes = require('./routes/notifications');
|
||
const dashboardRoutes = require('./routes/dashboard');
|
||
const adminRoutes = require('./routes/admin');
|
||
|
||
const socketHandler = require('./services/socketHandler');
|
||
const { errorHandler, notFound } = require('./middleware/errorHandler');
|
||
const { createNotificationService } = require('./services/notificationService');
|
||
const { setupUtf8mb4 } = require('./utils/dbCharsetSetup');
|
||
|
||
// Prisma client'ı başlat
|
||
const prisma = new PrismaClient();
|
||
|
||
// Ensure DB charset supports emojis (utf8mb4)
|
||
setupUtf8mb4(prisma).catch(() => {});
|
||
|
||
// Express uygulamasını oluştur
|
||
const app = express();
|
||
const server = createServer(app);
|
||
|
||
// Socket.IO'yu başlat
|
||
const io = new Server(server, {
|
||
cors: {
|
||
origin: process.env.CORS_ORIGIN || "http://localhost:3000",
|
||
methods: ["GET", "POST", "PUT", "DELETE"],
|
||
credentials: true
|
||
}
|
||
});
|
||
|
||
// NotificationService'i initialize et
|
||
const notificationService = createNotificationService(prisma, io);
|
||
console.log('📧 NotificationService initialized');
|
||
|
||
// Rate limiting
|
||
const limiter = rateLimit({
|
||
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000, // 15 dakika
|
||
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100, // İstek limiti
|
||
message: {
|
||
error: 'Çok fazla istek gönderdiniz. Lütfen daha sonra tekrar deneyin.'
|
||
},
|
||
standardHeaders: true,
|
||
legacyHeaders: false,
|
||
});
|
||
|
||
// Middleware'ler
|
||
app.use(helmet()); // Güvenlik başlıkları
|
||
app.use(compression()); // Gzip sıkıştırma
|
||
app.use(morgan('combined')); // HTTP isteklerini logla
|
||
app.use(limiter); // Rate limiting
|
||
|
||
app.use(cors({
|
||
origin: process.env.CORS_ORIGIN ? process.env.CORS_ORIGIN.split(',').map(origin => origin.trim()) : ["http://localhost:3000"],
|
||
credentials: true
|
||
}));
|
||
|
||
app.use(express.json({ limit: '10mb' }));
|
||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||
|
||
// Session middleware (Google OAuth için gerekli)
|
||
app.use(session({
|
||
secret: process.env.SESSION_SECRET || 'hmarket-session-secret',
|
||
resave: false,
|
||
saveUninitialized: false,
|
||
cookie: {
|
||
secure: process.env.NODE_ENV === 'production',
|
||
maxAge: 24 * 60 * 60 * 1000 // 24 saat
|
||
}
|
||
}));
|
||
|
||
// Passport middleware
|
||
app.use(passport.initialize());
|
||
app.use(passport.session());
|
||
|
||
// Static dosyalar
|
||
app.use('/uploads', express.static('uploads'));
|
||
|
||
// Prisma'yı request'e ekle
|
||
app.use((req, res, next) => {
|
||
req.prisma = prisma;
|
||
req.io = io;
|
||
next();
|
||
});
|
||
|
||
// Health check endpoint
|
||
app.get('/health', (req, res) => {
|
||
res.json({
|
||
status: 'OK',
|
||
timestamp: new Date().toISOString(),
|
||
uptime: process.uptime(),
|
||
environment: process.env.NODE_ENV || 'development'
|
||
});
|
||
});
|
||
|
||
// API rotaları
|
||
app.use('/api/auth', authRoutes);
|
||
app.use('/api/users', userRoutes);
|
||
app.use('/api/lists', listRoutes);
|
||
app.use('/api/items', itemRoutes);
|
||
app.use('/api/products', productRoutes);
|
||
app.use('/api/categories', categoryRoutes);
|
||
app.use('/api/notifications', notificationRoutes);
|
||
app.use('/api/dashboard', dashboardRoutes);
|
||
app.use('/api/admin', adminRoutes);
|
||
|
||
// Socket.IO event handler'ları
|
||
socketHandler(io, prisma);
|
||
|
||
// Error handling middleware'leri
|
||
app.use(notFound);
|
||
app.use(errorHandler);
|
||
|
||
// Graceful shutdown
|
||
process.on('SIGTERM', async () => {
|
||
console.log('🛑 SIGTERM sinyali alındı. Sunucu kapatılıyor...');
|
||
await prisma.$disconnect();
|
||
server.close(() => {
|
||
console.log('✅ Sunucu başarıyla kapatıldı.');
|
||
process.exit(0);
|
||
});
|
||
});
|
||
|
||
process.on('SIGINT', async () => {
|
||
console.log('🛑 SIGINT sinyali alındı. Sunucu kapatılıyor...');
|
||
await prisma.$disconnect();
|
||
server.close(() => {
|
||
console.log('✅ Sunucu başarıyla kapatıldı.');
|
||
process.exit(0);
|
||
});
|
||
});
|
||
|
||
// Sunucuyu başlat
|
||
const PORT = process.env.PORT || 5000;
|
||
|
||
server.listen(PORT, () => {
|
||
console.log(`🚀 Server ${PORT} portunda çalışıyor - port 7001`);
|
||
console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
|
||
console.log(`🌐 CORS Origin: ${process.env.CORS_ORIGIN || 'http://localhost:7000'}`);
|
||
console.log(`⏰ ${new Date().toLocaleString('tr-TR')}`);
|
||
// Server başlatıldı - port 7002
|
||
});
|
||
|
||
module.exports = { app, server, io, prisma };
|
||
|
||
|
||
|