Make Apple Health workout recording watch-only

The phone no longer writes estimated Health workouts: the watch, which
runs the live session, is the sole recorder. Replaces WorkoutHealthWriter
with a WorkoutHealthDeleter that only removes a legacy phone-estimate
workout when its record is deleted here, drops the MET calorie table and
the phone's write/read Health scopes, and keeps phoneEstimate decodable
for existing documents.

Claude-Session: https://claude.ai/code/session_01HJDQQDA9QdP8zByg43H5v3
This commit is contained in:
2026-07-08 07:56:19 -04:00
parent 06fa52345b
commit a4ed4df756
9 changed files with 102 additions and 261 deletions
-12
View File
@@ -51,14 +51,6 @@ final class SyncEngine {
/// this to push fresh state to the watch.
var onCacheChanged: (() -> Void)?
/// Called when a completed workout is persisted. The HealthKit writer uses this to
/// schedule an estimated Health workout if nothing recorded it.
var onWorkoutCompleted: ((WorkoutDocument) -> Void)?
/// Called when a workout carrying watch-recorded metrics is persisted, so the
/// writer can cancel any pending phone estimate for it.
var onWatchMetricsArrived: ((String) -> Void)?
private let log = Logger(subsystem: "dev.rzen.indie.Workouts", category: "sync")
private let modelContainer: ModelContainer
private var store: DocumentFileStore?
@@ -351,10 +343,6 @@ final class SyncEngine {
} catch {
report("Failed to save workout", error)
}
// Drive the HealthKit writer: a watch-recorded doc cancels any pending estimate;
// a completed doc (re)considers an estimate (the writer dedupes on metrics).
if doc.metrics?.source == .watch { onWatchMetricsArrived?(doc.id) }
if doc.status == WorkoutStatus.completed.rawValue { onWorkoutCompleted?(doc) }
}
func delete(split: Split) async {