feat: AI-генерация обложек + /api/stats + раздача /uploads
- services/covers.js: gpt-image-1, фиксированный стиль emerald-geometric, fallback на ошибки шлюза - articles.generateAndSaveArticle: запускает обложку в setImmediate (не блокирует ответ) - routes/articles: POST /backfill-covers для досгенерации - routes/stats: статистика блога (статьи, слова, токены, просмотры) - index.js: express.static на /uploads БЕЗ авторизации (публичные картинки)
This commit is contained in:
@@ -7,6 +7,7 @@ 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');
|
||||
|
||||
// Start queue worker
|
||||
require('./src/workers/generation');
|
||||
@@ -14,6 +15,15 @@ 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'];
|
||||
@@ -27,6 +37,7 @@ 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.get('/health', (req, res) => {
|
||||
res.json({ ok: true, service: 'zeropost-engine', time: new Date() });
|
||||
|
||||
Reference in New Issue
Block a user