import express, { Application } from 'express'; import cors from 'cors'; import path from 'path'; import swaggerUi from 'swagger-ui-express'; import { swaggerSpec } from './docs/swagger'; // Routes import authRoutes from './routes/authRoutes'; import creatorAuthRoutes from './routes/creatorAuthRoutes'; import agentRoutes from './routes/agentRoutes'; import chatRoutes from './routes/chatRoutes'; import subscriptionRoutes from './routes/subscriptionRoutes'; import walletRoutes from './routes/walletRoutes'; import userRoutes from './routes/userRoutes'; import creatorRoutes from './routes/creatorRoutes'; import adminRoutes from './routes/adminRoutes'; const app: Application = express(); // Trust proxy for Hugging Face Spaces app.set('trust proxy', 1); // Simple CORS - allow all app.use(cors()); // Body parsing app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); app.get('/', (req, res) => { res.json({ name: 'Zurri API', version: '1.0.0', description: 'Zurri Agents Marketplace API with Wallet Point System', status: 'running', timestamp: new Date().toISOString(), endpoints: { docs: '/docs', health: '/health', api: '/api', }, note: 'Frontend will be built in a separate milestone', }); }); app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); app.use('/docs', swaggerUi.serve); app.get('/docs', swaggerUi.setup(swaggerSpec, { explorer: true, customCss: '.swagger-ui .topbar { display: none }', customSiteTitle: 'Zurri API Documentation', swaggerOptions: { persistAuthorization: true, }, })); app.use('/api/auth', authRoutes); app.use('/api/creator-auth', creatorAuthRoutes); app.use('/api/users', userRoutes); app.use('/api/creators', creatorRoutes); app.use('/api/admin', adminRoutes); app.use('/api/agents', agentRoutes); app.use('/api/chat', chatRoutes); app.use('/api/subscriptions', subscriptionRoutes); app.use('/api/wallet', walletRoutes); // Serve frontend static files if they exist const frontendPath = path.join(__dirname, '../../zurri-mock-frontend/dist'); let frontendExists = false; try { const fs = require('fs'); if (fs.existsSync(frontendPath) && fs.existsSync(path.join(frontendPath, 'index.html'))) { app.use(express.static(frontendPath)); frontendExists = true; } } catch (error) { // Frontend not available, continue without it } // Serve React app for all non-API routes (SPA routing) // This must come after all API routes but before 404 handler if (frontendExists) { app.get('*', (req, res, next) => { // Skip if it's an API, docs, health, or root route if (req.path.startsWith('/api') || req.path.startsWith('/docs') || req.path.startsWith('/health') || req.path === '/') { return next(); } // Serve React app for all other routes (dashboard, wallet, etc.) res.sendFile(path.join(frontendPath, 'index.html')); }); } // 404 handler - only for API routes or if frontend doesn't exist app.use((req, res) => { if (req.path.startsWith('/api')) { res.status(404).json({ error: 'Route not found' }); } else if (!frontendExists) { res.status(404).send('Not found'); } }); // Simplified error handler (must be last) app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => { if (process.env.NODE_ENV === 'development') { console.error('Error:', err.message); } if (req.path.startsWith('/api')) { res.status(500).json({ error: 'Server error' }); } else { res.status(500).send('Server error'); } }); export default app;