docs: add ADR-0022 for LAN-Sync protocol implementation
- Documented a hybrid "Event-Sourcing Light with Lamport Clocks" approach for offline-first LAN synchronization between Meldestelle and Richter-Turm. - Included detailed options analysis (Event-Sourcing, CRDT, Timestamp-Sync) and rationale for the selected solution. - Added specifications: SyncEvent model, Lamport clock rules, WebSocket protocol (handshake, sync, recovery), and domain mastership rules. - Defined snapshot strategy to ensure scalable logs and efficient replay. - Outlined implementation plan in four phases, highlighting task breakdown for backend and frontend teams. - Updated architect, backend, and frontend roadmaps to reflect ADR-0022 integration steps. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
parent
236876a043
commit
2dd5453365
315
docs/01_Architecture/adr/0022-lan-sync-protocol-de.md
Normal file
315
docs/01_Architecture/adr/0022-lan-sync-protocol-de.md
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
---
|
||||
type: ADR
|
||||
status: ACCEPTED
|
||||
owner: Lead Architect
|
||||
last_update: 2026-04-03
|
||||
---
|
||||
|
||||
# ADR-0022: LAN-Sync-Protokoll (Meldestelle ↔ Richter-Turm)
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert — 2026-04-03
|
||||
|
||||
---
|
||||
|
||||
## Kontext
|
||||
|
||||
Die Desktop-Anwendung "Meldestelle-Biest" operiert auf Reitturnieren in einer LAN-Umgebung ohne garantierte
|
||||
Internetverbindung. Zwei Hauptakteure müssen Daten in Echtzeit synchronisieren:
|
||||
|
||||
- **Meldestelle-Desk** (Schreibzentrale): Verwaltet Nennungen, Startreihenfolgen, Teilnehmerkonten und Kassendaten.
|
||||
- **Richter-Turm-Desk** (Leseintensiv, gelegentlich schreibend): Zeigt Startreihenfolgen an, erfasst Bewertungen und
|
||||
Ergebnisse.
|
||||
|
||||
### Problemstellung
|
||||
|
||||
Welches Synchronisationsprotokoll eignet sich am besten für folgende Anforderungen?
|
||||
|
||||
1. **Offline-First**: Beide Seiten müssen auch ohne aktive Verbindung arbeitsfähig bleiben.
|
||||
2. **Konfliktauflösung**: Gleichzeitige Änderungen (z. B. Meldestelle ändert Startnummer, Richter erfasst Ergebnis)
|
||||
müssen deterministisch aufgelöst werden.
|
||||
3. **Einfachheit**: Das System wird von 1–3 Entwicklern betreut; Komplexität muss beherrschbar bleiben.
|
||||
4. **Latenz**: Ergebnisübertragung vom Richter-Turm zur Meldestelle soll < 500 ms betragen.
|
||||
5. **Datenmenge**: Pro Turnier typisch 50–300 Starts; kein Big-Data-Problem.
|
||||
|
||||
---
|
||||
|
||||
## Analyse der Optionen
|
||||
|
||||
### Option A: Event-Sourcing (Append-Only Event Log)
|
||||
|
||||
**Konzept:** Alle Zustandsänderungen werden als unveränderliche Events in einem Log gespeichert. Der aktuelle Zustand
|
||||
ergibt sich durch Replay aller Events. Peers tauschen fehlende Events aus (Log-Replikation).
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- Vollständige Audit-Trail aller Änderungen.
|
||||
- Natürliche Konfliktauflösung durch Event-Reihenfolge (Sequenznummern).
|
||||
- Gut kombinierbar mit CQRS.
|
||||
- Einfaches Nachsynchronisieren: Peer sendet seinen letzten bekannten `sequence_number`, Gegenseite liefert Delta.
|
||||
|
||||
**Nachteile:**
|
||||
|
||||
- Log wächst unbegrenzt (Snapshots erforderlich).
|
||||
- Höhere Implementierungskomplexität (Projektion, Snapshot-Strategie).
|
||||
- Replay bei großem Log kann langsam sein (mitigierbar durch Snapshots).
|
||||
|
||||
**Bewertung für unseren Kontext:** Gut geeignet, aber Snapshot-Strategie erhöht Komplexität. Für 50–300 Starts pro
|
||||
Turnier ist der Log überschaubar.
|
||||
|
||||
---
|
||||
|
||||
### Option B: CRDT (Conflict-free Replicated Data Types)
|
||||
|
||||
**Konzept:** Spezielle Datenstrukturen, die mathematisch garantieren, dass parallele Änderungen immer zu einem
|
||||
konsistenten Zustand konvergieren — ohne zentrale Koordination.
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- Echte Peer-to-Peer-Fähigkeit ohne Master.
|
||||
- Automatische, mathematisch korrekte Konfliktauflösung.
|
||||
- Keine Koordination nötig.
|
||||
|
||||
**Nachteile:**
|
||||
|
||||
- Sehr hohe Implementierungskomplexität (LWW-Register, OR-Set, RGA für Texte etc.).
|
||||
- Kaum Kotlin/KMP-Bibliotheken verfügbar; müsste selbst implementiert werden.
|
||||
- Semantische Konflikte (z. B. "Startnummer geändert UND Ergebnis für diese Startnummer erfasst") sind mit CRDTs nicht
|
||||
lösbar — nur strukturelle Konflikte.
|
||||
- Debugging und Nachvollziehbarkeit schwierig.
|
||||
|
||||
**Bewertung für unseren Kontext:** Überdimensioniert und zu komplex für ein 1–3-Personen-Team. Verworfen.
|
||||
|
||||
---
|
||||
|
||||
### Option C: Timestamp-basierte Synchronisation (Last-Write-Wins)
|
||||
|
||||
**Konzept:** Jede Entität trägt einen `updated_at`-Timestamp. Bei Konflikten gewinnt die neuere Änderung. Peers
|
||||
tauschen Deltas seit einem bekannten Zeitpunkt aus.
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- Sehr einfach zu implementieren.
|
||||
- Gut verständlich und debuggbar.
|
||||
- Funktioniert mit bestehenden SQLDelight-Schemas ohne große Umbauten.
|
||||
|
||||
**Nachteile:**
|
||||
|
||||
- Uhren-Drift zwischen Geräten kann zu falschen Ergebnissen führen (mitigierbar durch NTP oder logische Uhren).
|
||||
- Kein vollständiger Audit-Trail.
|
||||
- "Last-Write-Wins" kann fachlich falsch sein (z. B. ältere Bewertung überschreibt neuere Korrektur).
|
||||
- Keine Möglichkeit, Änderungshistorie nachzuvollziehen.
|
||||
|
||||
**Bewertung für unseren Kontext:** Zu riskant für fachlich kritische Daten (Ergebnisse, Nennungen). Uhren-Drift im
|
||||
LAN-Betrieb ohne NTP ist ein reales Problem. Verworfen als alleinige Strategie.
|
||||
|
||||
---
|
||||
|
||||
### Option D (Gewählt): Hybridansatz — Event-Sourcing Light mit Lamport-Uhren
|
||||
|
||||
**Konzept:** Vereinfachtes Event-Sourcing ohne vollständigen CQRS-Stack, kombiniert mit logischen Uhren (Lamport
|
||||
Timestamps) statt Wanduhren. Jede Änderung erzeugt ein `SyncEvent` mit monoton steigender logischer Uhr. Peers
|
||||
tauschen fehlende Events via WebSocket aus (Push bei Verbindung, Pull bei Reconnect).
|
||||
|
||||
**Kernprinzipien:**
|
||||
|
||||
1. **Meldestelle ist Master** für Nennungs- und Kassendaten.
|
||||
2. **Richter-Turm ist Master** für Bewertungs- und Ergebnisdaten.
|
||||
3. **Klare Domänentrennung** eliminiert 90 % der Konflikte strukturell.
|
||||
4. **Lamport-Timestamps** lösen verbleibende Konflikte deterministisch ohne Uhren-Drift-Problem.
|
||||
5. **Snapshots** alle N Events (konfigurierbar, Standard: 100) begrenzen Log-Größe und Replay-Zeit.
|
||||
|
||||
---
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir implementieren **Option D: Event-Sourcing Light mit Lamport-Uhren** als LAN-Sync-Protokoll.
|
||||
|
||||
### Architektur-Überblick
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐ WebSocket (LAN) ┌─────────────────────────────┐
|
||||
│ Meldestelle-Desk │◄──────────────────────────────►│ Richter-Turm-Desk │
|
||||
│ │ │ │
|
||||
│ Master für: │ SyncEvent-Stream │ Master für: │
|
||||
│ - Nennungen │ (bidirektional) │ - Bewertungen │
|
||||
│ - Startreihenfolge │ │ - Ergebnisse │
|
||||
│ - Teilnehmerkonten │ │ - Richter-Notizen │
|
||||
│ - Kassendaten │ │ │
|
||||
│ │ │ │
|
||||
│ SQLDelight (lokal) │ │ SQLDelight (lokal) │
|
||||
│ + SyncEvent-Log │ │ + SyncEvent-Log │
|
||||
└─────────────────────────────┘ └──────────────────────────────┘
|
||||
```
|
||||
|
||||
### SyncEvent-Datenmodell
|
||||
|
||||
```kotlin
|
||||
data class SyncEvent(
|
||||
val eventId: String, // Veranstaltungs-ID (Tenant)
|
||||
val turnierId: String, // Turnier-Scope (gemäß ADR-0020)
|
||||
val sequenceNumber: Long, // Lamport-Timestamp (logische Uhr)
|
||||
val originNodeId: String, // Geräte-ID (UUID, persistent)
|
||||
val aggregateType: String, // z. B. "Nennung", "Bewertung", "Start"
|
||||
val aggregateId: String, // ID der betroffenen Entität
|
||||
val eventType: String, // z. B. "NennungErstellt", "BewertungErfasst"
|
||||
val payload: ByteArray, // JSON/Protobuf-serialisiertes Delta
|
||||
val createdAt: Instant, // Wanduhr (nur für Anzeige/Logging)
|
||||
val checksum: String // SHA-256 des Payloads (Integritätsprüfung)
|
||||
)
|
||||
```
|
||||
|
||||
### Lamport-Uhr-Regeln
|
||||
|
||||
```
|
||||
Bei lokaler Änderung: localClock = localClock + 1
|
||||
Bei Empfang eines Events: localClock = max(localClock, event.sequenceNumber) + 1
|
||||
Konflikt-Auflösung: Höherer sequenceNumber gewinnt.
|
||||
Bei Gleichstand: lexikografisch größere originNodeId gewinnt (deterministisch).
|
||||
```
|
||||
|
||||
### Sync-Protokoll (WebSocket)
|
||||
|
||||
#### Verbindungsaufbau (Handshake)
|
||||
|
||||
```
|
||||
Client → Server: HELLO { nodeId, eventId, turnierId, lastKnownSeq }
|
||||
Server → Client: HELLO_ACK { nodeId, currentSeq }
|
||||
Server → Client: SYNC_DELTA [ SyncEvent, ... ] (alle Events > lastKnownSeq)
|
||||
Client → Server: SYNC_ACK { ackedSeq }
|
||||
```
|
||||
|
||||
#### Laufender Betrieb
|
||||
|
||||
```
|
||||
Änderung lokal: SYNC_PUSH { SyncEvent }
|
||||
Gegenseite: SYNC_ACK { ackedSeq } oder SYNC_NACK { reason }
|
||||
Heartbeat: PING / PONG alle 30 Sekunden
|
||||
```
|
||||
|
||||
#### Reconnect / Offline-Recovery
|
||||
|
||||
```
|
||||
Reconnect: HELLO { lastKnownSeq } → Server liefert Delta seit lastKnownSeq
|
||||
Snapshot-Request: SNAPSHOT_REQUEST { turnierId } → Server liefert aktuellen Snapshot + seq
|
||||
```
|
||||
|
||||
### Domänen-Mastership (Konflikt-Prävention)
|
||||
|
||||
| Aggregat | Master | Richter-Turm darf |
|
||||
|---------------------|------------------|-------------------|
|
||||
| Nennung | Meldestelle | Lesen |
|
||||
| Startreihenfolge | Meldestelle | Lesen |
|
||||
| TeilnehmerKonto | Meldestelle | Lesen |
|
||||
| Kassenbuchung | Meldestelle | Kein Zugriff |
|
||||
| Bewertung | Richter-Turm | Schreiben |
|
||||
| Ergebnis | Richter-Turm | Schreiben |
|
||||
| Richter-Notiz | Richter-Turm | Schreiben |
|
||||
| Veranstaltungs-Chat | Beide (CRDT-Set) | Schreiben |
|
||||
|
||||
> **Hinweis:** Schreibt ein Peer in ein Aggregat, für das er nicht Master ist, wird das Event lokal gespeichert
|
||||
> aber mit `status = PENDING_REVIEW` markiert und dem Master zur Bestätigung vorgelegt.
|
||||
|
||||
### Snapshot-Strategie
|
||||
|
||||
- Snapshot wird nach jeweils **100 Events** pro `(turnierId, aggregateType)` erstellt.
|
||||
- Snapshot enthält: vollständiger Zustand des Aggregats + `snapshotSeq`.
|
||||
- Beim Replay: Lade letzten Snapshot, wende nur Events mit `seq > snapshotSeq` an.
|
||||
- Snapshots werden lokal in SQLDelight gespeichert und bei Bedarf übertragen.
|
||||
|
||||
### Sicherheit (gemäß ADR-0020)
|
||||
|
||||
- WebSocket-Verbindung via `wss://` mit Shared Security Key pro Veranstaltung.
|
||||
- `eventId` im Handshake wird gegen lokale Registry validiert.
|
||||
- Events mit falscher `eventId` oder `turnierId` werden verworfen (kein Silent-Drop, sondern `SYNC_NACK`).
|
||||
|
||||
---
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
|
||||
- **Offline-First**: Beide Peers arbeiten vollständig lokal; Sync erfolgt opportunistisch bei Verbindung.
|
||||
- **Kein Uhren-Drift-Problem**: Lamport-Uhren sind unabhängig von Systemuhren.
|
||||
- **Audit-Trail**: Vollständige Änderungshistorie pro Turnier nachvollziehbar.
|
||||
- **Einfaches Delta-Sync**: `lastKnownSeq` reicht für vollständiges Nachsynchronisieren.
|
||||
- **Klare Verantwortlichkeiten**: Domänen-Mastership eliminiert strukturell die meisten Konflikte.
|
||||
- **Skalierbar**: Funktioniert für 1 Richter-Turm ebenso wie für 5 parallele Türme.
|
||||
|
||||
### Negativ / Herausforderungen
|
||||
|
||||
- **Log-Management**: Snapshot-Strategie muss implementiert und getestet werden.
|
||||
- **Schema-Evolution**: Payload-Format muss versioniert werden (empfohlen: JSON mit `schemaVersion`-Feld).
|
||||
- **Mehr Aufwand als reines Timestamp-Sync**: Initiale Implementierung aufwändiger, langfristig robuster.
|
||||
- **WebSocket-Infrastruktur**: Meldestelle-Desk fungiert als WebSocket-Server; Richter-Turm als Client (gemäß
|
||||
ADR-0020 Master-Client-Hybrid).
|
||||
|
||||
### Neutral
|
||||
|
||||
- SQLDelight-Schema muss um `sync_events`- und `sync_snapshots`-Tabellen erweitert werden.
|
||||
- `originNodeId` muss beim ersten Start persistent generiert und gespeichert werden.
|
||||
|
||||
---
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
| Option | Entscheidung | Hauptgrund |
|
||||
|---------------------|---------------------|-----------------------------------------------------------------|
|
||||
| A: Event-Sourcing | Basis (vereinfacht) | Zu komplex mit vollem CQRS-Stack; Light-Variante gewählt |
|
||||
| B: CRDT | Verworfen | Zu hohe Implementierungskomplexität, keine KMP-Bibliotheken |
|
||||
| C: Timestamp-Sync | Verworfen | Uhren-Drift-Risiko, kein Audit-Trail, fachlich unsicher |
|
||||
| D: Hybrid (gewählt) | Akzeptiert | Beste Balance aus Robustheit, Einfachheit und Offline-Fähigkeit |
|
||||
|
||||
---
|
||||
|
||||
## Implementierungsplan
|
||||
|
||||
### Phase 1 — Fundament (Backend Sprint B / Frontend Sprint B)
|
||||
|
||||
- [ ] `SyncEvent`-Datenmodell in `core`-Modul definieren (KMP-shared)
|
||||
- [ ] SQLDelight-Tabellen `sync_events`, `sync_snapshots` anlegen
|
||||
- [ ] `LamportClock`-Implementierung (thread-safe, persistent)
|
||||
- [ ] `originNodeId`-Generierung und -Persistierung beim App-Start
|
||||
|
||||
### Phase 2 — Transport (Backend Sprint B / Frontend Sprint B)
|
||||
|
||||
- [ ] WebSocket-Server auf Meldestelle-Desk (Ktor)
|
||||
- [ ] WebSocket-Client auf Richter-Turm-Desk (Ktor-Client / KMP)
|
||||
- [ ] Handshake-Protokoll implementieren (HELLO / HELLO_ACK / SYNC_DELTA)
|
||||
- [ ] SYNC_PUSH / SYNC_ACK / PING-PONG implementieren
|
||||
|
||||
### Phase 3 — Konfliktauflösung & Recovery
|
||||
|
||||
- [ ] Domänen-Mastership-Validierung im Event-Handler
|
||||
- [ ] Snapshot-Erstellung und -Wiederherstellung
|
||||
- [ ] Reconnect-Logik mit Delta-Sync (lastKnownSeq)
|
||||
- [ ] `PENDING_REVIEW`-Workflow für Mastership-Verletzungen
|
||||
|
||||
### Phase 4 — Observability & Tests
|
||||
|
||||
- [ ] Sync-Status-UI (verbunden / getrennt / ausstehende Events)
|
||||
- [ ] Integrationstests: 2 Peers, Offline-Phase, Reconnect, Konflikt
|
||||
- [ ] Chaos-Tests: Verbindungsabbruch während Sync, Clock-Skew-Simulation
|
||||
|
||||
---
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
- **USB-Stick Fallback**: Separate Besprechung (Sprint B/C) — Export/Import des SyncEvent-Logs auf USB als
|
||||
Notfall-Sync-Kanal. Snapshot-Format ist bereits kompatibel.
|
||||
- **Payload-Serialisierung**: JSON (einfacher) vs. Protobuf (kompakter). Empfehlung: JSON mit `schemaVersion` für
|
||||
Phase 1, Migration zu Protobuf optional in Phase 2.
|
||||
- **Mehrere Richter-Türme**: Protokoll unterstützt N Clients; Broadcast-Strategie auf Meldestelle-Seite noch zu
|
||||
spezifizieren (Fan-out vs. Relay).
|
||||
|
||||
---
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [ADR-0020: LAN-Kommunikation und Daten-Isolierung](0020-lan-communication-isolation-de.md)
|
||||
- [ADR-0021: Tenant-Resolution-Strategie](0021-tenant-resolution-strategy-de.md)
|
||||
- [ADR-0004: Event-driven Communication](0004-event-driven-communication-de.md)
|
||||
- [ADR-0010: SQLDelight for Cross-Platform Persistence](0010-sqldelight-for-cross-platform-persistence.md)
|
||||
- [ADR-0008: Multiplatform Client Applications](0008-multiplatform-client-applications-de.md)
|
||||
- Lamport, L. (1978). "Time, Clocks, and the Ordering of Events in a Distributed System." CACM 21(7).
|
||||
|
|
@ -21,13 +21,18 @@
|
|||
|
||||
- [x] **B-0** | Rulebook-Session (03.04.2026) dokumentiert →
|
||||
`docs/99_Journal/2026-04-03_Rulebook_B1_Validierung_Frontend.md`
|
||||
- [x] **B-1** (teilweise) | Architect B-1 Session-Log erstellt →
|
||||
`docs/99_Journal/2026-04-03_Architect_B1_LAN-Sync_ADR-0022.md`
|
||||
- [x] **B-1** (teilweise) | Roadmaps aktualisiert: Architect (✅ Sprint B), Backend (C-3 freigegeben), Frontend (C-3
|
||||
freigegeben)
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Sprint B — Offen (höchste Priorität)
|
||||
|
||||
- [ ] **B-1** | Roadmaps-Verzeichnis pflegen
|
||||
- [ ] Alle 9 Roadmap-Dateien in `docs/04_Agents/Roadmaps/` auf Vollständigkeit prüfen ← *diese Session*
|
||||
- [x] Architect-, Backend-, Frontend-Roadmaps aktualisiert (03.04.2026)
|
||||
- [ ] Verbleibende Roadmaps (DevOps, QA, UI/UX, Rulebook) auf Vollständigkeit prüfen
|
||||
- [ ] Abgeschlossene Aufgaben als `[x]` markieren (nach Rückmeldung der Teams)
|
||||
|
||||
- [ ] **B-2** | `docs/05_Backend/` aktualisieren
|
||||
|
|
|
|||
73
docs/99_Journal/2026-04-03_Architect_B1_LAN-Sync_ADR-0022.md
Normal file
73
docs/99_Journal/2026-04-03_Architect_B1_LAN-Sync_ADR-0022.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# Session-Log: Architect B-1 — ADR-0022 LAN-Sync-Protokoll
|
||||
|
||||
> **Datum:** 3. April 2026
|
||||
> **Agent:** 🏗️ Lead Architect
|
||||
> **Aufgabe:** B-1 — ADR für LAN-Sync-Protokoll schreiben
|
||||
|
||||
---
|
||||
|
||||
## Erledigte Aufgaben
|
||||
|
||||
### 1. Optionen analysiert
|
||||
|
||||
Drei Synchronisationsstrategien wurden für den Kontext Meldestelle ↔ Richter-Turm bewertet:
|
||||
|
||||
| Option | Ergebnis |
|
||||
|-----------------------------------------|--------------------------------------------------|
|
||||
| A: Event-Sourcing (Append-Only Log) | Basis der gewählten Lösung (vereinfacht) |
|
||||
| B: CRDT | Verworfen — zu komplex, keine KMP-Bibliotheken |
|
||||
| C: Timestamp-Sync (Last-Write-Wins) | Verworfen — Uhren-Drift-Risiko, kein Audit-Trail |
|
||||
| D: Event-Sourcing Light + Lamport-Uhren | **Gewählt** |
|
||||
|
||||
### 2. Entscheidung getroffen
|
||||
|
||||
**Event-Sourcing Light mit Lamport-Uhren** als LAN-Sync-Protokoll:
|
||||
|
||||
- Meldestelle = Master für Nennungen/Kassa; Richter-Turm = Master für Bewertungen/Ergebnisse
|
||||
- Domänen-Mastership eliminiert strukturell ~90 % der Konflikte
|
||||
- Lamport-Timestamps lösen verbleibende Konflikte deterministisch (kein Uhren-Drift)
|
||||
- WebSocket-Transport (bidirektional), Handshake via HELLO/HELLO_ACK/SYNC_DELTA
|
||||
- Snapshots alle 100 Events begrenzen Log-Größe und Replay-Zeit
|
||||
|
||||
### 3. ADR-0022 abgelegt
|
||||
|
||||
**Datei:** `docs/01_Architecture/adr/0022-lan-sync-protocol-de.md`
|
||||
|
||||
Inhalt:
|
||||
|
||||
- Vollständige Optionsanalyse (A–D)
|
||||
- `SyncEvent`-Datenmodell (Kotlin)
|
||||
- Lamport-Uhr-Regeln
|
||||
- WebSocket-Protokoll (Handshake, laufender Betrieb, Reconnect)
|
||||
- Domänen-Mastership-Tabelle
|
||||
- Snapshot-Strategie
|
||||
- Implementierungsplan (4 Phasen)
|
||||
- Offene Punkte (USB-Stick Fallback, Payload-Serialisierung, Multi-Richter-Turm)
|
||||
|
||||
### 4. Downstream-Teams informiert
|
||||
|
||||
- **👷 Backend Developer**: `Backend_Roadmap.md` — C-3 als freigegeben markiert, detaillierte Implementierungsschritte
|
||||
ergänzt
|
||||
- **🎨 Frontend Expert**: `Frontend_Roadmap.md` — C-3 als freigegeben markiert, WebSocket-Client- und UI-Aufgaben ergänzt
|
||||
- **🏗️ Architect Roadmap**: Sprint B als abgeschlossen markiert
|
||||
|
||||
---
|
||||
|
||||
## Geänderte Dateien
|
||||
|
||||
| Datei | Änderung |
|
||||
|----------------------------------------------------------------|------------------------------------------|
|
||||
| `docs/01_Architecture/adr/0022-lan-sync-protocol-de.md` | **NEU** — ADR-0022 erstellt |
|
||||
| `docs/04_Agents/Roadmaps/Architect_Roadmap.md` | Sprint B abgeschlossen, B-1 ✅ |
|
||||
| `docs/04_Agents/Roadmaps/Backend_Roadmap.md` | C-3 freigegeben, Abhängigkeit ADR-0022 ✅ |
|
||||
| `docs/04_Agents/Roadmaps/Frontend_Roadmap.md` | C-3 freigegeben, Abhängigkeit ADR-0022 ✅ |
|
||||
| `docs/99_Journal/2026-04-03_Architect_B1_LAN-Sync_ADR-0022.md` | **NEU** — dieser Session-Log |
|
||||
|
||||
---
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
- **Sprint C-1** (Architect): Offline-First-Konzept für Desktop ↔ Backend ausarbeiten
|
||||
- **Sprint C-3** (Backend): `SyncEvent`-Modell, SQLDelight-Tabellen, LamportClock, WebSocket-Server
|
||||
- **Sprint C-3** (Frontend): WebSocket-Client, Sync-Status-UI, Discovery-UI
|
||||
- **Offen**: USB-Stick Fallback — separate Besprechung (Sprint B/C)
|
||||
Loading…
Reference in New Issue
Block a user