← back to Watches
analytics/scheduler.js
130 lines
/**
* Analytics Report Scheduler
* Automatically generates reports on schedule
*/
import cron from 'node-cron';
import ReportGenerator from './report-generator.js';
class AnalyticsScheduler {
constructor(analyticsStore) {
this.analyticsStore = analyticsStore;
this.reportGenerator = new ReportGenerator(analyticsStore);
this.jobs = [];
}
/**
* Start all scheduled jobs
*/
start() {
console.log('Starting analytics scheduler...');
// Daily report - every day at 2 AM
const dailyJob = cron.schedule('0 2 * * *', async () => {
console.log('Generating daily report...');
try {
await this.reportGenerator.generateDailyReport();
console.log('Daily report generated successfully');
} catch (error) {
console.error('Failed to generate daily report:', error);
}
});
this.jobs.push({ name: 'daily_report', job: dailyJob });
// Weekly report - every Monday at 3 AM
const weeklyJob = cron.schedule('0 3 * * 1', async () => {
console.log('Generating weekly report...');
try {
await this.reportGenerator.generateWeeklyReport();
console.log('Weekly report generated successfully');
} catch (error) {
console.error('Failed to generate weekly report:', error);
}
});
this.jobs.push({ name: 'weekly_report', job: weeklyJob });
// Monthly report - first day of month at 4 AM
const monthlyJob = cron.schedule('0 4 1 * *', async () => {
console.log('Generating monthly report...');
try {
await this.reportGenerator.generateMonthlyReport();
console.log('Monthly report generated successfully');
} catch (error) {
console.error('Failed to generate monthly report:', error);
}
});
this.jobs.push({ name: 'monthly_report', job: monthlyJob });
// Hourly data backup - every hour
const backupJob = cron.schedule('0 * * * *', () => {
console.log('Backing up analytics data...');
// Trigger backup in analytics-server.js
});
this.jobs.push({ name: 'hourly_backup', job: backupJob });
console.log(`Analytics scheduler started with ${this.jobs.length} jobs`);
}
/**
* Stop all scheduled jobs
*/
stop() {
console.log('Stopping analytics scheduler...');
this.jobs.forEach(({ name, job }) => {
job.stop();
console.log(`Stopped job: ${name}`);
});
this.jobs = [];
}
/**
* Manually trigger a report
*/
async triggerReport(type) {
console.log(`Manually triggering ${type} report...`);
try {
switch (type) {
case 'daily':
await this.reportGenerator.generateDailyReport();
break;
case 'weekly':
await this.reportGenerator.generateWeeklyReport();
break;
case 'monthly':
await this.reportGenerator.generateMonthlyReport();
break;
default:
throw new Error(`Unknown report type: ${type}`);
}
console.log(`${type} report generated successfully`);
return true;
} catch (error) {
console.error(`Failed to generate ${type} report:`, error);
return false;
}
}
/**
* Get scheduler status
*/
getStatus() {
return {
running: this.jobs.length > 0,
jobs: this.jobs.map(({ name }) => name),
nextRuns: this.jobs.map(({ name, job }) => ({
name,
// Cron jobs don't expose next run time easily, would need separate library
status: 'scheduled'
}))
};
}
}
export default AnalyticsScheduler;