diff --git a/src/services/scheduledPostsRunner.js b/src/services/scheduledPostsRunner.js index a422934..64a77c0 100644 --- a/src/services/scheduledPostsRunner.js +++ b/src/services/scheduledPostsRunner.js @@ -229,10 +229,24 @@ async function publishOne(scheduledPost) { : `https://zeropost.ru${article.cover_url}`; console.log(`[scheduled-runner] cover=${article.cover_url.split('/').pop()} article=${article.id}`); } else { + const attempts = scheduledPost.cover_regen_attempts || 0; + const MAX_REGEN_ATTEMPTS = 3; // 3 × 15 мин = 45 мин максимум ждём + if (attempts < MAX_REGEN_ATTEMPTS) { + // Откладываем пост на 15 минут, не публикуем + const retryAt = new Date(Date.now() + 15 * 60_000); + await query( + `UPDATE scheduled_posts SET scheduled_at=$1, cover_regen_attempts=$2 WHERE id=$3`, + [retryAt, attempts + 1, scheduledPost.id] + ); + console.log(`[scheduled-runner] SVG stub — delayed 15min (attempt ${attempts+1}/${MAX_REGEN_ATTEMPTS}) post=${scheduledPost.id} article=${article.id}`); + return; // не публикуем сейчас + } + // Исчерпали попытки — публикуем с Зеро чтобы пост не завис навсегда + console.log(`[scheduled-runner] SVG stub max attempts reached, using Zero article=${article.id}`); const picked = zeroChar.pickPose({ title: article.title, excerpt: article.excerpt, category: article.category }); if (picked.exists) { photoUrl = `/uploads/zero-${picked.pose}.webp`; - console.log(`[scheduled-runner] SVG fallback → Zero pose=${picked.pose} article=${article.id}`); + console.log(`[scheduled-runner] Zero fallback pose=${picked.pose} article=${article.id}`); } } } else {