trackslash
VAULT-56 P1

Removing a tag from an item doesn't stick

0
All issues

Description

Found by the VAULT-42 differential test, which compares the new record store with the SwiftData store.

The bug: when an item loses a tag, the tag stays on the item. It happens in two places:

  • editing an item and removing one of its tags
  • a merge import that brings in a newer copy of an item with fewer tags

It reproduces on the SQLite store the app uses, including after reopening it.

Cause: PersistedLocalVaultStore.update inserted a new model with the same id and relied on SwiftData's unique-id upsert. The upsert merges to-many relationships (tags) instead of replacing them.

Fix: the store updates items and tags in place. It replaces the tag set, updates a detail of the same kind in place, and deletes a detail the item no longer has, so no orphaned detail rows (old secrets) are left behind. The contract suite covers removing tags on update, changing an item's kind, and a newer import replacing tags.

Sub-issues

0

Linked issues

0

GitHub

0

No branches or pull requests linked.

Comments

1
Bradley

Fixed in https://github.com/badbundle/vault-app/pull/625 (merged as 736be18f), alongside VAULT-42.

  • The fix: PersistedLocalVaultStore now updates items and tags in place instead of relying on SwiftData's unique-id upsert, which merged the old tags into the new model.
  • Tags: an item's tags are replaced outright.
  • Details: a detail of the same kind is updated in place, and a detail the item no longer has is deleted, so no orphaned rows are left behind.
  • Tests: the contract suite now covers removing tags on update, changing an item's kind, and a newer import replacing tags, all on SQLite as well as in memory.