From 793627b04651e93f137432e9f88123c2b94d8d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Wed, 12 Aug 2026 09:14:33 -0300 Subject: [PATCH] Run Olist sync daily at 10am --- backend/config.js | 2 +- backend/services/olistService.js | 40 +++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/backend/config.js b/backend/config.js index 20689ca..5b3f02c 100644 --- a/backend/config.js +++ b/backend/config.js @@ -43,7 +43,7 @@ module.exports = { OLIST_FRONTEND_URL: process.env.OLIST_FRONTEND_URL || '', OLIST_TOKEN_ENCRYPTION_KEY: process.env.OLIST_TOKEN_ENCRYPTION_KEY || '', OLIST_SYNC_ENABLED: process.env.OLIST_SYNC_ENABLED === 'true', - OLIST_SYNC_INTERVAL_MS: Number(process.env.OLIST_SYNC_INTERVAL_MS) || 24 * 60 * 60 * 1000, + OLIST_SYNC_HOUR: 10, OLIST_SYNC_REQUEST_DELAY_MS: Math.max(2_500, Number(process.env.OLIST_SYNC_REQUEST_DELAY_MS) || 2_500), TURNSTILE_SITE_KEY, TURNSTILE_SECRET diff --git a/backend/services/olistService.js b/backend/services/olistService.js index 424e382..8a28c6b 100644 --- a/backend/services/olistService.js +++ b/backend/services/olistService.js @@ -5,7 +5,7 @@ const { OLIST_CLIENT_SECRET, OLIST_FRONTEND_URL, OLIST_REDIRECT_URI, - OLIST_SYNC_INTERVAL_MS, + OLIST_SYNC_HOUR, OLIST_SYNC_REQUEST_DELAY_MS, OLIST_TOKEN_ENCRYPTION_KEY } = require('../config'); @@ -111,15 +111,27 @@ const listSyncRuns = async (limit = 5) => { return result.rows.map(mapRun); }; -const getLastCompletedSyncAt = async () => { +const hasScheduledSyncToday = async () => { const result = await pool.query(` - SELECT completed_at - FROM olist_sync_runs - WHERE status = 'completed' AND completed_at IS NOT NULL - ORDER BY completed_at DESC - LIMIT 1; + SELECT EXISTS ( + SELECT 1 + FROM olist_sync_runs + WHERE trigger = 'scheduled' + AND started_at >= (date_trunc('day', CURRENT_TIMESTAMP AT TIME ZONE 'America/Sao_Paulo') AT TIME ZONE 'America/Sao_Paulo') + ) AS exists; `); - return result.rows[0]?.completed_at || null; + return Boolean(result.rows[0]?.exists); +}; + +const getTodayOlistRunAt = () => { + const parts = new Intl.DateTimeFormat('en-CA', { + timeZone: 'America/Sao_Paulo', + year: 'numeric', + month: '2-digit', + day: '2-digit' + }).formatToParts(new Date()); + const value = (type) => parts.find(part => part.type === type)?.value; + return new Date(`${value('year')}-${value('month')}-${value('day')}T${String(OLIST_SYNC_HOUR).padStart(2, '0')}:00:00-03:00`); }; const logRunEvent = async (runId, { @@ -707,15 +719,15 @@ const requestOlistSyncStop = async () => { const scheduleOlistSync = async () => { if (scheduledSync) clearTimeout(scheduledSync); - let delay = OLIST_SYNC_INTERVAL_MS; + let scheduledRunAt = getTodayOlistRunAt(); + let delay = Math.max(0, scheduledRunAt.getTime() - Date.now()); try { - const lastCompletedAt = await getLastCompletedSyncAt(); - const lastCompletedMs = lastCompletedAt ? new Date(lastCompletedAt).getTime() : Number.NaN; - if (!Number.isNaN(lastCompletedMs)) { - delay = Math.max(0, lastCompletedMs + OLIST_SYNC_INTERVAL_MS - Date.now()); + if (delay === 0 && await hasScheduledSyncToday()) { + scheduledRunAt.setUTCDate(scheduledRunAt.getUTCDate() + 1); + delay = scheduledRunAt.getTime() - Date.now(); } } catch (error) { - console.error('Could not calculate the next Olist sync:', error.message); + console.error('Could not calculate the next daily Olist sync:', error.message); } nextScheduledSyncAt = new Date(Date.now() + delay).toISOString();