Migrate journal entries to CoreData for iCloud sync (build 33)
- Add JournalEntry CoreData entity (syncable=YES): id, monthKey, note, moodRaw, rating, completionTime, createdAt - Rewrite MonthlyCheckInStore: CoreData as primary storage, same public API - One-time migration from UserDefaults triggered after store loads - MonthlyCheckInCard: @FetchRequest on JournalEntry — reactive to iCloud sync - MonthlyCheckInView: onReceive NSManagedObjectContextObjectsDidChange to refresh @State vars on sync - Stats cards: observe NSManagedObjectContextObjectsDidChange instead of UserDefaults - ChartsViewModel.completedMonthKeys: remove MonthlyCheckInStore dependency (data-driven) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -709,8 +709,7 @@ class ChartsViewModel: ObservableObject {
|
||||
|
||||
private func completedMonthKeys(
|
||||
sources: [InvestmentSource],
|
||||
snapshots: [Snapshot],
|
||||
after cutoff: Date
|
||||
snapshots: [Snapshot]
|
||||
) -> Set<DateComponents> {
|
||||
let sourceIds = Set(sources.compactMap { $0.id })
|
||||
guard !sourceIds.isEmpty else { return [] }
|
||||
@@ -723,9 +722,8 @@ class ChartsViewModel: ObservableObject {
|
||||
completed.reserveCapacity(groupedByMonth.count)
|
||||
|
||||
for (key, monthSnapshots) in groupedByMonth {
|
||||
guard let monthDate = Calendar.current.date(from: key) else { continue }
|
||||
guard monthDate > cutoff else { continue }
|
||||
guard MonthlyCheckInStore.completionDate(for: monthDate) != nil else { continue }
|
||||
// A month is complete when all active sources have snapshot data for it.
|
||||
// MonthlyCheckInStore (UserDefaults) is NOT synced via iCloud — don't use it as a filter.
|
||||
let monthSourceIds = Set(monthSnapshots.compactMap { $0.source?.id })
|
||||
if sourceIds.isSubset(of: monthSourceIds) {
|
||||
completed.insert(key)
|
||||
@@ -739,24 +737,8 @@ class ChartsViewModel: ObservableObject {
|
||||
sources: [InvestmentSource],
|
||||
snapshots: [Snapshot]
|
||||
) -> [Snapshot] {
|
||||
guard let lastCompleted = MonthlyCheckInStore.latestCompletionDate()?.startOfMonth else {
|
||||
return snapshots
|
||||
}
|
||||
|
||||
let completedMonthsAfter = completedMonthKeys(
|
||||
sources: sources,
|
||||
snapshots: snapshots,
|
||||
after: lastCompleted
|
||||
)
|
||||
|
||||
return snapshots.filter { snapshot in
|
||||
let monthDate = chartMonthStart(for: snapshot.date)
|
||||
if monthDate <= lastCompleted {
|
||||
return true
|
||||
}
|
||||
let key = chartMonth(for: snapshot.date)
|
||||
return completedMonthsAfter.contains(key)
|
||||
}
|
||||
let completedKeys = completedMonthKeys(sources: sources, snapshots: snapshots)
|
||||
return snapshots.filter { completedKeys.contains(chartMonth(for: $0.date)) }
|
||||
}
|
||||
|
||||
private func groupSnapshotsBySource(_ snapshots: [Snapshot]) -> [UUID: [Snapshot]] {
|
||||
|
||||
Reference in New Issue
Block a user