Skip to content

feat(data): add batch deletes for a highlight color and a collection - #386

Merged
mohamede1945 merged 1 commit into
mainfrom
feat/batch-delete-highlights-collections
Nov 6, 2026
Merged

mohamede1945 merged 1 commit into
mainfrom
feat/batch-delete-highlights-collections

Conversation

@mohamede1945

Copy link
Copy Markdown
Collaborator

Summary

Adds two batch deletes to QuranDataService for the iOS "Delete All" actions on a highlight color page and a collection page (quran/quran-ios#1274, quran/quran-ios#1275):

  • deleteHighlights(color: AyahHighlightColor): Int clears every verse's highlight of that color. It leaves other colors and the verses' Favorites and user collection memberships alone, and keeps the color's collection.
  • removeAllAyahBookmarksFromCollection(collectionId: String): Int empties a collection and keeps it.
    • Read-only collections like Favorites can be emptied; read-only still only blocks renaming and deleting.
    • A highlight collection id is rejected like addAyahBookmarkToCollection rejects it (IllegalArgumentException).
    • An unknown or malformed id returns 0.

How both behave:

  • Each runs in one transaction through CollectionStore, and triggers sync once, only when something was removed.
  • Each removes only memberships whose verse exists (Verses.exists). Those are the same rows single deletes can reach and the app can show. An invalid stored verse is kept and not counted, so Delete All never pushes a DELETE the server would reject with 422.
  • The sync engine derives each push from the stored base and the current row, so the removed rows sync as the same COLLECTION_BOOKMARK DELETEs that N single deletes would send.
  • sync-v2's Verses becomes public so persistence can use the same verse check push validation uses. sync-v2 still isn't exported through umbrella.

Today iOS loops over deleteHighlight / removeAyahBookmarkFromCollection: N transactions, N sync triggers, N observer emissions, and a partial clear if one fails. That loop also has to read the current highlights first so it doesn't delete a highlight sync has since recolored. A color-scoped delete makes that read unnecessary.

Tests

  • Store tests: only that color is removed; a collection is emptied and kept; Favorites works; highlight ids are rejected; no-op and unknown ids return 0 with nothing pending; invalid verses are kept.
  • Same pushes as single deletes: the bulk delete and N single deletes leave equal pending(), held() and stored rows, including a never-pushed membership and a held INVALID_VERSE create.
  • QuranDataServiceLifecycleTest: sync is triggered only when the count is above 0.
  • Integration scenarios:
    • HL-10: a bulk highlight-color delete.
    • BMK-23: emptying a user collection, with an offline add just before it that sends neither a CREATE nor a DELETE.
    • BMK-24: emptying Favorites, including a legacy web favorite the server never logged.
    • In each, one device runs the bulk call and another runs single deletes. The posted mutations and the server state match, and the second device converges.

./gradlew :persistence:allTests :sync-pipelines:jvmTest and ./gradlew :umbrella:assembleSharedXCFramework pass locally. The branch was rebased onto main after that run, onto #385, so CI is the check on the current base.

The Swift wrappers follow in mobile-sync-spm once this is released.

🤖 Generated with Claude Code

QuranDataService gains deleteHighlights(color) and
removeAllAyahBookmarksFromCollection(collectionId). Each clears a color or
empties a collection, Favorites included, in one transaction and triggers sync
once, only when something was removed. The collection itself is kept.

The removed rows are the same ones the single deletes would remove, so they
sync as the same COLLECTION_BOOKMARK deletes. Store tests and the HL-10,
BMK-23 and BMK-24 scenarios check this against N single deletes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mohamede1945
mohamede1945 merged commit bf7d25f into main Nov 6, 2026
2 checks passed
@mohamede1945
mohamede1945 deleted the feat/batch-delete-highlights-collections branch November 6, 2026 23:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant