diff --git a/PortfolioJournal/Models/CoreData/PortfolioJournal.xcdatamodeld/PortfolioJournal.xcdatamodel/contents b/PortfolioJournal/Models/CoreData/PortfolioJournal.xcdatamodeld/PortfolioJournal.xcdatamodel/contents
index 1487447..1b72142 100644
--- a/PortfolioJournal/Models/CoreData/PortfolioJournal.xcdatamodeld/PortfolioJournal.xcdatamodel/contents
+++ b/PortfolioJournal/Models/CoreData/PortfolioJournal.xcdatamodeld/PortfolioJournal.xcdatamodel/contents
@@ -100,6 +100,7 @@
+
diff --git a/PortfolioJournal/Models/CoreData/Snapshot+CoreDataClass.swift b/PortfolioJournal/Models/CoreData/Snapshot+CoreDataClass.swift
index 9d39c26..2758719 100644
--- a/PortfolioJournal/Models/CoreData/Snapshot+CoreDataClass.swift
+++ b/PortfolioJournal/Models/CoreData/Snapshot+CoreDataClass.swift
@@ -18,6 +18,10 @@ public class Snapshot: NSManagedObject, Identifiable {
@NSManaged public var value: NSDecimalNumber?
@NSManaged public var contribution: NSDecimalNumber?
@NSManaged public var notes: String?
+ /// True for auto-generated (interpolated) snapshots that fill a gap between two
+ /// real snapshots. Estimated snapshots are shown with a distinct marker and can
+ /// be removed in bulk. Defaults to false (model default) for all real snapshots.
+ @NSManaged public var isEstimated: Bool
@objc public var createdAt: Date {
get { safeValue(forKey: "createdAt", fallback: .distantPast) }
set { setManagedValue(newValue, forKey: "createdAt") }
diff --git a/PortfolioJournal/Repositories/AccountRepository.swift b/PortfolioJournal/Repositories/AccountRepository.swift
index 396bbe9..5002017 100644
--- a/PortfolioJournal/Repositories/AccountRepository.swift
+++ b/PortfolioJournal/Repositories/AccountRepository.swift
@@ -96,9 +96,12 @@ class AccountRepository: ObservableObject {
return existing
}
- // No accounts exist, create Default account
+ // No accounts exist, create Default account.
+ // Use a DETERMINISTIC id so every device creates the same CloudKit record
+ // instead of a per-device duplicate (root-cause fix for the dedup pile-up).
let defaultCurrency = AppSettings.getOrCreate(in: context).currency
let account = Account(context: context)
+ account.id = Account.defaultAccountStableID
account.name = Account.defaultAccountName
account.currency = defaultCurrency
account.inputMode = InputMode.simple.rawValue
diff --git a/PortfolioJournal/Repositories/CategoryRepository.swift b/PortfolioJournal/Repositories/CategoryRepository.swift
index 5ee5db6..1435caf 100644
--- a/PortfolioJournal/Repositories/CategoryRepository.swift
+++ b/PortfolioJournal/Repositories/CategoryRepository.swift
@@ -109,6 +109,8 @@ class CategoryRepository: ObservableObject {
}
let category = Category(context: context)
+ // Deterministic id → same CloudKit record on every device (no duplicates).
+ category.id = Category.stableID(for: categoryData.name)
category.name = categoryData.name
category.colorHex = categoryData.colorHex
category.icon = categoryData.icon
diff --git a/PortfolioJournal/ViewModels/SettingsViewModel.swift b/PortfolioJournal/ViewModels/SettingsViewModel.swift
index 4c62bc1..c172dbc 100644
--- a/PortfolioJournal/ViewModels/SettingsViewModel.swift
+++ b/PortfolioJournal/ViewModels/SettingsViewModel.swift
@@ -353,6 +353,7 @@ class SettingsViewModel: ObservableObject {
if accountCount == 0 {
let defaultCurrency = AppSettings.getOrCreate(in: context).currency
let account = Account(context: context)
+ account.id = Account.defaultAccountStableID
account.name = Account.defaultAccountName
account.currency = defaultCurrency
account.inputMode = InputMode.simple.rawValue