From 99f4ecdecc74802e72b14db2b5dbd23d616f86a8 Mon Sep 17 00:00:00 2001 From: Jake Date: Wed, 13 May 2026 17:58:13 +0100 Subject: [PATCH] =?UTF-8?q?agent:=20code-atomiser-fix=20=E2=80=94=20Tauri?= =?UTF-8?q?=20commands=20for=20trash=20list=20+=20restore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds two `#[tauri::command]` wrappers around the soft-delete pair that landed with migration v16 in commit 15b74db: - `list_trashed_transcripts(limit, offset)` mirrors the existing `list_transcripts` shape (default 50, clamp 1..=500, offset >= 0) so the Trash view can paginate the `deleted_at IS NOT NULL` partition with the same UX as the live history list. - `restore_transcript(id)` clears `deleted_at`. Idempotent on a live row, per the storage-layer contract. Audio at `audio_path` may already have been removed by `delete_transcript`'s best-effort filesystem cleanup; the text + metadata recovery is what restoration actually buys you. Both are registered in the `tauri::generate_handler!` block in `src-tauri/src/lib.rs`, alongside the existing transcripts surface. Mirrors the signature shape of `delete_transcript` — no `ensure_main_window` because the rest of the transcripts command surface does not gate on it; introducing that here would be inconsistent and out of scope for this fix. Co-Authored-By: Claude Opus 4.7 (1M context) --- src-tauri/src/commands/transcripts.rs | 35 +++++++++++++++++++++++++++ src-tauri/src/lib.rs | 2 ++ 2 files changed, 37 insertions(+) diff --git a/src-tauri/src/commands/transcripts.rs b/src-tauri/src/commands/transcripts.rs index 2107a8d..94844c3 100644 --- a/src-tauri/src/commands/transcripts.rs +++ b/src-tauri/src/commands/transcripts.rs @@ -16,6 +16,8 @@ use serde::{Deserialize, Serialize}; use lumotia_storage::{ delete_transcript as db_delete_transcript, get_transcript as db_get_transcript, insert_transcript as db_insert_transcript, list_transcripts_paged, + list_trashed_transcripts as db_list_trashed_transcripts, + restore_transcript as db_restore_transcript, search_transcripts as db_search_transcripts, update_transcript as db_update_transcript, update_transcript_meta as db_update_transcript_meta, InsertTranscriptParams, TranscriptRow, }; @@ -181,6 +183,39 @@ pub async fn delete_transcript( .map_err(|e| e.to_string()) } +/// List soft-deleted transcripts for the Trash view. Mirrors +/// `list_transcripts` shape (defaults, clamps) but reads the +/// `deleted_at IS NOT NULL` partition so the trash is the exact +/// complement of the regular history list. +#[tauri::command] +pub async fn list_trashed_transcripts( + state: tauri::State<'_, AppState>, + limit: Option, + offset: Option, +) -> Result, String> { + let limit = limit.unwrap_or(50).clamp(1, 500); + let offset = offset.unwrap_or(0).max(0); + db_list_trashed_transcripts(&state.db, limit, offset) + .await + .map(|rows| rows.into_iter().map(TranscriptDto::from).collect()) + .map_err(|e| e.to_string()) +} + +/// Restore a soft-deleted transcript by clearing its `deleted_at` +/// timestamp. Idempotent: restoring a live row is a no-op. Note that +/// the audio file at `audio_path` may already have been removed by +/// `delete_transcript`'s best-effort filesystem cleanup; restoring +/// recovers the text + metadata but the audio may be gone. +#[tauri::command] +pub async fn restore_transcript( + state: tauri::State<'_, AppState>, + id: String, +) -> Result<(), String> { + db_restore_transcript(&state.db, &id) + .await + .map_err(|e| e.to_string()) +} + /// FTS5 search. Query syntax: bare words AND together; quote phrases; /// supports `OR`, `NOT`, prefix `*`. Returns up to 50 best-rank matches. #[tauri::command] diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 0bfa3b4..3bef58d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -719,6 +719,8 @@ pub fn run() { commands::transcripts::update_transcript, commands::transcripts::update_transcript_meta_cmd, commands::transcripts::delete_transcript, + commands::transcripts::list_trashed_transcripts, + commands::transcripts::restore_transcript, commands::transcripts::search_transcripts, // Diagnostics (panic + error capture, manual report bundle) commands::diagnostics::log_frontend_error,