8. SMTP: emailService.js (nodemailer), templates (welcome/payment/low_credits)
/api/admin/email/test — тест отправки
app_settings category=smtp (HOST/PORT/USER/PASS/FROM/ENABLED)
9. Maintenance mode: middleware в index.js, MAINTENANCE_MODE в engine settings
При true → 503 для всех запросов кроме /uploads и /api/settings
10. Blog topic bank:
DB: blog_topics(category,topic,is_used,source,priority)
40 тем мигрированы из хардкода (source=hardcoded)
autogen.js: getNextTopic берёт из DB, fallback на TOPIC_BANK
admin API: GET/POST /blog-topics, DELETE /:id, POST /generate (AI +10)
routes/admin.js:
GET /autogen — настройки+статистика+очередь+размеры банков тем
PATCH /autogen/:category — enabled/per_day/run_hour/run_minute
POST /autogen/:category/run — ручной запуск генерации
POST /autogen/queue — добавить тему с приоритетом
DELETE /autogen/queue/:id — удалить тему
routes/admin.js: GET /logs — объединённые ошибки из 3 источников:
generation_jobs (status=failed), ai_usage (!succeeded), scheduled_posts (status=failed)
Сортировка по времени, топ-5 частых ошибок, группировка по типу
routes/admin.js: GET /queue (stats+recent30+stuck), POST /queue/:id/retry, DELETE /queue/stuck
stuck = processing > 5 min → сбрасываем в failed
retry = pending + requeue через Bull
DB: promo_codes, promo_usages tables
routes/admin.js: CRUD /api/admin/promos (GET/POST/PATCH/DELETE)
routes/billing.js: POST /api/billing/apply-promo
Валидация: exists, active, not expired, not exhausted, not used by this user
type=credits → начисляет через billing.credit()