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:
Alexey Pavlov
2026-05-31 09:17:08 +03:00
parent 500bb0299e
commit c7b83147f1
5 changed files with 180 additions and 0 deletions
+10
View File
@@ -1,5 +1,6 @@
const { query } = require('../config/db');
const ai = require('./ai');
const covers = require('./covers');
/**
* Slug из заголовка — транслит для русского.
@@ -132,6 +133,15 @@ async function generateAndSaveArticle({ topic, keywords = [], tags = [], autoPub
[content, articleRes.usage?.prompt_tokens, articleRes.usage?.completion_tokens, jobId]
);
// Фоновая генерация обложки — не блокирует возврат статьи
setImmediate(() => {
covers.generateCover({
articleId: artRows[0].id,
title: artRows[0].title,
tags: artRows[0].tags || [],
}).catch(err => console.warn('[Article] cover bg failed:', err.message.slice(0,200)));
});
return artRows[0];
} catch (err) {
await query(