Files
Data-Coupler/CredentialManager/Models/ProfileSchedule.cs
T
Alessio Dal Santo e35de1614f [Feature] Disabilitata deletion sync nei trasferimenti manuali e aggiunta configurazione nelle schedulazioni
- Disabilitata completamente la sincronizzazione eliminazioni nei trasferimenti manuali (DataCoupler.razor.cs)
- Aggiunto campo EnableDeletionSync al modello ProfileSchedule (default: false)
- Implementata logica condizionale in ScheduledProfileExecutionService per deletion sync
- Aggiunta sezione 'Opzioni Avanzate' nell'interfaccia schedulazione con warning
- Creata migration Entity Framework AddEnableDeletionSyncToProfileSchedule
- Aggiornato BackupModels per supporto backup/restore del nuovo campo
- Aggiornata documentazione README.md e copilot-instructions.md
- La deletion sync è ora disponibile solo per schedulazioni con configurazione esplicita per massima sicurezza
2026-01-23 15:52:15 +01:00

231 lines
7.7 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace CredentialManager.Models;
/// <summary>
/// Modello per la schedulazione dei profili Data Coupler
/// </summary>
public class ProfileSchedule
{
[Key]
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; } = string.Empty;
[MaxLength(500)]
public string? Description { get; set; }
// Relazione con il profilo
[Required]
public int ProfileId { get; set; }
[ForeignKey(nameof(ProfileId))]
public virtual DataCouplerProfile Profile { get; set; } = null!;
// Configurazione scheduling
[Required]
public bool IsEnabled { get; set; } = true;
[Required]
[MaxLength(20)]
public string ScheduleType { get; set; } = string.Empty; // "once", "daily", "weekly", "monthly", "interval"
public DateTime? ScheduledDateTime { get; set; } // Per schedulazioni "once"
[MaxLength(10)]
public string? DailyTime { get; set; } // Format "HH:mm" per schedulazioni ricorrenti
public int? DayOfWeek { get; set; } // 0-6 per schedulazioni settimanali (0=Domenica)
public int? DayOfMonth { get; set; } // 1-31 per schedulazioni mensili
// Configurazione per schedulazioni a intervalli
public int? IntervalValue { get; set; } // Valore dell'intervallo (es. 5, 10, 30)
[MaxLength(20)]
public string? IntervalUnit { get; set; } // "seconds", "minutes", "hours", "days", "weeks", "months"
// Tracking delle esecuzioni
public DateTime? LastExecutionTime { get; set; }
public DateTime? NextExecutionTime { get; set; }
public int ExecutionCount { get; set; } = 0;
[MaxLength(20)]
public string LastExecutionStatus { get; set; } = string.Empty; // "success", "failed", "running"
[MaxLength(1000)]
public string? LastExecutionMessage { get; set; }
public int? LastExecutionRecordCount { get; set; }
// Configurazione override per database sources
[MaxLength(100)]
public string? SourceDatabaseOverride { get; set; }
[MaxLength(100)]
public string? DestinationDatabaseOverride { get; set; }
// Configurazione sincronizzazione eliminazioni (default: disabilitata)
public bool EnableDeletionSync { get; set; } = false;
// Metadati
[MaxLength(100)]
public string? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = true;
// Metodi helper per calcolare la prossima esecuzione
public DateTime? CalculateNextExecution()
{
if (!IsEnabled || !IsActive)
return null;
var now = DateTime.Now;
return ScheduleType switch
{
"once" => ScheduledDateTime > now ? ScheduledDateTime : null,
"daily" when !string.IsNullOrEmpty(DailyTime) => CalculateNextDaily(now),
"weekly" when DayOfWeek.HasValue && !string.IsNullOrEmpty(DailyTime) => CalculateNextWeekly(now),
"monthly" when DayOfMonth.HasValue && !string.IsNullOrEmpty(DailyTime) => CalculateNextMonthly(now),
"interval" when IntervalValue.HasValue && !string.IsNullOrEmpty(IntervalUnit) => CalculateNextInterval(now),
_ => null
};
}
public DateTime? CalculateNextExecutionFromLast()
{
if (!IsEnabled || !IsActive)
return null;
// Per intervalli, calcola dalla ultima esecuzione (o da ora se mai eseguito)
if (ScheduleType == "interval" && IntervalValue.HasValue && !string.IsNullOrEmpty(IntervalUnit))
{
var baseTime = LastExecutionTime ?? DateTime.Now;
return CalculateNextInterval(baseTime);
}
// Per altri tipi, usa CalculateNextExecution normale
return CalculateNextExecution();
}
private DateTime CalculateNextDaily(DateTime now)
{
var time = TimeSpan.Parse(DailyTime!);
var today = now.Date.Add(time);
return today > now ? today : today.AddDays(1);
}
private DateTime CalculateNextWeekly(DateTime now)
{
var time = TimeSpan.Parse(DailyTime!);
var targetDayOfWeek = (DayOfWeek)DayOfWeek!;
var daysUntilTarget = ((int)targetDayOfWeek - (int)now.DayOfWeek + 7) % 7;
if (daysUntilTarget == 0)
{
// È oggi, controlla se l'orario è già passato
var todayAtTime = now.Date.Add(time);
if (todayAtTime > now)
return todayAtTime;
else
daysUntilTarget = 7; // Prossima settimana
}
return now.Date.AddDays(daysUntilTarget).Add(time);
}
private DateTime CalculateNextMonthly(DateTime now)
{
var time = TimeSpan.Parse(DailyTime!);
var targetDay = DayOfMonth!.Value;
var thisMonth = new DateTime(now.Year, now.Month, Math.Min(targetDay, DateTime.DaysInMonth(now.Year, now.Month))).Add(time);
if (thisMonth > now)
return thisMonth;
// Prossimo mese
var nextMonth = now.AddMonths(1);
return new DateTime(nextMonth.Year, nextMonth.Month, Math.Min(targetDay, DateTime.DaysInMonth(nextMonth.Year, nextMonth.Month))).Add(time);
}
private DateTime CalculateNextInterval(DateTime baseTime)
{
if (!IntervalValue.HasValue || string.IsNullOrEmpty(IntervalUnit))
return baseTime;
return IntervalUnit.ToLower() switch
{
"seconds" => baseTime.AddSeconds(IntervalValue.Value),
"minutes" => baseTime.AddMinutes(IntervalValue.Value),
"hours" => baseTime.AddHours(IntervalValue.Value),
"days" => baseTime.AddDays(IntervalValue.Value),
"weeks" => baseTime.AddDays(IntervalValue.Value * 7),
"months" => baseTime.AddMonths(IntervalValue.Value),
_ => baseTime
};
}
/// <summary>
/// Ottiene una descrizione leggibile della schedulazione
/// </summary>
public string GetScheduleDescription()
{
return ScheduleType switch
{
"once" => $"Una volta il {ScheduledDateTime:dd/MM/yyyy HH:mm}",
"daily" => $"Ogni giorno alle {DailyTime}",
"weekly" => $"Ogni {GetDayOfWeekName(DayOfWeek)} alle {DailyTime}",
"monthly" => $"Il giorno {DayOfMonth} di ogni mese alle {DailyTime}",
"interval" => GetIntervalDescription(),
_ => "Non configurato"
};
}
private string GetIntervalDescription()
{
if (!IntervalValue.HasValue || string.IsNullOrEmpty(IntervalUnit))
return "Intervallo non configurato";
var unit = IntervalUnit.ToLower() switch
{
"seconds" => IntervalValue.Value == 1 ? "secondo" : "secondi",
"minutes" => IntervalValue.Value == 1 ? "minuto" : "minuti",
"hours" => IntervalValue.Value == 1 ? "ora" : "ore",
"days" => IntervalValue.Value == 1 ? "giorno" : "giorni",
"weeks" => IntervalValue.Value == 1 ? "settimana" : "settimane",
"months" => IntervalValue.Value == 1 ? "mese" : "mesi",
_ => IntervalUnit
};
return $"Ogni {IntervalValue} {unit}";
}
private string GetDayOfWeekName(int? dayOfWeek)
{
if (!dayOfWeek.HasValue)
return "sconosciuto";
return ((DayOfWeek)dayOfWeek.Value).ToString() switch
{
"Monday" => "Lunedì",
"Tuesday" => "Martedì",
"Wednesday" => "Mercoledì",
"Thursday" => "Giovedì",
"Friday" => "Venerdì",
"Saturday" => "Sabato",
"Sunday" => "Domenica",
_ => dayOfWeek.Value.ToString()
};
}
}