agent: lumotia — pin rust toolchain + workspace clippy/fmt sweep
rust-toolchain.toml pins to stable 1.94.1 so contributors and CI runners share the exact rustc / rustfmt / clippy versions. Without the pin, every machine surfaces a different lint set depending on its local install — six pre-existing lints showed up on 1.94.1 that 1.93-era HANDOVER reported clean. Clippy fixes (all pre-existing, not introduced by feature work): - crates/storage/src/database.rs: std::iter::repeat().take() -> repeat_n() - crates/llm/src/lib.rs (docs): "+ frontends" was parsed as a markdown bullet continuation by rustdoc, breaking doc-lazy-continuation. Reworded to "and". - crates/llm/src/lib.rs (loop): while-let-on-iterator -> for-loop. - src-tauri/src/commands/security.rs: .iter().any(|a| *a == x) -> .contains(&x). - src-tauri/src/lib.rs: io::Error::new(Other, e) -> io::Error::other(e). - src-tauri/src/tauri_app_data_migration.rs: drop function-tail `return`s inside cfg blocks; each platform's block now ends with a tail expression. cargo fmt sweep across the workspace. Mechanical layout-only changes; no semantics affected. Workspace gates after this commit: - cargo fmt --check: clean - cargo clippy --workspace --all-targets -- -D warnings: clean - cargo test --workspace: 405/0 (will become 409/0 with Phase A.1+A.2)
This commit is contained in:
@@ -181,15 +181,13 @@ pub async fn list_transcripts_paged(
|
||||
/// Excludes soft-deleted (deleted_at IS NOT NULL) rows — they only count
|
||||
/// toward the trash view.
|
||||
pub async fn count_transcripts(pool: &SqlitePool) -> Result<i64> {
|
||||
let n: i64 = sqlx::query_scalar(
|
||||
"SELECT COUNT(*) FROM transcripts WHERE deleted_at IS NULL",
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|source| Error::Query {
|
||||
operation: "count_transcripts".into(),
|
||||
source,
|
||||
})?;
|
||||
let n: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM transcripts WHERE deleted_at IS NULL")
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|source| Error::Query {
|
||||
operation: "count_transcripts".into(),
|
||||
source,
|
||||
})?;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
@@ -337,17 +335,16 @@ pub async fn delete_transcript(pool: &SqlitePool, id: &str) -> Result<()> {
|
||||
// (which filters deleted_at IS NULL) so a double-delete still finds
|
||||
// the row and the second call is a no-op cleanup rather than an
|
||||
// error.
|
||||
let audio_path: Option<String> = sqlx::query_scalar(
|
||||
"SELECT audio_path FROM transcripts WHERE id = ?",
|
||||
)
|
||||
.bind(id)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.map_err(|source| Error::Query {
|
||||
operation: "delete_transcript".into(),
|
||||
source,
|
||||
})?
|
||||
.flatten();
|
||||
let audio_path: Option<String> =
|
||||
sqlx::query_scalar("SELECT audio_path FROM transcripts WHERE id = ?")
|
||||
.bind(id)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.map_err(|source| Error::Query {
|
||||
operation: "delete_transcript".into(),
|
||||
source,
|
||||
})?
|
||||
.flatten();
|
||||
|
||||
let res = sqlx::query(
|
||||
"UPDATE transcripts SET deleted_at = datetime('now') \
|
||||
@@ -390,10 +387,7 @@ pub async fn delete_transcript(pool: &SqlitePool, id: &str) -> Result<()> {
|
||||
///
|
||||
/// Audio files are also best-effort removed here in case the original
|
||||
/// soft-delete failed at the filesystem layer (Rev-3 belt-and-braces).
|
||||
pub async fn purge_deleted_transcripts(
|
||||
pool: &SqlitePool,
|
||||
older_than_days: i64,
|
||||
) -> Result<u64> {
|
||||
pub async fn purge_deleted_transcripts(pool: &SqlitePool, older_than_days: i64) -> Result<u64> {
|
||||
// Collect (id, audio_path) BEFORE the DELETE so we still have the
|
||||
// paths to clean up after the row is gone.
|
||||
let rows = sqlx::query(
|
||||
@@ -429,8 +423,7 @@ pub async fn purge_deleted_transcripts(
|
||||
// SQLITE_MAX_VARIABLE_NUMBER (default 999).
|
||||
let mut total: u64 = 0;
|
||||
for chunk in ids.chunks(200) {
|
||||
let placeholders = std::iter::repeat("?")
|
||||
.take(chunk.len())
|
||||
let placeholders = std::iter::repeat_n("?", chunk.len())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
let sql = format!("DELETE FROM transcripts WHERE id IN ({placeholders})");
|
||||
@@ -3067,7 +3060,10 @@ mod tests {
|
||||
assert_eq!(second, (0, 0));
|
||||
}
|
||||
|
||||
fn minimal_transcript(id: &'static str, audio_path: Option<&'static str>) -> InsertTranscriptParams<'static> {
|
||||
fn minimal_transcript(
|
||||
id: &'static str,
|
||||
audio_path: Option<&'static str>,
|
||||
) -> InsertTranscriptParams<'static> {
|
||||
InsertTranscriptParams {
|
||||
id,
|
||||
text: "soft-delete fixture",
|
||||
@@ -3100,14 +3096,16 @@ mod tests {
|
||||
|
||||
delete_transcript(&pool, "t-soft").await.unwrap();
|
||||
|
||||
let deleted_at: Option<String> = sqlx::query_scalar(
|
||||
"SELECT deleted_at FROM transcripts WHERE id = ?",
|
||||
)
|
||||
.bind("t-soft")
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(deleted_at.is_some(), "row should still exist with deleted_at set");
|
||||
let deleted_at: Option<String> =
|
||||
sqlx::query_scalar("SELECT deleted_at FROM transcripts WHERE id = ?")
|
||||
.bind("t-soft")
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
deleted_at.is_some(),
|
||||
"row should still exist with deleted_at set"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -3116,10 +3114,7 @@ mod tests {
|
||||
// soft-delete actually flipped a row. A repeat delete is a
|
||||
// no-op and does NOT fail when the file is already gone.
|
||||
let pool = test_pool().await;
|
||||
let tmp = std::env::temp_dir().join(format!(
|
||||
"lumotia-test-{}.wav",
|
||||
std::process::id()
|
||||
));
|
||||
let tmp = std::env::temp_dir().join(format!("lumotia-test-{}.wav", std::process::id()));
|
||||
std::fs::write(&tmp, b"fake wav").unwrap();
|
||||
let path_owned = tmp.to_string_lossy().to_string();
|
||||
let path_static: &'static str = Box::leak(path_owned.into_boxed_str());
|
||||
@@ -3130,7 +3125,10 @@ mod tests {
|
||||
assert!(tmp.exists(), "fixture file should exist pre-delete");
|
||||
|
||||
delete_transcript(&pool, "t-audio").await.unwrap();
|
||||
assert!(!tmp.exists(), "audio file should be removed by delete_transcript");
|
||||
assert!(
|
||||
!tmp.exists(),
|
||||
"audio file should be removed by delete_transcript"
|
||||
);
|
||||
|
||||
// Repeat delete must not surface an error even though both the
|
||||
// soft-delete UPDATE is a no-op AND the audio file is already gone.
|
||||
@@ -3184,33 +3182,32 @@ mod tests {
|
||||
delete_transcript(&pool, "t-new").await.unwrap();
|
||||
|
||||
// Backdate t-old past the 30-day window. t-new keeps "now".
|
||||
sqlx::query(
|
||||
"UPDATE transcripts SET deleted_at = datetime('now', '-60 days') WHERE id = ?",
|
||||
)
|
||||
.bind("t-old")
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
sqlx::query("UPDATE transcripts SET deleted_at = datetime('now', '-60 days') WHERE id = ?")
|
||||
.bind("t-old")
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let purged = purge_deleted_transcripts(&pool, 30).await.unwrap();
|
||||
assert_eq!(purged, 1, "only t-old should be hard-deleted");
|
||||
|
||||
let old_exists: Option<String> = sqlx::query_scalar(
|
||||
"SELECT id FROM transcripts WHERE id = ?",
|
||||
)
|
||||
.bind("t-old")
|
||||
.fetch_optional(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
let old_exists: Option<String> =
|
||||
sqlx::query_scalar("SELECT id FROM transcripts WHERE id = ?")
|
||||
.bind("t-old")
|
||||
.fetch_optional(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(old_exists.is_none(), "t-old should be hard-gone");
|
||||
|
||||
let new_exists: Option<String> = sqlx::query_scalar(
|
||||
"SELECT id FROM transcripts WHERE id = ?",
|
||||
)
|
||||
.bind("t-new")
|
||||
.fetch_optional(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(new_exists.is_some(), "t-new still inside the retention window");
|
||||
let new_exists: Option<String> =
|
||||
sqlx::query_scalar("SELECT id FROM transcripts WHERE id = ?")
|
||||
.bind("t-new")
|
||||
.fetch_optional(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
new_exists.is_some(),
|
||||
"t-new still inside the retention window"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user