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:
@@ -0,0 +1,38 @@
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
@objc(JournalEntry)
|
||||
public class JournalEntry: NSManagedObject, Identifiable {
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<JournalEntry> {
|
||||
return NSFetchRequest<JournalEntry>(entityName: "JournalEntry")
|
||||
}
|
||||
|
||||
@NSManaged public var id: UUID?
|
||||
@NSManaged public var monthKey: String?
|
||||
@NSManaged public var note: String?
|
||||
@NSManaged public var moodRaw: String?
|
||||
@NSManaged public var rating: Int16
|
||||
@NSManaged public var completionTime: Date?
|
||||
@NSManaged public var createdAt: Date?
|
||||
|
||||
public override func awakeFromInsert() {
|
||||
super.awakeFromInsert()
|
||||
id = UUID()
|
||||
createdAt = Date()
|
||||
}
|
||||
|
||||
var mood: MonthlyCheckInMood? {
|
||||
get { moodRaw.flatMap { MonthlyCheckInMood(rawValue: $0) } }
|
||||
set { moodRaw = newValue?.rawValue }
|
||||
}
|
||||
|
||||
var ratingValue: Int? {
|
||||
get { rating > 0 ? Int(rating) : nil }
|
||||
set { rating = Int16(newValue.map { min(max(1, $0), 5) } ?? 0) }
|
||||
}
|
||||
|
||||
var completionDate: Date? {
|
||||
get { completionTime }
|
||||
set { completionTime = newValue }
|
||||
}
|
||||
}
|
||||
+9
@@ -102,4 +102,13 @@
|
||||
<attribute name="value" optional="YES" attributeType="Decimal"/>
|
||||
<relationship name="source" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="InvestmentSource" inverseName="snapshots" inverseEntity="InvestmentSource"/>
|
||||
</entity>
|
||||
<entity name="JournalEntry" representedClassName="JournalEntry" syncable="YES">
|
||||
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
|
||||
<attribute name="monthKey" optional="YES" attributeType="String"/>
|
||||
<attribute name="note" optional="YES" attributeType="String"/>
|
||||
<attribute name="moodRaw" optional="YES" attributeType="String"/>
|
||||
<attribute name="rating" optional="YES" attributeType="Integer 16" usesScalarValueType="YES"/>
|
||||
<attribute name="completionTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="createdAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
</entity>
|
||||
</model>
|
||||
|
||||
@@ -186,6 +186,7 @@ class CoreDataStack: ObservableObject {
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self?.isLoaded = true
|
||||
MonthlyCheckInStore.migrateIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user