Vollständige Sync-Orchestrierung, Port von Swift EventSyncEngine: - EventSyncEngine: Anonymous-First, emit (lokal+Outbox+Crypto), Pull-Loop (decrypt+Projektion+Cursor), signIn-Claim (anon->sub + re-encrypt + drain), Poll, Soft-Fail, Schema-Outdated-Stop, Crypto-Degraded-Pause, Listener - EventStore-Interface + InMemoryEventStore (Room-Adapter folgt im App-Modul) - SyncTransport/SyncWebSocket-Abstraktionen; SyncHttpClient: SyncTransport - createEventSyncEngine(...) Produktions-Factory (HTTP + Vault) - 36 Tests (Crypto-Roundtrip 2 Geräte, signIn-Claim, Schema-Outdated) - braucht mana-kotlin-core 0.2.0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57 lines
2.9 KiB
Markdown
57 lines
2.9 KiB
Markdown
# mana-kotlin-event-sync
|
|
|
|
Kotlin-Port des Event-Sync-Clients von mana e.V. — Pendant zu
|
|
[`mana-swift-event-sync`](../mana-swift-event-sync) (`ManaEventSync`). Der
|
|
Daten-Layer der event-sourced Flotte: User-eigene Decks/Cards/Reviews
|
|
laufen hierüber (E2E-verschlüsselt, gegen `sync2.mana.how`), nicht über REST.
|
|
|
|
Reine Kotlin/JVM-Library, baut auf [`mana-kotlin-core`](../mana-kotlin-core)
|
|
(Auth) auf. Während der Entwicklung über Gradle-Composite-Build verdrahtet
|
|
(`includeBuild("../mana-kotlin-core")`), kein Maven-Publish nötig.
|
|
|
|
## Was drin ist (v0.2 — Phase 2 komplett, außer Adaptern)
|
|
|
|
**Engine (Teil 2):**
|
|
- **`EventSyncEngine`** — die App-facing Orchestrierung: Anonymous-First-
|
|
Identität, `emit` (lokal + Outbox + Crypto-Wire), Pull-Loop (decrypt +
|
|
Projektion + Cursor), `signIn`-Claim (anon→`sub` re-taggen + re-encrypt +
|
|
drainen), Poll-Timer, Soft-Fail, Schema-Outdated-Stop, Crypto-Degraded-
|
|
Pause, Aggregate-Change-Listener. Port von Swift `EventSyncEngine`.
|
|
- **`EventStore`** (Interface) + **`InMemoryEventStore`** — Event-Log + Outbox
|
|
+ Meta + Retention. Saubere Trennung: die Android-App liefert einen **Room-
|
|
Adapter** (`EventStore`-Impl), die Engine bleibt pure Kotlin.
|
|
- **`SyncTransport`** / **`SyncWebSocket`** — Transport-Abstraktionen
|
|
(`SyncHttpClient` implementiert `SyncTransport`; WS-Impl im App-Modul).
|
|
- **`createEventSyncEngine(...)`** — Produktions-Verdrahtung (HTTP + Vault).
|
|
|
|
## Bausteine (v0.1 — Phase 2, Teil 1)
|
|
|
|
- **`crypto.MasterKeyCryptoProvider`** — AES-GCM-256, **byte-kompatibel** zu
|
|
Swift + TS (`enc:1:<b64-iv>.<b64-(ct‖tag)>`, WebCrypto-Layout). Bewiesen
|
|
per **Golden-Vektor** aus dem Node/WebCrypto-Pfad (Cross-Impl-Parität).
|
|
- **`crypto.NoOpCryptoProvider`** — Passthrough (Anonymous-Modus / Vault
|
|
unerreichbar). Mixed-Log-tolerant.
|
|
- **`crypto.VaultClient`** + `createMasterKeyProviderFromVault` — holt den
|
|
Master-Key (`/api/v1/me/encryption-vault/{key,init}`), baut den Provider;
|
|
ZK-Modus → wirft (Caller fällt auf NoOp zurück).
|
|
- **`core.EventEnvelope`** + `ActorContext` — Wire-Format; `sequenceNumber`
|
|
toleriert JSON-String **und** -Zahl (mana-sync Go `json:",string"`).
|
|
- **`core.Ulid`** — sortierbare IDs (Port der Swift-Generierung).
|
|
- **`transport.SyncHttpClient`** — `POST /sync/{appId}` (append ≤500) +
|
|
`GET /sync/{appId}/pull?since=N&limit=K`; `422` → `SchemaOutdated`.
|
|
|
|
## Was noch fehlt (Adapter, im App-Modul)
|
|
|
|
- **Room-`EventStore`-Adapter** — persistente Implementierung des
|
|
`EventStore`-Interfaces (braucht Android-SDK).
|
|
- **Ktor-`SyncWebSocket`-Impl** — Live-Push (braucht WS-fähige Engine +
|
|
Live-Server zum Verifizieren).
|
|
|
|
## Bauen & Testen
|
|
|
|
```bash
|
|
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
|
|
./gradlew test # 26 Tests, inkl. WebCrypto-Golden-Vektor
|
|
```
|
|
|
|
SOT-Plan: [`mana/docs/playbooks/WORDECK_ANDROID_GREENFIELD.md`](../mana/docs/playbooks/WORDECK_ANDROID_GREENFIELD.md).
|