const express = require('express'); const config = require('./src/config'); const { migrate } = require('./src/config/db'); // Routes const generateRoutes = require('./src/routes/generate'); const channelsRoutes = require('./src/routes/channels'); const postsRoutes = require('./src/routes/posts'); const articlesRoutes = require('./src/routes/articles'); const statsRoutes = require('./src/routes/stats'); const notesRoutes = require('./src/routes/notes'); const seriesRoutes = require('./src/routes/series'); const categoriesRoutes = require('./src/routes/categories'); // Start queue worker require('./src/workers/generation'); const app = express(); app.use(express.json()); // Раздача загруженных файлов (обложки статей и т.п.) const path = require('path'); const UPLOADS_DIR = process.env.UPLOADS_DIR || '/var/www/zeropost-uploads'; require('fs').mkdirSync(UPLOADS_DIR, { recursive: true }); // Public uploads — ДО auth-middleware, без секрета app.use('/uploads', express.static(UPLOADS_DIR, { maxAge: '7d', immutable: true })); // Simple internal auth middleware app.use((req, res, next) => { const secret = req.headers['x-internal-secret']; if (secret !== config.internalSecret) { return res.status(401).json({ error: 'Unauthorized' }); } next(); }); app.use('/api/generate', generateRoutes); app.use('/api/channels', channelsRoutes); app.use('/api/posts', postsRoutes); app.use('/api/articles', articlesRoutes); app.use('/api/stats', statsRoutes); app.use('/api/notes', notesRoutes); app.use('/api/series', seriesRoutes); app.use('/api/categories', categoriesRoutes); app.get('/health', (req, res) => { res.json({ ok: true, service: 'zeropost-engine', time: new Date() }); }); const start = async () => { await migrate(); app.listen(config.port, () => { console.log(`[Engine] Running on port ${config.port}`); }); }; start().catch(err => { console.error('[Engine] Failed to start:', err); process.exit(1); });