Fix boundary bugs, route side effects through MoodLogger, add data listeners

- Fix ExtensionDataProvider <= boundary to < in date queries (prevented cross-day leaks)
- Replace force-unwraps with guards and add error logging in DataControllerGET and ExtensionDataProvider
- Route DayViewViewModel update/delete through MoodLogger.shared (was duplicating side effects)
- Add data listeners to InsightsViewModel and YearViewModel for cross-tab refresh
- Add HealthKitManager.deleteMood(for:) for single-date cleanup
- Add SharedModelContainer.isUsingInMemoryFallback flag with critical logging
- Add analytics events: entryDeleted, allDataCleared, duplicatesRemoved, storageFallbackActivated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-14 23:34:09 -06:00
parent 0e8738794b
commit 7c142568be
8 changed files with 157 additions and 39 deletions

View File

@@ -311,6 +311,38 @@ class HealthKitManager: ObservableObject {
return deletedCount
}
// MARK: - Delete Mood for Date from HealthKit
/// Deletes State of Mind samples created by this app for a specific date
/// Note: HealthKit only allows deleting samples that your app created
func deleteMood(for date: Date) async throws {
guard isHealthKitAvailable else {
throw HealthKitError.notAvailable
}
guard let stateOfMindType = stateOfMindType else {
throw HealthKitError.typeNotAvailable
}
guard checkAuthorizationStatus() == .sharingAuthorized else {
throw HealthKitError.notAuthorized
}
let calendar = Calendar.current
let dayStart = calendar.startOfDay(for: date)
guard let dayEnd = calendar.date(byAdding: .day, value: 1, to: dayStart) else { return }
let samples = try await fetchMoods(from: dayStart, to: dayEnd)
guard !samples.isEmpty else {
logger.info("No State of Mind samples found for \(date) to delete")
return
}
try await healthStore.delete(samples)
logger.info("Deleted \(samples.count) State of Mind samples for \(date)")
}
// MARK: - Read Mood from HealthKit
func fetchMoods(from startDate: Date, to endDate: Date) async throws -> [HKStateOfMind] {