Skip to main content

Delete & cancel

Two distinct user actions: bulk delete of completed/failed calls, and cancel of in-flight uploads or analysis.

Deleting transcribed calls​

Long-press any Completed or Failed card in the Transcribed tab to enter selection mode. Subsequent short-taps toggle each row; the contextual strip at the top shows the count, a × to clear, and a trash icon to delete. Back gesture also clears the selection.

What's deletable​

Only Completed / Failed rows. The backend rejects in-flight statuses with HTTP 409, so MainShellViewModel.isDeletable() filters them out before the user can even select them — long-pressing an in-flight row surfaces a toast explaining why.

What's deleted server-side​

Hard delete — action_items, call_artifacts, call_records rows + every storage object (raw transcript JSON, normalised transcript JSON, analysis JSON, legacy TRANSCRIPT_JSON). No soft-delete window, no undo.

Local cleanup​

ScryonRepository.deleteCalls removes:

  • InFlightUploadStore entries for deleted / notFound callIds
  • DismissedCallStore entries for deleted / notFound callIds
  • CallContentCache files for deleted / notFound callIds

IdempotencyKeyStore is left alone (the 24 h key was for the upload, not the call).

Bulk semantics​

The backend processes each id independently — one 409 never rolls back the others. The client surfaces a mixed toast (3 deleted · 1 still processing) and refreshes the list so the 409'd rows come back with their real status.

Concurrency​

The repository hides the difference between "deleted by us right now" and "deleted by another device earlier" — both deleted[] and notFound[] are counted as gone for the user-visible toast.

Cancelling uploads & analysis​

Every in-flight row in the Transcribed tab has a Cancel button. The dialog and label depend on the current stage:

Row stateButtonEffect
Uploading (synthetic row, worker hasn't reached the server)Cancel uploadWorkManager.cancelUniqueWork(...) + remove from UploadQueueStore. Recording reappears under Calls.
Queued / Transcribing / Analyzing / Processing (server-side)Cancel analysisAdd the callId to DismissedCallStore (per-uid hidden ids), remove from InFlightUploadStore, unmark transcribed. Polling stops; the row never returns. Server-side processing may still complete — it just won't appear in the app for this user.

Both paths route through MainShellViewModel.cancelCall(call), which decides which branch to take from the stableId prefix (synthetic upload IDs start with scryon-upload:).

Scryon's REST API has no cancel endpoint today. "Cancel analysis" is a local hide only.