Commit Graph

12 Commits

Author SHA1 Message Date
Aleksei Pavlov 90f6b474a1 fix(autogen): remove sort_order from ORDER BY — column doesn't exist in autogen_settings
Critical: every runAutogen tick was failing with 'column sort_order does not exist'
since deploy of rotation feature. This means NO articles were generated on Jun 22
and draftAutoApprove also failed on Jun 23 07:00.

autogen_settings has no sort_order column — use ORDER BY category instead.
2026-06-23 10:11:51 +03:00
Aleksei Pavlov 1f25adff00 feat(autogen): ротация 4 из 8 категорий по дням
Каждый день генерируем 4 из 8 категорий по скользящему окну:
  День 1: cat[0..3], День 2: cat[1..4], ..., День 8: cat[7,0,1,2]

Логика: dayOfYear % totalCategories = сдвиг окна.
За 8 дней каждая категория выходит 4 раза, каждый день — новый набор.

getAutogenStatus теперь возвращает today_active=true/false — входит
ли категория в сегодняшнюю ротацию.

Слоты публикации откатаны к 4 (08:11/12:11/16:11/20:11).
2026-06-21 21:55:32 +03:00
Aleksei Pavlov 174c3a17c1 feat(autogen): next_topic в статусе — следующая тема для каждой категории 2026-06-21 21:38:12 +03:00
Aleksei Pavlov 1ced06fa2d fix(autogen): pg_advisory_lock + catch-up + double-check after lock
Race condition (дубли статей) устранён окончательно:

1. pg_advisory_lock по ключу категории в начале runAutogenForCategory —
   если два процесса запускаются одновременно, второй ждёт первого.
   pg_advisory_unlock в finally — освобождается всегда, даже при ошибке.

2. После получения lock — повторная проверка 'уже генерировали сегодня'
   (SELECT articles WHERE category AND created_at >= CURRENT_DATE).
   Если да — skip без генерации. Это защита от случая когда первый процесс
   завершился пока второй ждал lock.

3. draftAutoApprove catch-up при старте: если engine стартовал после 07:00
   и есть непрогнанные вчерашние черновики — одобряет их сразу.
   Раньше deploy в 07:27 приводил к тому что черновики зависали навсегда.
2026-06-21 21:30:06 +03:00
Aleksei Pavlov f40bb27953 fix(autogen/status): показываем topic_count_free/total из blog_topics
getAutogenStatus теперь считает:
  - topic_count_free: свободных тем для генерации
  - topic_count: всего тем в банке
  - drafts_today: черновиков созданных за 24ч
  - cat_icon, cat_color: из таблицы categories

Убрана ссылка на несуществующую content_queue (queue_count).
2026-06-21 21:08:29 +03:00
Aleksei Pavlov c920d3bcd5 fix(autogen): атомарный захват темы — исключает дубли статей
Проблема: одна и та же тема из blog_topics использовалась несколько раз
(см. 7 дублей в БД). Причина: getNextTopic читал is_used=false, возвращал
тему, но помечал её использованной только ПОСЛЕ INSERT статьи (через 30-60 сек
пока AI генерирует текст). За это время повторный запуск видел ту же is_used=false
и выбирал её снова.

Фикс: атомарная операция UPDATE...RETURNING с FOR UPDATE SKIP LOCKED —
тема помечается is_used=true В МОМЕНТ ВЫБОРА, до вызова AI.
Параллельные или повторные запуски видят is_used=true и пропускают тему.

Дополнительно: fallback TOPIC_BANK теперь перемешивает пул случайно
(вместо Math.random() на весь массив) — более равномерное распределение.
2026-06-21 16:47:49 +03:00
Nik (Claude) 5852b9f439 feat: draft review flow — autogen→draft, auto-approve 07:00 MSK, /api/drafts routes 2026-06-16 09:17:10 +03:00
Ник (Claude) c40ef90ad1 feat: SMTP, maintenance mode, blog topic bank UI
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)
2026-06-13 11:45:23 +03:00
Ник (Claude) 7a70f79e61 fix: duplicate article prevention — source_topic deduplication
autogen.js: getNextTopic() теперь проверяет source_topic (exact match) вместо
  сравнения первых 20 символов заголовка (который AI переименовывает)
articles.js: INSERT сохраняет source_topic из topic параметра
DB: articles.source_topic TEXT, articles.topic_hash VARCHAR(64)
Пометили существующие дубли: article 61 → archived, source_topic заполнен
2026-06-12 11:49:33 +03:00
Nik (Claude) a370b8f7d8 feat: Зеро-персонаж, auto-publish, auto-series, channel-stats, fallback covers
- Персонаж Зеро: 23 позы (zeroCharacter.js), скрипты генерации
- Auto-publish статей в TG: multipart upload, кнопки, режим alternating Zero/cover
- Fallback цепочка обложек: aiprimetech gpt-5.5 → Pollinations → local SVG (6 палитр)
- Auto-series: Claude haiku определяет серию для каждой статьи автоматически
- Channel stats: подписчики, история, delta 24h/7d
- Photo-search: Yandex API, профили доменов, Redis лимиты
- Scheduled posts runner: backfill, preview, queue, cancel
- promptBuilder: author_persona Зеро, голос от первого лица
- Fixes: dollar-placeholder bugs в PATCH channels/autogen, listArticles фильтры
- AI model: gpt-5.5 для image generation
2026-06-07 14:03:56 +03:00
Alexey Pavlov 213dc104f5 feat: autogen run_hour/run_minute, publish_slots, scheduled_posts tables and routes 2026-05-31 16:45:15 +03:00
Alexey Pavlov 3372574b32 feat: autogen service — content_queue, autogen_settings, TOPIC_BANK, cron API 2026-05-31 14:48:38 +03:00