What: Wrap the per-entry INSERT OR IGNORE loop in ImportModal inside a single SQLite transaction so that a partial import either fully commits or fully rolls back.
Why: Currently, if the app crashes mid-import, some entries may be written and others not — leaving the vault in an inconsistent state.
Pros: Atomic import — all or nothing; consistent with standard DB practices.
Cons: Minor added complexity; requires exposing a begin_transaction / commit helper in storage.rs and a batch-insert method in AppState.
Context: The import loop is in src/components/import_modal.rs inside a tokio::task::spawn_blocking call. All DB access goes through AppState which holds a Mutex<Connection>. The transaction would need to hold the mutex lock for the entire batch.
What: Wrap the per-entry
INSERT OR IGNOREloop inImportModalinside a single SQLite transaction so that a partial import either fully commits or fully rolls back.Why: Currently, if the app crashes mid-import, some entries may be written and others not — leaving the vault in an inconsistent state.
Pros: Atomic import — all or nothing; consistent with standard DB practices.
Cons: Minor added complexity; requires exposing a
begin_transaction/commithelper instorage.rsand a batch-insert method inAppState.Context: The import loop is in
src/components/import_modal.rsinside atokio::task::spawn_blockingcall. All DB access goes throughAppStatewhich holds aMutex<Connection>. The transaction would need to hold the mutex lock for the entire batch.