Files
LehrerApp/LehrerApp.Sync/ConflictResolver.cs
2026-03-29 23:47:31 +02:00

65 lines
2.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using LehrerApp.Sync.Models;
namespace LehrerApp.Sync;
/// <summary>
/// Entscheidet bei kollidierenden Events welcher gewinnt.
/// Desktop hat Vorrang vor Companion. Bei Gleichstand gewinnt der spätere Timestamp.
/// </summary>
public class ConflictResolver
{
private readonly EventQueue _queue;
public ConflictResolver(EventQueue queue)
{
_queue = queue;
}
/// <summary>
/// Prüft ob ein Remote-Event mit einem lokalen Event kollidiert.
/// Gibt null zurück wenn kein Konflikt besteht.
/// </summary>
public ConflictEntry? TryResolve(SyncEvent remoteEvent, string localDeviceId)
{
// Lokalen Event für dieselbe Entity suchen
var localEvent = _queue.GetPending()
.FirstOrDefault(e =>
e.EntityType == remoteEvent.EntityType &&
e.EntityId == remoteEvent.EntityId &&
e.DeviceId != remoteEvent.DeviceId);
if (localEvent is null)
return null; // kein Konflikt Remote-Event einfach anwenden
// Konflikt aufgelöst Gewinner bestimmen
var winner = DetermineWinner(localEvent, remoteEvent);
var resolution = winner == localEvent ? "LocalWon" : "RemoteWon";
// Wenn Remote gewinnt: lokalen Event aus Queue entfernen
if (winner == remoteEvent)
_queue.Acknowledge([localEvent.EventId]);
return new ConflictEntry
{
LocalEvent = localEvent,
RemoteEvent = remoteEvent,
Resolution = resolution,
};
}
private static SyncEvent DetermineWinner(SyncEvent local, SyncEvent remote)
{
// Regel 1: Desktop schlägt Companion
if (local.DeviceType == DeviceType.Desktop &&
remote.DeviceType == DeviceType.Companion)
return local;
if (remote.DeviceType == DeviceType.Desktop &&
local.DeviceType == DeviceType.Companion)
return remote;
// Regel 2: Späterer Timestamp gewinnt
return local.Timestamp >= remote.Timestamp ? local : remote;
}
}