mana-kotlin-event-sync/CHANGELOG.md

3.8 KiB

Changelog

0.6.0 — 2026-06-16

  • EventSyncEngine.shredScope(scopeId, shredAfterIso?) — App-API zum Crypto-Shredding eines Scope-Sub-Keys (Mandant löschen). null → sofort (privat/Art. 17), sonst geplant (Firma/GeBüV-Frist). Via injizierter shredScopeImpl (Factory baut ScopeVaultClient).

0.5.0 — 2026-06-16

  • Per-Mandant-Crypto-Shredding (A3), Parität zu @mana/event-sync 0.7.0 + mana-swift-event-sync 0.6.0: CryptoContext + optionale suspend- context-Varianten von encryptPayload/decryptPayload (Default forwarden zur synchronen Basis → bestehende Provider + Tests unverändert). ScopeVaultClient (Ktor: getOrMint/get/shred gegen /encryption-vault/scopes/:appId/:scopeId/key, 404→ScopeNotFoundException, 410→ScopeShreddedException). ScopedCryptoProvider (delegiert pro Scope an eine MasterKeyCryptoProvider- Instanz mit dem Sub-Key, Mutex-Cache, Master-Fallback; geschreddert → wirft). createScopedKeyProviderFromVault. EventSyncConfig.scopeResolver → Factory baut den Scoped-Provider; Context an emit/pull/reencrypt durchgereicht. Wire identisch enc:1:, abwärtskompatibel, bestehende Tests grün.

0.4.0 — 2026-06-10

  • Decrypt-Failures sichtbar statt Silent-Skip (Parität zu @mana/event-sync 0.6.0 + mana-swift-event-sync): Ein nicht- entschlüsselbares Event aus dem Pull wurde bisher via runCatching{}.getOrNull() still verworfen — die App sah nie, dass ihr Daten fehlen (der enc:1-Footgun). Jetzt:
    • persistenter Zähler in Meta (decrypt-failure-count, …-last-at, …-last-event), abfragbar via stats() → decryptFailures / decryptFailureLastAt, Reset via clearDecryptFailures();
    • neuer Hook onDecryptFailure: ((DecryptFailure) -> Unit)? pro Event, zusätzlich feuert onError mit EventSyncError.DecryptFailed(eventId);
    • decryptPulledPayload(payload, eventId, provider) wirft auch, wenn der Provider den Ciphertext unangetastet durchreicht (NoOp ohne Key) — vorher wäre der enc:1:-String als „Plaintext" in der Projektion gelandet. Der Pull-Cursor wandert trotz Failures weiter — Sync hängt nicht fest.

0.2.0 — 2026-06-04 (Phase 2 Teil 2)

  • EventSyncEngine — vollständige Orchestrierung (Port von Swift): Anonymous-First-Identität, Emit (lokal + Outbox + Crypto-Wire), Pull-Loop (decrypt + Projektion + Cursor), signIn-Claim (anon→sub Re-Attribution + Re-Encrypt + Drain), Poll-Timer, Soft-Fail, Schema-Outdated-Stop, Crypto-Degraded-Outbox-Pause, Aggregate-Change-Listener.
  • EventStore (Interface) + InMemoryEventStore — Event-Log + Outbox + Meta + Retention; Room-Adapter folgt im App-Modul.
  • SyncTransport / SyncWebSocket — Abstraktionen; SyncHttpClient implementiert SyncTransport.
  • createEventSyncEngine(...) — Produktions-Verdrahtung (HTTP + Vault).
  • EventSyncConfig / AuthMode / ClaimResult / EngineStats / AnonymousRetention.
  • 36 Tests (inkl. Crypto-Roundtrip über zwei Geräte, signIn-Claim, Schema-Outdated). Braucht mana-kotlin-core 0.2.0.

0.1.0 — 2026-06-04 (Phase 2 Teil 1)

Erstes Skelett. Phase 2 (Teil 1) des Android-Plans (WORDECK_ANDROID_GREENFIELD.md).

  • MasterKeyCryptoProvider (AES-GCM-256) + NoOpCryptoProvider — wire- kompatibel zu Swift/TS, byte-genau bewiesen per WebCrypto-Golden-Vektor.
  • VaultClient + createMasterKeyProviderFromVault (Key-Fetch, ZK-Erkennung).
  • EventEnvelope + ActorContext + flexibler Long-Serializer (sequenceNumber als String oder Zahl).
  • Ulid (Port der Swift-Generierung).
  • SyncHttpClient (append/pull gegen mana-sync, 422→SchemaOutdated).
  • 26 Tests grün.

Offen (Teil 2): WebSocket-Client, Room-EventStorage, EventSyncEngine.