Add admin-only case reset functionality
Introduce a new "reset" action for bulk operations and a dedicated endpoint for individual case resets. These features allow administrators to revert a case to its raw audio state by deleting derived artifacts like transcripts, analysis input, and documents. The functionality also includes renaming `.m4a.failed` files back to `.m4a` to re-trigger transcription. This commit also: - Adds a `reset_case_artefacts` helper function to `case_actions.rs`. - Implements the `handle_reset_case` endpoint. - Adds the "Reset" button to the UI for administrators. - Includes unit and integration tests to verify the new functionality and access control.
This commit is contained in:
@@ -13,7 +13,7 @@ use crate::auth::AuthenticatedWebUser;
|
||||
use crate::config::Config;
|
||||
use crate::error::AppError;
|
||||
use crate::paths::{write_delete_marker, DeleteMarker};
|
||||
use crate::routes::case_actions::{build_analysis_input, write_input_create_new};
|
||||
use crate::routes::case_actions::{build_analysis_input, reset_case_artefacts, write_input_create_new};
|
||||
use crate::routes::user_web::locate_case;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -39,6 +39,13 @@ pub async fn handle_bulk_action(
|
||||
match form.action.as_str() {
|
||||
"analyze" => bulk_analyze(&config, &analyze_tx, &user.slug, &user_root, &form.case_ids).await,
|
||||
"delete" => bulk_delete(&user.slug, &user_root, &form.case_ids).await,
|
||||
"reset" => {
|
||||
if !user.is_admin() {
|
||||
warn!(slug = %user.slug, "bulk-reset: not admin");
|
||||
return Err(AppError::Forbidden("Nur für Admins".into()));
|
||||
}
|
||||
bulk_reset(&user.slug, &user_root, &form.case_ids).await
|
||||
}
|
||||
other => {
|
||||
warn!(slug = %user.slug, action = %other, "bulk: unknown action");
|
||||
return Err(AppError::BadRequest("Unbekannte Aktion".into()));
|
||||
@@ -148,3 +155,27 @@ async fn bulk_delete(slug: &str, user_root: &std::path::Path, case_ids: &[String
|
||||
}
|
||||
info!(slug = %slug, batch = %batch, ok, skipped, "bulk-delete completed");
|
||||
}
|
||||
|
||||
async fn bulk_reset(slug: &str, user_root: &std::path::Path, case_ids: &[String]) {
|
||||
let mut ok = 0usize;
|
||||
let mut skipped = 0usize;
|
||||
for case_id in case_ids {
|
||||
if uuid::Uuid::parse_str(case_id).is_err() {
|
||||
warn!(slug = %slug, case_id = %case_id, "bulk-reset: invalid case_id");
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
let Some(case_dir) = locate_case(user_root, case_id).await else {
|
||||
warn!(slug = %slug, case_id = %case_id, "bulk-reset: case not found");
|
||||
skipped += 1;
|
||||
continue;
|
||||
};
|
||||
if let Err(e) = reset_case_artefacts(&case_dir).await {
|
||||
warn!(slug = %slug, case_id = %case_id, error = %e, "bulk-reset: failed");
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
ok += 1;
|
||||
}
|
||||
info!(slug = %slug, ok, skipped, "bulk-reset completed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user