import { userPreferencesService } from '@/services/core/user-preferences'; import { JiraService } from './jira'; import { addMinutes, getToday } from '@/lib/date-utils'; export interface JiraSchedulerConfig { enabled: boolean; interval: 'hourly' | 'daily' | 'weekly'; } export class JiraScheduler { private timer: NodeJS.Timeout | null = null; private isRunning = false; /** * Démarre le planificateur de synchronisation Jira automatique */ async start(): Promise { if (this.isRunning) { console.log('⚠️ Jira scheduler is already running'); return; } const config = await this.getConfig(); if (!config.enabled) { console.log('📋 Automatic Jira sync is disabled'); return; } // Vérifier que Jira est configuré const jiraConfig = await userPreferencesService.getJiraConfig(); if (!jiraConfig.enabled || !jiraConfig.baseUrl || !jiraConfig.email || !jiraConfig.apiToken) { console.log('⚠️ Jira not configured, scheduler cannot start'); return; } const intervalMs = this.getIntervalMs(config.interval); // Première synchronisation immédiate (optionnelle) // this.performScheduledSync(); // Planifier les synchronisations suivantes this.timer = setInterval(() => { this.performScheduledSync(); }, intervalMs); this.isRunning = true; console.log(`✅ Jira scheduler started with ${config.interval} interval`); } /** * Arrête le planificateur */ stop(): void { if (this.timer) { clearInterval(this.timer); this.timer = null; } this.isRunning = false; console.log('🛑 Jira scheduler stopped'); } /** * Redémarre le planificateur (utile lors des changements de config) */ async restart(): Promise { this.stop(); await this.start(); } /** * Vérifie si le planificateur fonctionne */ isActive(): boolean { return this.isRunning && this.timer !== null; } /** * Effectue une synchronisation planifiée */ private async performScheduledSync(): Promise { try { console.log('🔄 Starting scheduled Jira sync...'); // Récupérer la config Jira const jiraConfig = await userPreferencesService.getJiraConfig(); if (!jiraConfig.enabled || !jiraConfig.baseUrl || !jiraConfig.email || !jiraConfig.apiToken) { console.log('⚠️ Jira config incomplete, skipping scheduled sync'); return; } // Créer le service Jira const jiraService = new JiraService({ enabled: jiraConfig.enabled, baseUrl: jiraConfig.baseUrl, email: jiraConfig.email, apiToken: jiraConfig.apiToken, projectKey: jiraConfig.projectKey, ignoredProjects: jiraConfig.ignoredProjects || [] }); // Tester la connexion d'abord const connectionOk = await jiraService.testConnection(); if (!connectionOk) { console.error('❌ Scheduled Jira sync failed: connection error'); return; } // Effectuer la synchronisation const result = await jiraService.syncTasks(); if (result.success) { console.log(`✅ Scheduled Jira sync completed: ${result.stats.created} created, ${result.stats.updated} updated, ${result.stats.skipped} skipped`); } else { console.error(`❌ Scheduled Jira sync failed: ${result.errors.join(', ')}`); } } catch (error) { console.error('❌ Scheduled Jira sync error:', error); } } /** * Convertit l'intervalle en millisecondes */ private getIntervalMs(interval: JiraSchedulerConfig['interval']): number { const intervals = { hourly: 60 * 60 * 1000, // 1 heure daily: 24 * 60 * 60 * 1000, // 24 heures weekly: 7 * 24 * 60 * 60 * 1000, // 7 jours }; return intervals[interval]; } /** * Obtient le prochain moment de synchronisation */ async getNextSyncTime(): Promise { if (!this.isRunning || !this.timer) { return null; } const config = await this.getConfig(); const intervalMs = this.getIntervalMs(config.interval); return addMinutes(getToday(), Math.floor(intervalMs / (1000 * 60))); } /** * Récupère la configuration du scheduler depuis les user preferences */ private async getConfig(): Promise { try { const [jiraConfig, schedulerConfig] = await Promise.all([ userPreferencesService.getJiraConfig(), userPreferencesService.getJiraSchedulerConfig() ]); return { enabled: schedulerConfig.jiraAutoSync && jiraConfig.enabled && !!jiraConfig.baseUrl && !!jiraConfig.email && !!jiraConfig.apiToken, interval: schedulerConfig.jiraSyncInterval }; } catch (error) { console.error('Error getting Jira scheduler config:', error); return { enabled: false, interval: 'daily' }; } } /** * Obtient les stats du planificateur */ async getStatus() { const config = await this.getConfig(); const jiraConfig = await userPreferencesService.getJiraConfig(); return { isRunning: this.isRunning, isEnabled: config.enabled, interval: config.interval, nextSync: await this.getNextSyncTime(), jiraConfigured: !!(jiraConfig.baseUrl && jiraConfig.email && jiraConfig.apiToken), }; } } // Instance singleton export const jiraScheduler = new JiraScheduler(); // Auto-start du scheduler // Démarrer avec un délai pour laisser l'app s'initialiser setTimeout(() => { console.log('🚀 Auto-starting Jira scheduler...'); jiraScheduler.start(); }, 6000); // 6 secondes, après le backup scheduler