refactor: replace delete/undo flow with close/reopen endpoints
- POST /web/cases/:id/delete renamed to /close; emits CaseClosed. - New POST /web/cases/:id/reopen removes the marker; emits CaseReopened. - Bulk action "delete" renamed to "close"; the shared closed_at timestamp still groups the selection for future UI features. - POST /web/cases/undo-delete removed along with summarize_latest_close_group, latest_close_timestamp and restore_close_group. Per-case reopen makes the group-undo banner obsolete. - CaseEventKind::CaseDeleted -> CaseClosed, CaseRestored -> CaseReopened. - Templates updated to Lucide trash-2 icon, German label "Fall schliessen". - Tests migrated; delete_watermark_test.rs moved to close_watermark_test.rs.
This commit is contained in:
+10
-12
@@ -27,9 +27,9 @@ pub struct BulkForm {
|
||||
case_ids: Vec<String>,
|
||||
}
|
||||
|
||||
/// POST /web/cases/bulk — apply `action` (analyze | delete) to every
|
||||
/// selected case. Errors per case are logged but do not abort the batch:
|
||||
/// a single bad/missing case must not block the rest.
|
||||
/// POST /web/cases/bulk — apply `action` (analyze | close | reset) to
|
||||
/// every selected case. Errors per case are logged but do not abort the
|
||||
/// batch: a single bad/missing case must not block the rest.
|
||||
pub async fn handle_bulk_action(
|
||||
user: AuthenticatedWebUser,
|
||||
State(config): State<Arc<Config>>,
|
||||
@@ -51,7 +51,7 @@ pub async fn handle_bulk_action(
|
||||
)
|
||||
.await
|
||||
}
|
||||
"delete" => bulk_delete(&events_tx, &user.slug, &user_root, &form.case_ids).await,
|
||||
"close" => bulk_close(&events_tx, &user.slug, &user_root, &form.case_ids).await,
|
||||
"reset" => {
|
||||
if !user.is_admin() {
|
||||
warn!(slug = %user.slug, "bulk-reset: not admin");
|
||||
@@ -133,25 +133,23 @@ async fn bulk_analyze(
|
||||
info!(slug = %slug, ok, skipped, "bulk-analyze completed");
|
||||
}
|
||||
|
||||
async fn bulk_delete(
|
||||
async fn bulk_close(
|
||||
events_tx: &EventSender,
|
||||
slug: &str,
|
||||
user_root: &std::path::Path,
|
||||
case_ids: &[String],
|
||||
) {
|
||||
// Shared `closed_at` across the whole bulk action: identical timestamp
|
||||
// groups the cases so a subsequent undo can restore exactly this click.
|
||||
let closed_at = now_rfc3339();
|
||||
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-delete: invalid case_id");
|
||||
warn!(slug = %slug, case_id = %case_id, "bulk-close: 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-delete: case not found");
|
||||
warn!(slug = %slug, case_id = %case_id, "bulk-close: case not found");
|
||||
skipped += 1;
|
||||
continue;
|
||||
};
|
||||
@@ -159,14 +157,14 @@ async fn bulk_delete(
|
||||
closed_at: closed_at.clone(),
|
||||
};
|
||||
if let Err(e) = write_close_marker(&case_dir, &marker).await {
|
||||
warn!(slug = %slug, case_id = %case_id, error = %e, "bulk-delete: write marker failed");
|
||||
warn!(slug = %slug, case_id = %case_id, error = %e, "bulk-close: write marker failed");
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
events::emit(events_tx, slug, case_id, CaseEventKind::CaseDeleted);
|
||||
events::emit(events_tx, slug, case_id, CaseEventKind::CaseClosed);
|
||||
ok += 1;
|
||||
}
|
||||
info!(slug = %slug, closed_at = %closed_at, ok, skipped, "bulk-delete completed");
|
||||
info!(slug = %slug, closed_at = %closed_at, ok, skipped, "bulk-close completed");
|
||||
}
|
||||
|
||||
async fn bulk_reset(
|
||||
|
||||
Reference in New Issue
Block a user