# Guida Utente - Schedulazione a Intervalli ## 🎯 **Come Creare una Schedulazione a Intervalli** ### Opzione 1: Tramite UI (Quando Implementata) 1. **Naviga alla sezione Schedulazioni** - Menu β†’ Schedulazioni 2. **Clicca "Nuova Schedulazione"** 3. **Compila il Form** ``` Nome: [Nome descrittivo] Profilo: [Seleziona profilo esistente] Tipo: [Seleziona "A Intervalli"] β†’ Appare configurazione intervalli: Valore Intervallo: [Numero] (es. 5, 10, 30) UnitΓ : [Seleziona] - Secondi - Minuti ← Raccomandato - Ore - Giorni - Settimane - Mesi ``` 4. **Salva e Attiva** - βœ… Abilita Schedulazione - Salva --- ### Opzione 2: Tramite Database Diretto ```sql -- Inserisci nuova schedulazione a intervalli INSERT INTO ProfileSchedules ( Name, Description, ProfileId, IsEnabled, ScheduleType, IntervalValue, IntervalUnit, IsActive, CreatedAt, CreatedBy ) VALUES ( 'Sync Clienti Ogni 5 Minuti', -- Nome 'Sincronizzazione automatica clienti', -- Descrizione 1, -- ID del profilo esistente 1, -- Abilitata (1 = true) 'interval', -- Tipo schedulazione 5, -- Valore intervallo 'minutes', -- UnitΓ  intervallo 1, -- Attiva (1 = true) datetime('now'), -- Data creazione 'Admin' -- Creato da ); ``` --- ### Opzione 3: Tramite API/Service (C#) ```csharp using CredentialManager.Services; using CredentialManager.Models; // Inject IProfileScheduleService var schedule = new ProfileSchedule { Name = "Sync Prodotti Ogni 10 Minuti", Description = "Sincronizzazione automatica prodotti", ProfileId = 2, // ID profilo esistente ScheduleType = "interval", IntervalValue = 10, IntervalUnit = "minutes", IsEnabled = true, IsActive = true }; var created = await scheduleService.CreateScheduleAsync(schedule); Console.WriteLine($"Schedulazione creata con ID: {created.Id}"); Console.WriteLine($"Prossima esecuzione: {created.NextExecutionTime}"); ``` --- ## πŸ“‹ **Esempi di Configurazione Comuni** ### πŸ”΅ Sincronizzazione Frequente (Ogni 5 Minuti) **Caso d'uso**: Dati che cambiano frequentemente (ordini, inventario real-time) ```sql IntervalValue: 5 IntervalUnit: minutes ``` **Esecuzione**: 10:00, 10:05, 10:10, 10:15, 10:20, ... --- ### 🟒 Sincronizzazione Oraria (Ogni 1 Ora) **Caso d'uso**: Report, statistiche, aggregazioni ```sql IntervalValue: 1 IntervalUnit: hours ``` **Esecuzione**: 08:00, 09:00, 10:00, 11:00, 12:00, ... --- ### 🟑 Backup Semi-Orario (Ogni 30 Minuti) **Caso d'uso**: Backup incrementali, snapshot dati ```sql IntervalValue: 30 IntervalUnit: minutes ``` **Esecuzione**: 08:00, 08:30, 09:00, 09:30, 10:00, ... --- ### πŸ”΄ Test Rapido (Ogni 30 Secondi) **Caso d'uso**: Test, debugging, demo ```sql IntervalValue: 30 IntervalUnit: seconds ``` **Esecuzione**: 14:30:00, 14:30:30, 14:31:00, 14:31:30, ... ⚠️ **Solo per ambienti di test!** --- ### 🟣 Sincronizzazione Giornaliera (Ogni 2 Giorni) **Caso d'uso**: Archivi, dati storici, backup completi ```sql IntervalValue: 2 IntervalUnit: days ``` **Esecuzione**: 01/10 00:00, 03/10 00:00, 05/10 00:00, ... --- ### 🟠 Report Settimanale (Ogni 1 Settimana) **Caso d'uso**: Report settimanali, consolidamenti ```sql IntervalValue: 1 IntervalUnit: weeks ``` **Esecuzione**: 01/10, 08/10, 15/10, 22/10, 29/10, ... --- ### ⚫ Archivio Mensile (Ogni 1 Mese) **Caso d'uso**: Archiviazioni mensili, report fiscali ```sql IntervalValue: 1 IntervalUnit: months ``` **Esecuzione**: 01/10, 01/11, 01/12, 01/01, ... --- ## πŸ” **Come Verificare una Schedulazione** ### Query di Controllo ```sql -- Verifica schedulazione creata SELECT Id, Name, ScheduleType, IntervalValue, IntervalUnit, CONCAT(IntervalValue, ' ', IntervalUnit) as Interval, IsEnabled, IsActive, LastExecutionTime, NextExecutionTime, LastExecutionStatus FROM ProfileSchedules WHERE ScheduleType = 'interval' ORDER BY Id DESC; ``` ### Verifica Prossima Esecuzione ```sql -- Schedulazioni che verranno eseguite nei prossimi 10 minuti SELECT Id, Name, NextExecutionTime, ROUND((JULIANDAY(NextExecutionTime) - JULIANDAY('now')) * 24 * 60, 1) as MinutesToNext FROM ProfileSchedules WHERE IsEnabled = 1 AND IsActive = 1 AND NextExecutionTime <= datetime('now', '+10 minutes') ORDER BY NextExecutionTime; ``` --- ## πŸ“Š **Monitoraggio Esecuzioni** ### Storico Ultime Esecuzioni ```sql SELECT s.Name as ScheduleName, h.StartTime, h.EndTime, ROUND((JULIANDAY(h.EndTime) - JULIANDAY(h.StartTime)) * 24 * 60, 2) as DurationMinutes, h.Status, h.RecordsProcessed, h.Message FROM ScheduleExecutionHistory h JOIN ProfileSchedules s ON h.ScheduleId = s.Id WHERE s.ScheduleType = 'interval' ORDER BY h.StartTime DESC LIMIT 20; ``` ### Statistiche per Schedulazione ```sql SELECT s.Name, s.ScheduleType, CONCAT(s.IntervalValue, ' ', s.IntervalUnit) as Interval, COUNT(h.Id) as TotalExecutions, SUM(CASE WHEN h.Status = 'success' THEN 1 ELSE 0 END) as Successes, SUM(CASE WHEN h.Status = 'failed' THEN 1 ELSE 0 END) as Failures, AVG(ROUND((JULIANDAY(h.EndTime) - JULIANDAY(h.StartTime)) * 24 * 60, 2)) as AvgDurationMinutes, SUM(h.RecordsProcessed) as TotalRecords FROM ProfileSchedules s LEFT JOIN ScheduleExecutionHistory h ON s.Id = h.ScheduleId WHERE s.ScheduleType = 'interval' AND h.StartTime >= datetime('now', '-24 hours') GROUP BY s.Id, s.Name, s.ScheduleType, s.IntervalValue, s.IntervalUnit ORDER BY TotalExecutions DESC; ``` --- ## πŸ› οΈ **Gestione Schedulazioni** ### Disabilitare Temporaneamente ```sql -- Disabilita schedulazione (mantiene configurazione) UPDATE ProfileSchedules SET IsEnabled = 0 WHERE Id = 1; ``` ### Modificare Intervallo ```sql -- Cambia da 5 minuti a 10 minuti UPDATE ProfileSchedules SET IntervalValue = 10, UpdatedAt = datetime('now') WHERE Id = 1; ``` ### Cambiare UnitΓ  di Tempo ```sql -- Cambia da minuti a ore UPDATE ProfileSchedules SET IntervalValue = 1, IntervalUnit = 'hours', UpdatedAt = datetime('now') WHERE Id = 1; ``` ### Riattivare Schedulazione ```sql -- Riattiva schedulazione disabilitata UPDATE ProfileSchedules SET IsEnabled = 1, NextExecutionTime = datetime('now'), -- Esegue subito UpdatedAt = datetime('now') WHERE Id = 1; ``` ### Eliminare Schedulazione ```sql -- Disattiva definitivamente (soft delete) UPDATE ProfileSchedules SET IsActive = 0, IsEnabled = 0, UpdatedAt = datetime('now') WHERE Id = 1; -- Oppure elimina fisicamente DELETE FROM ProfileSchedules WHERE Id = 1; ``` --- ## ⚠️ **Troubleshooting** ### Schedulazione Non Eseguita **Possibili Cause**: 1. **Schedulazione disabilitata** ```sql SELECT IsEnabled, IsActive FROM ProfileSchedules WHERE Id = X; ``` Soluzione: `UPDATE ProfileSchedules SET IsEnabled = 1 WHERE Id = X;` 2. **NextExecutionTime nel futuro** ```sql SELECT NextExecutionTime, datetime('now') as Now FROM ProfileSchedules WHERE Id = X; ``` Soluzione: Attendi orario programmato o aggiorna manualmente 3. **Background service non avviato** - Verifica logs applicazione - Controlla che `ScheduledJobService` sia running 4. **Profilo non valido** ```sql SELECT p.* FROM ProfileSchedules s LEFT JOIN DataCouplerProfiles p ON s.ProfileId = p.Id WHERE s.Id = X; ``` Soluzione: Verifica che il profilo esista e sia configurato --- ### Schedulazione Eseguita Troppo Frequentemente **Causa**: Intervallo troppo breve per la durata dell'esecuzione **Soluzione**: 1. Aumenta intervallo 2. Ottimizza profilo (meno dati, filtri migliori) 3. Monitora durata: ```sql SELECT ROUND((JULIANDAY(EndTime) - JULIANDAY(StartTime)) * 24 * 60, 2) as Minutes FROM ScheduleExecutionHistory WHERE ScheduleId = X ORDER BY StartTime DESC LIMIT 10; ``` --- ### Schedulazione Bloccata (Running >1 Ora) **Verifica**: ```sql SELECT Id, Name, LastExecutionStatus, LastExecutionTime, ROUND((JULIANDAY('now') - JULIANDAY(LastExecutionTime)) * 24, 1) as HoursSince FROM ProfileSchedules WHERE LastExecutionStatus = 'running' AND LastExecutionTime < datetime('now', '-1 hour'); ``` **Soluzione**: ```sql -- Reset manuale status UPDATE ProfileSchedules SET LastExecutionStatus = 'failed', LastExecutionMessage = 'Timeout manuale - esecuzione bloccata', NextExecutionTime = datetime('now', '+5 minutes') WHERE Id = X; ``` --- ## πŸ“ **Best Practices** ### βœ… Raccomandazioni 1. **Intervalli Minimi Produzione**: 5-10 minuti 2. **Test prima di produzione**: Prova con intervalli brevi in staging 3. **Monitora durata**: Assicurati che esecuzione < intervallo 4. **Usa descrizioni chiare**: Facilita troubleshooting 5. **Backup prima di modifiche**: Salva configurazioni funzionanti ### ❌ Da Evitare 1. **Intervalli <1 minuto in produzione** (carico eccessivo) 2. **Troppi intervalli brevi contemporanei** (saturazione risorse) 3. **Modificare schedulazioni running** (rischio inconsistenza) 4. **Eliminare senza disabilitare prima** (perdita log esecuzioni) --- ## πŸ†˜ **Supporto** ### Logs Applicazione **Windows Event Log**: ```powershell Get-EventLog -LogName Application -Source "ScheduledJobService" -Newest 50 ``` **File Log** (se configurato): ```powershell Get-Content logs/datacoupler.log -Tail 100 ``` ### Query Debug ```sql -- Overview completa schedulazione SELECT s.*, p.Name as ProfileName, p.SourceType, p.DestinationType, (SELECT COUNT(*) FROM ScheduleExecutionHistory WHERE ScheduleId = s.Id) as TotalExecutions, (SELECT COUNT(*) FROM ScheduleExecutionHistory WHERE ScheduleId = s.Id AND Status = 'success') as SuccessCount, (SELECT MAX(StartTime) FROM ScheduleExecutionHistory WHERE ScheduleId = s.Id) as LastActualExecution FROM ProfileSchedules s LEFT JOIN DataCouplerProfiles p ON s.ProfileId = p.Id WHERE s.Id = X; ``` --- **Versione**: 2.0 **Ultimo Aggiornamento**: 2 Ottobre 2025 **Documentazione Tecnica**: ADVANCED_SCHEDULING_SYSTEM.md