Harden SimpleFIN sync: protect user data, fix stuck syncs, optimize API calls (#671)

* Implement entry protection flags for sync overwrites

- Added `user_modified` and `import_locked` flags to `entries` table to prevent provider sync from overwriting user-edited and imported data.
- Introduced backfill migration to mark existing entries based on conditions.
- Enhanced sync and processing logic to respect protection flags, track skipped entries, and log detailed stats.
- Updated UI to display skipped/protected entries and reasons in sync summaries.

* Localize error details summary text and adjust `sync_account_later` method placement

* Restored schema.rb

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
This commit is contained in:
LPW
2026-01-16 06:34:06 -05:00
committed by GitHub
parent 9b1188eab4
commit c391ba2b23
20 changed files with 344 additions and 37 deletions

View File

@@ -243,6 +243,23 @@ class Entry < ApplicationRecord
external_id.present?
end
# Checks if entry should be protected from provider sync overwrites.
# This does NOT prevent user from editing - only protects from automated sync.
#
# @return [Boolean] true if entry should be skipped during provider sync
def protected_from_sync?
excluded? || user_modified? || import_locked?
end
# Marks entry as user-modified after manual edit.
# Called when user edits any field to prevent provider sync from overwriting.
#
# @return [Boolean] true if successfully marked
def mark_user_modified!
return true if user_modified?
update!(user_modified: true)
end
class << self
def search(params)
EntrySearch.new(params).build_query(all)
@@ -272,6 +289,7 @@ class Entry < ApplicationRecord
entry.update! bulk_attributes
entry.lock_saved_attributes!
entry.mark_user_modified!
entry.entryable.lock_attr!(:tag_ids) if entry.transaction? && entry.transaction.tags.any?
end
end