fix(autogen): устранить дубли черновиков и накопление backlog

- autogen: атомарный захват категорий (UPDATE ... RETURNING, last_run_at
  ставится ДО генерации), окно ±5 -> ±2 мин. Убирает дубли одной категории
  (advisory-lock на пуле не сериализовал, last_run_at ставился после ~90с гена).
- draftAutoApprove: дренаж backlog — 4 старейших черновика/день, не трогая
  сегодняшнюю свежую партию. Раньше брало строго 'вчера' + LIMIT 4, остальное
  копилось навсегда.
- articles: guard минимальной длины (800 симв) — не сохранять обрезки в draft
  (куцые digest с веб-поиском).
- drafts route: GET /api/drafts/:id с полным content (чтение статьи целиком).
- promptBuilder: запрет однообразных временных зачинов ('...назад').
This commit is contained in:
Alexey Pavlov
2026-06-30 00:58:01 +03:00
parent 4694093080
commit 4a11c63ed5
5 changed files with 67 additions and 19 deletions
+9 -8
View File
@@ -43,14 +43,16 @@ async function getTodaySlots() {
async function runDraftAutoApprove() {
try {
// Берём черновики созданные ВЧЕРА по МСК (между 00:00 и 23:59 вчера).
// Строго только вчерашние — чтобы при повторном деплое/рестарте не захватить
// старые черновики и не создать очередь на несколько дней.
// Берём самые СТАРЫЕ черновики, созданные НЕ сегодня (по МСК).
// Раньше окно было «строго вчера» + LIMIT 4 — поэтому всё, что не одобрили
// на следующий день (дубли, излишки), оставалось в draft навсегда и копилось.
// Теперь дренируем backlog по 4 старейших в день, при этом сегодняшнюю свежую
// партию не трогаем (она станет доступна завтра). В связке с дедупом автогена
// (макс 4/день) это даёт устойчивое состояние без накопления.
const { rows: drafts } = await query(
`SELECT id, title, category, created_at FROM articles
WHERE status='draft'
AND created_at AT TIME ZONE 'Europe/Moscow' >= (CURRENT_DATE - INTERVAL '1 day')::date
AND created_at AT TIME ZONE 'Europe/Moscow' < CURRENT_DATE::date
AND created_at AT TIME ZONE 'Europe/Moscow' < CURRENT_DATE::date
ORDER BY created_at ASC
LIMIT 4`
);
@@ -111,7 +113,7 @@ async function runDraftAutoApprove() {
}
function startDraftAutoApproveScheduler() {
console.log('[DraftApprove] scheduler started (auto-approve at 07:00 MSK, только вчерашние черновики)');
console.log('[DraftApprove] scheduler started (auto-approve at 07:00 MSK, дренаж backlog: 4 старейших/день, не трогая сегодняшние)');
// Catch-up при старте: если сейчас уже после AUTO_APPROVE_HOUR_MSK —
// проверить есть ли вчерашние черновики которые пропустили тик.
@@ -123,8 +125,7 @@ function startDraftAutoApproveScheduler() {
const { rows: missed } = await query(`
SELECT COUNT(*) AS cnt FROM articles
WHERE status='draft'
AND created_at AT TIME ZONE 'Europe/Moscow' >= (CURRENT_DATE - INTERVAL '1 day')::date
AND created_at AT TIME ZONE 'Europe/Moscow' < CURRENT_DATE::date
AND created_at AT TIME ZONE 'Europe/Moscow' < CURRENT_DATE::date
`);
if (parseInt(missed[0]?.cnt, 10) > 0) {
console.log('[DraftApprove] catch-up при старте: найдены пропущенные вчерашние черновики (' + missed[0].cnt + ' шт)');