commit 78ee59483c5ffb11917e3256568fcc9c60e25eb9
parent 2278efef23ba305647593ee47760d1aab7b7a08c
Author: Michael Camilleri <[email protected]>
Date: Fri, 24 Apr 2026 16:57:37 +0900
Fix gaps in synchronisation logic
Previous to this commit, completedAt was not pushed and resignGame didn't flush
the buffer.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
Diffstat:
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/Crossmate/Persistence/GameStore.swift b/Crossmate/Persistence/GameStore.swift
@@ -94,6 +94,12 @@ final class GameStore {
@ObservationIgnored
var onGameDeleted: (([String]) -> Void)?
+ /// Called when a mutable field on the `Game` record (e.g. `completedAt`)
+ /// changes and needs to be re-pushed. Wired to `SyncEngine.enqueueGame`
+ /// by `AppServices`.
+ @ObservationIgnored
+ var onGameUpdated: ((String) -> Void)?
+
init(persistence: PersistenceController) {
self.persistence = persistence
}
@@ -334,6 +340,10 @@ final class GameStore {
guard let entity = currentEntity else { return }
entity.completedAt = Date()
try context.save()
+ if let ckName = entity.ckRecordName {
+ onGameUpdated?(ckName)
+ }
+ Task { await moveBuffer?.flush() }
// Clean up current references
currentGame = nil
@@ -352,6 +362,9 @@ final class GameStore {
entity.completedAt == nil else { return }
entity.completedAt = Date()
try? context.save()
+ if let ckName = entity.ckRecordName {
+ onGameUpdated?(ckName)
+ }
Task { await moveBuffer?.flush() }
}
diff --git a/Crossmate/Services/AppServices.swift b/Crossmate/Services/AppServices.swift
@@ -47,6 +47,9 @@ final class AppServices {
store.onGameCreated = { [syncEngine] ckRecordName in
Task { await syncEngine.enqueueGame(ckRecordName: ckRecordName) }
}
+ store.onGameUpdated = { [syncEngine] ckRecordName in
+ Task { await syncEngine.enqueueGame(ckRecordName: ckRecordName) }
+ }
store.onGameDeleted = { [syncEngine] ckRecordNames in
Task { await syncEngine.enqueueDeleteRecords(ckRecordNames) }
}