namespace LehrerApp.Sync.Models;
///
/// Ein einzelnes Ereignis im Event-Log.
/// Wird verschlüsselt zum Server übertragen – der Server versteht den Payload nicht.
///
public class SyncEvent
{
public Guid EventId { get; init; } = Guid.NewGuid();
public string DeviceId { get; init; } = "";
public DeviceType DeviceType { get; init; }
public DateTime Timestamp { get; init; } = DateTime.UtcNow;
public long SequenceNr { get; init; } // monoton steigend pro Gerät
public string EntityType { get; init; } = ""; // "Student", "Exam", "Grade" ...
public string EntityId { get; init; } = "";
public string Operation { get; init; } = ""; // "Create", "Update", "Delete"
public string Payload { get; init; } = ""; // JSON, AES-256 verschlüsselt
}
///
/// Eintrag im lokalen Konflikt-Log – für UI-Anzeige.
///
public class ConflictEntry
{
public Guid Id { get; init; } = Guid.NewGuid();
public DateTime DetectedAt { get; init; } = DateTime.UtcNow;
public SyncEvent LocalEvent { get; init; } = null!;
public SyncEvent RemoteEvent { get; init; } = null!;
public string Resolution { get; init; } = ""; // "LocalWon", "RemoteWon", "Pending"
public bool Reviewed { get; set; }
}
///
/// Antwort des Servers auf einen Pull-Request.
///
public class PullResponse
{
public List Events { get; init; } = [];
public long ServerSequenceNr { get; init; }
}
///
/// Antwort des Servers auf einen Push-Request.
///
public class PushResponse
{
public bool Success { get; init; }
public long ServerSequenceNr { get; init; }
public List ConflictingEventIds { get; init; } = [];
}
public enum DeviceType { Desktop, Companion }
///
/// Sync-Status für UI-Anzeige.
///
public class SyncStatus
{
public SyncState State { get; set; } = SyncState.Idle;
public DateTime? LastSyncAt { get; set; }
public int PendingEvents { get; set; }
public int ConflictCount { get; set; }
public string? ErrorMessage { get; set; }
}
public enum SyncState { Idle, Syncing, Error, Offline }