From 3feb23f67f2425d909cb5debfa676b1f147bf10b Mon Sep 17 00:00:00 2001 From: caadiq Date: Mon, 23 Feb 2026 15:27:16 +0900 Subject: [PATCH] =?UTF-8?q?fix(scheduler):=20=EB=B4=87=20=EC=A4=91?= =?UTF-8?q?=EC=A7=80=20=EC=83=81=ED=83=9C=EA=B0=80=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EC=9E=AC=EC=8B=9C=EC=9E=91=20=ED=9B=84=20=EC=9C=A0=EC=A7=80?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DB 조회 시 WHERE enabled = 1 필터를 제거하여 비활성 봇도 시스템에서 인식되도록 변경. 이전에는 비활성 봇이 목록/검색에서 완전히 제외되어 재시작 불가 및 관리 UI에서 사라지는 문제가 있었음. PUT 엔드포인트의 stopBot/startBot 조건 로직도 함께 정리. Co-Authored-By: Claude Opus 4.6 --- backend/src/plugins/scheduler.js | 21 +++++++++++++++++++-- backend/src/routes/admin/x-bots.js | 7 ++++--- backend/src/routes/admin/youtube-bots.js | 7 ++++--- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/backend/src/plugins/scheduler.js b/backend/src/plugins/scheduler.js index c7e485a..7db9623 100644 --- a/backend/src/plugins/scheduler.js +++ b/backend/src/plugins/scheduler.js @@ -16,7 +16,7 @@ async function schedulerPlugin(fastify, opts) { */ async function getYouTubeBotsFromDB() { const [rows] = await fastify.db.query( - 'SELECT * FROM bot_youtube WHERE enabled = 1' + 'SELECT * FROM bot_youtube' ); return rows.map(row => ({ id: `youtube-${row.id}`, // DB ID를 문자열 형식으로 변환 @@ -52,7 +52,7 @@ async function schedulerPlugin(fastify, opts) { */ async function getXBotsFromDB() { const [rows] = await fastify.db.query( - 'SELECT * FROM bot_x WHERE enabled = 1' + 'SELECT * FROM bot_x' ); return rows.map(row => ({ id: `x-${row.id}`, @@ -161,6 +161,18 @@ async function schedulerPlugin(fastify, opts) { return result.addedCount; } + /** + * DB의 enabled 필드 업데이트 (정적 봇은 무시) + */ + async function setEnabled(botId, enabled) { + const match = botId.match(/^(youtube|x)-(\d+)$/); + if (!match) return; // 정적 봇 (meilisearch 등) + const table = match[1] === 'x' ? 'bot_x' : 'bot_youtube'; + const dbId = match[2]; + await fastify.db.query(`UPDATE ${table} SET enabled = ? WHERE id = ?`, [enabled ? 1 : 0, dbId]); + invalidateCache(); + } + /** * 봇 시작 */ @@ -176,6 +188,9 @@ async function schedulerPlugin(fastify, opts) { tasks.delete(botId); } + // DB enabled 활성화 + await setEnabled(botId, true); + const syncFn = getSyncFunction(bot); if (!syncFn) { throw new Error(`지원하지 않는 봇 타입: ${bot.type}`); @@ -222,6 +237,8 @@ async function schedulerPlugin(fastify, opts) { tasks.get(botId).stop(); tasks.delete(botId); } + // DB enabled 비활성화 + await setEnabled(botId, false); await updateStatus(botId, { status: 'stopped' }); fastify.log.info(`[${botId}] 스케줄 정지`); } diff --git a/backend/src/routes/admin/x-bots.js b/backend/src/routes/admin/x-bots.js index e1b5d90..78bae28 100644 --- a/backend/src/routes/admin/x-bots.js +++ b/backend/src/routes/admin/x-bots.js @@ -327,11 +327,12 @@ export default async function xBotsRoutes(fastify) { // 스케줄러 캐시 무효화 및 봇 재시작 scheduler.invalidateCache(); const botId = `x-${id}`; + const shouldBeEnabled = updates.enabled !== undefined + ? updates.enabled + : existing[0].enabled === 1; try { await scheduler.stopBot(botId); - if (updates.enabled !== false && existing[0].enabled === 1) { - await scheduler.startBot(botId); - } else if (updates.enabled === true) { + if (shouldBeEnabled) { await scheduler.startBot(botId); } } catch (err) { diff --git a/backend/src/routes/admin/youtube-bots.js b/backend/src/routes/admin/youtube-bots.js index 71fe98a..6b1c026 100644 --- a/backend/src/routes/admin/youtube-bots.js +++ b/backend/src/routes/admin/youtube-bots.js @@ -334,11 +334,12 @@ export default async function youtubeBotsRoutes(fastify) { // 스케줄러 캐시 무효화 및 봇 재시작 scheduler.invalidateCache(); const botId = `youtube-${id}`; + const shouldBeEnabled = updates.enabled !== undefined + ? updates.enabled + : existing[0].enabled === 1; try { await scheduler.stopBot(botId); - if (updates.enabled !== false && existing[0].enabled === 1) { - await scheduler.startBot(botId); - } else if (updates.enabled === true) { + if (shouldBeEnabled) { await scheduler.startBot(botId); } } catch (err) {