Fix 7 data mutation layer risks identified in audit
- save()/saveAndRunDataListeners() now return @discardableResult Bool; listeners only fire on successful save - MoodLogger.updateMood() now recalculates streak, updates Live Activity, and notifies watch (was missing these side effects) - CSV import uses new addBatch()/importMoods() for O(1) side effects instead of O(n) per-row widget reloads and streak calcs - Foreground task ordering: fillInMissingDates() now runs before removeDuplicates() so backfill-created duplicates are caught same cycle - WidgetMoodSaver deletes ALL entries for date (was fetchLimit=1, leaving CloudKit sync duplicates behind) - cleanupPhotoIfNeeded logs warning on failed photo deletion instead of silently orphaning files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,19 +52,32 @@ final class DataController: ObservableObject {
|
||||
editedDataClosure.append(closure)
|
||||
}
|
||||
|
||||
func saveAndRunDataListeners() {
|
||||
save()
|
||||
for closure in editedDataClosure {
|
||||
closure()
|
||||
@discardableResult
|
||||
func saveAndRunDataListeners() -> Bool {
|
||||
let success = save()
|
||||
if success {
|
||||
for closure in editedDataClosure {
|
||||
closure()
|
||||
}
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
func save() {
|
||||
guard modelContext.hasChanges else { return }
|
||||
@discardableResult
|
||||
func save() -> Bool {
|
||||
guard modelContext.hasChanges else { return true }
|
||||
do {
|
||||
try modelContext.save()
|
||||
return true
|
||||
} catch {
|
||||
Self.logger.error("Failed to save context: \(error.localizedDescription)")
|
||||
Self.logger.error("Failed to save context, retrying: \(error.localizedDescription)")
|
||||
do {
|
||||
try modelContext.save()
|
||||
return true
|
||||
} catch {
|
||||
Self.logger.critical("Failed to save context after retry: \(error.localizedDescription)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user