Files
cannaiq/backend/dist/services/scheduler.js
Kelly 66e07b2009 fix(monitor): remove non-existent worker columns from job_run_logs query
The job_run_logs table tracks scheduled job orchestration, not individual
worker jobs. Worker info (worker_id, worker_hostname) belongs on
dispensary_crawl_jobs, not job_run_logs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:45:05 -07:00

105 lines
4.0 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.startScheduler = startScheduler;
exports.stopScheduler = stopScheduler;
exports.restartScheduler = restartScheduler;
exports.triggerStoreScrape = triggerStoreScrape;
exports.triggerAllStoresScrape = triggerAllStoresScrape;
const node_cron_1 = __importDefault(require("node-cron"));
const migrate_1 = require("../db/migrate");
const scraper_v2_1 = require("../scraper-v2");
let scheduledJobs = [];
async function getSettings() {
const result = await migrate_1.pool.query(`
SELECT key, value FROM settings
WHERE key IN ('scrape_interval_hours', 'scrape_specials_time')
`);
const settings = {};
result.rows.forEach((row) => {
settings[row.key] = row.value;
});
return {
scrapeIntervalHours: parseInt(settings.scrape_interval_hours || '4'),
scrapeSpecialsTime: settings.scrape_specials_time || '00:01'
};
}
async function scrapeAllStores() {
console.log('🔄 Starting scheduled scrape for all stores...');
const result = await migrate_1.pool.query(`
SELECT id, name FROM stores WHERE active = true AND scrape_enabled = true
`);
for (const store of result.rows) {
try {
console.log(`Scraping store: ${store.name}`);
await (0, scraper_v2_1.scrapeStore)(store.id);
}
catch (error) {
console.error(`Failed to scrape store ${store.name}:`, error);
}
}
console.log('✅ Scheduled scrape completed');
}
async function scrapeSpecials() {
console.log('🌟 Starting scheduled specials scrape...');
const result = await migrate_1.pool.query(`
SELECT s.id, s.name, c.id as category_id
FROM stores s
JOIN categories c ON c.store_id = s.id
WHERE s.active = true AND s.scrape_enabled = true
AND c.slug = 'specials' AND c.scrape_enabled = true
`);
for (const row of result.rows) {
try {
console.log(`Scraping specials for: ${row.name}`);
await (0, scraper_v2_1.scrapeCategory)(row.id, row.category_id);
}
catch (error) {
console.error(`Failed to scrape specials for ${row.name}:`, error);
}
}
console.log('✅ Specials scrape completed');
}
async function startScheduler() {
// Stop any existing jobs
stopScheduler();
const settings = await getSettings();
// Schedule regular store scrapes (every N hours)
const scrapeIntervalCron = `0 */${settings.scrapeIntervalHours} * * *`;
const storeJob = node_cron_1.default.schedule(scrapeIntervalCron, scrapeAllStores);
scheduledJobs.push(storeJob);
console.log(`📅 Scheduled store scraping: every ${settings.scrapeIntervalHours} hours`);
// Schedule specials scraping (daily at specified time)
const [hours, minutes] = settings.scrapeSpecialsTime.split(':');
const specialsCron = `${minutes} ${hours} * * *`;
const specialsJob = node_cron_1.default.schedule(specialsCron, scrapeSpecials);
scheduledJobs.push(specialsJob);
console.log(`📅 Scheduled specials scraping: daily at ${settings.scrapeSpecialsTime}`);
// Initial scrape on startup (after 10 seconds)
setTimeout(() => {
console.log('🚀 Running initial scrape...');
scrapeAllStores().catch(console.error);
}, 10000);
}
function stopScheduler() {
scheduledJobs.forEach(job => job.stop());
scheduledJobs = [];
console.log('🛑 Scheduler stopped');
}
async function restartScheduler() {
console.log('🔄 Restarting scheduler...');
stopScheduler();
await startScheduler();
}
// Manual trigger functions for admin
async function triggerStoreScrape(storeId) {
console.log(`🔧 Manual scrape triggered for store ID: ${storeId}`);
await (0, scraper_v2_1.scrapeStore)(storeId);
}
async function triggerAllStoresScrape() {
console.log('🔧 Manual scrape triggered for all stores');
await scrapeAllStores();
}