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 };