refactor: rename soft-delete marker from .deleted to .closed

Internal rename: DELETE_MARKER -> CLOSE_MARKER, DeleteMarker ->
CloseMarker, is_deleted -> is_closed. The batch UUID is dropped;
undo now groups cases by their exact closed_at timestamp, which
bulk-close writes identically across its selection while per-case
close writes a unique stamp.

Behavior unchanged. No migration (project is pre-production);
legacy .deleted files in tmpdata were removed manually.
This commit is contained in:
2026-04-21 10:36:55 +02:00
parent a8389a89db
commit 9410d6daaa
13 changed files with 131 additions and 145 deletions
+6 -6
View File
@@ -319,7 +319,7 @@ pub async fn handle_my_cases(
let cases = scan_user_cases(&config, &user.slug, busy).await;
let total = cases.len();
let groups = group_by_utc_date(cases);
let undo_count = crate::routes::case_actions::summarize_latest_batch(&user_root)
let undo_count = crate::routes::case_actions::summarize_latest_close_group(&user_root)
.await
.map(|(_, n)| n)
.unwrap_or(0);
@@ -478,14 +478,14 @@ pub async fn handle_case_recordings(
}
/// Locate a case directory under `<user_root>/<case_id>/`. Returns `None`
/// if the directory does not exist OR is soft-deleted (`.deleted` marker
/// if the directory does not exist OR is closed (`.closed` marker
/// present). Both are treated as 404 / IDOR probe by callers.
pub(crate) async fn locate_case(user_root: &Path, case_id: &str) -> Option<std::path::PathBuf> {
let p = user_root.join(case_id);
if !tokio::fs::try_exists(&p).await.unwrap_or(false) {
return None;
}
if crate::paths::is_deleted(&p).await {
if crate::paths::is_closed(&p).await {
return None;
}
Some(p)
@@ -519,8 +519,8 @@ pub(crate) async fn locate_case_or_404(
/// Scan all of the given user's cases. Returned vec is sorted by most
/// recent recording filename (lexicographic ≈ chronological since
/// timestamps are ISO-8601), newest first. Soft-deleted cases (with
/// `.deleted` marker) are excluded.
/// timestamps are ISO-8601), newest first. Closed cases (with
/// `.closed` marker) are excluded.
async fn scan_user_cases(config: &Config, slug: &str, worker_busy: bool) -> Vec<UserCaseView> {
let user_root = config.data_path.join(slug);
let llm_configured = config.llm_configured();
@@ -560,7 +560,7 @@ async fn filter_valid_case_dir(entry: tokio::fs::DirEntry) -> Option<(String, st
if !case_path.is_dir() {
return None;
}
if crate::paths::is_deleted(&case_path).await {
if crate::paths::is_closed(&case_path).await {
return None;
}
Some((case_id, case_path))