Skip to content

ADR-0041: "Clear all" soft-dismisses the review queue

  • Status: Accepted
  • Date: 2026-10-12
  • Deciders: maintainers
  • Related: ADR-0003

Context

The review queue only allowed removing pending notifications one at a time via each card's Dismiss. When a burst of unparseable alerts arrives, clearing them is tedious. The queue needs a single Clear all action, and it must not fire accidentally.

The app already has two removal paths for unmatched rows:

  • per-item Dismiss — UnmatchedDao.dismiss(id) sets isDismissed = 1 (soft; the row survives with the flag), and
  • UnmatchedDao.deleteAll() — a hard DELETE used only by the Settings data-wipe path.

Decision

Clear all performs a bulk soft dismiss, matching the per-item Dismiss semantics. It is a single statement over the still-pending rows:

UPDATE unmatched SET isDismissed = 1 WHERE isDismissed = 0
  • UnmatchedDao.dismissAll() is the query; UnmatchedRepository.dismissAll() forwards it; UnmatchedViewModel.dismissAll() launches it on Dispatchers.IO, mirroring dismiss(entity).
  • The Settings wipe keeps using the hard deleteAll(); the two are never interchanged.
  • UnmatchedContent exposes a destructive Clear all button in the header row, shown only when the queue is non-empty, gated behind an AlertDialog confirmation (rememberSaveable). The callback fires only on confirm.

Consequences

  • Dismissed rows remain in the database, consistent with single-item dismissal, so the bulk action is auditable/non-destructive.
  • No new schema or migration; a new DAO query only.
  • The confirmation dialog makes clearing all a deliberate, two-step action.

Rejected alternatives

  • Hard deleteAll() — destroys rows and diverges from per-item Dismiss; documented as the Settings-wipe path only.
  • No confirmation — a destructive-feeling bulk action reachable by one tap invites accidental clears.