Baustein 6: Datei-Anhaenge synchronisieren (Kapitel 10)

Anhaenge laufen bewusst NICHT ueber den JSON-Ereigniskanal (wuerde ihn
fuer Fotos/Scans stark aufblaehen), sondern ueber einen eigenen
verschluesselten Binaerkanal - analog zum bereits bestehenden Muster
in SnapshotService.

- Neue Endpunkte POST/GET /api/sync/attachments/{storageId} in
  LehrerApp.Api (AttachmentStore, dateibasiert je Nutzer)
- EventQueue: neue, vom JSON-Ereignis getrennte Warteliste fuer
  ausstehende Uploads (SyncEventPublisher traegt Anhaenge einer
  gespeicherten Documentation dort ein)
- AttachmentSyncer laedt ausstehende Anhaenge hoch (in
  SyncEngine.SyncNowAsync nach dem Event-Push)
- EventApplier laedt fehlende Anhaenge nach dem Anwenden eines
  Documentation-Ereignisses nach - ueber die rohe Collection statt
  IAttachmentStorage.Upload, da dieses immer eine neue Id vergaebe und
  hier die Original-StorageId erhalten bleiben muss

Round-Trip-Tests belegen byteidentische Uebertragung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 11:30:04 +02:00
co-authored by Claude Sonnet 5
parent ce4dfb0197
commit f0f8fa25e5
14 changed files with 391 additions and 29 deletions
+6 -1
View File
@@ -179,14 +179,19 @@ public static class AppBootstrapper
if (!string.IsNullOrEmpty(serverUrl))
{
services.AddSingleton(sp => new EventApplier(
sp.GetRequiredService<LiteDbContext>(), sp.GetRequiredService<byte[]>()));
sp.GetRequiredService<LiteDbContext>(), sp.GetRequiredService<byte[]>(),
BuildHttp(serverUrl, appData)));
services.AddSingleton(sp => new SyncEventPublisher(
sp.GetRequiredService<EventQueue>(), deviceId, sp.GetRequiredService<byte[]>()));
services.AddSingleton(sp => new AttachmentSyncer(
sp.GetRequiredService<LiteDbContext>(), BuildHttp(serverUrl, appData),
sp.GetRequiredService<byte[]>()));
services.AddSingleton<SyncEngine>(sp => new SyncEngine(
sp.GetRequiredService<EventQueue>(),
sp.GetRequiredService<ConflictResolver>(),
sp.GetRequiredService<EventApplier>(),
sp.GetRequiredService<AttachmentSyncer>(),
BuildHttp(serverUrl, appData),
new SyncConfig
{