/** * Admin Service - Governance & Destination Management * * Endpoints: * - /api/v1/destinations - Full CRUD (Owner) * - /api/v1/providers - Approval & Management * - /api/v1/complaints - Audit & Resolution * - /api/v1/auth - Admin authentication */ const express = require('express'); const { connectDB } = require('./db'); const destinationRoutes = require('./routes/destinations.routes'); const providerRoutes = require('./routes/providers.routes'); const complaintRoutes = require('./routes/complaints.routes'); const authRoutes = require('./routes/auth.routes'); const { applySecurityMiddleware, authLimiter } = require('./middlewares/security'); const app = express(); const PORT = process.env.PORT || 8080; // Security middleware (Helmet, CORS, Rate Limiting) applySecurityMiddleware(app); // Body parser app.use(express.json({ limit: '10kb' })); // Health check app.get('/health', async (req, res) => { res.json({ status: 'healthy', service: 'admin-service', timestamp: new Date().toISOString() }); }); // Analytics endpoint for admin dashboard const { authenticateAdmin } = require('./middlewares/auth'); app.get('/api/v1/analytics/overview', authenticateAdmin, async (req, res) => { const { getPool } = require('./db'); const pool = getPool(); if (!pool) return res.status(500).json({ error: 'Database not connected' }); try { const [usersResult, destinationsResult, providersResult, complaintsResult] = await Promise.all([ pool.query('SELECT COUNT(*)::integer as total FROM users'), pool.query('SELECT COUNT(*)::integer as total FROM destinations WHERE is_active = true'), pool.query("SELECT COUNT(*)::integer as total FROM provider_profiles"), pool.query("SELECT COUNT(*)::integer as total, COUNT(*) FILTER (WHERE status = 'open')::integer as open_count FROM complaints") ]); res.json({ success: true, data: { total_users: usersResult.rows[0]?.total || 0, total_destinations: destinationsResult.rows[0]?.total || 0, total_providers: providersResult.rows[0]?.total || 0, total_complaints: complaintsResult.rows[0]?.total || 0, open_complaints: complaintsResult.rows[0]?.open_count || 0 } }); } catch (error) { console.error('[Analytics Error]', error.message); res.status(500).json({ error: 'Failed to fetch analytics' }); } }); // Routes with auth rate limiting app.use('/api/v1/auth/login', authLimiter); app.use('/api/v1/destinations', destinationRoutes); app.use('/api/v1/providers', providerRoutes); app.use('/api/v1/complaints', complaintRoutes); app.use('/api/v1/auth', authRoutes); // Error handler app.use((err, req, res, next) => { console.error('[Error]', err.message); res.status(err.status || 500).json({ error: err.message || 'Internal Server Error' }); }); // Start server async function start() { await connectDB(); app.listen(PORT, () => { console.log(`🚀 Admin Service running on port ${PORT}`); }); } start(); module.exports = app;