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

@@ -7,11 +7,17 @@
import SwiftData
import Foundation
import os.log
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "DataControllerGET")
extension DataController {
func getEntry(byDate date: Date) -> MoodEntryModel? {
let startDate = Calendar.current.startOfDay(for: date)
let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate)!
guard let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) else {
logger.error("Failed to calculate end date for getEntry")
return nil
}
var descriptor = FetchDescriptor<MoodEntryModel>(
predicate: #Predicate { entry in
@@ -21,7 +27,12 @@ extension DataController {
)
descriptor.fetchLimit = 1
return try? modelContext.fetch(descriptor).first
do {
return try modelContext.fetch(descriptor).first
} catch {
logger.error("Failed to fetch entry: \(error.localizedDescription)")
return nil
}
}
func getData(startDate: Date, endDate: Date, includedDays: [Int]) -> [MoodEntryModel] {
@@ -36,7 +47,12 @@ extension DataController {
sortBy: [SortDescriptor(\.forDate, order: .forward)]
)
return (try? modelContext.fetch(descriptor)) ?? []
do {
return try modelContext.fetch(descriptor)
} catch {
logger.error("Failed to fetch entries: \(error.localizedDescription)")
return []
}
}
/// Calculate the current mood streak efficiently using a single batch query.