ralph/queue/operations/batch/
delete.rs1use crate::contracts::{QueueFile, TaskStatus};
16use anyhow::Result;
17
18use super::{
19 BatchOperationResult, BatchResultCollector, preprocess_batch_ids, validate_task_ids_exist,
20};
21
22pub fn batch_delete_tasks(
32 queue: &mut QueueFile,
33 task_ids: &[String],
34 continue_on_error: bool,
35) -> Result<BatchOperationResult> {
36 let unique_ids = preprocess_batch_ids(task_ids, "delete")?;
37
38 if !continue_on_error {
40 validate_task_ids_exist(queue, &unique_ids)?;
41 }
42
43 let mut collector = BatchResultCollector::new(unique_ids.len(), continue_on_error, "delete");
44
45 for task_id in &unique_ids {
46 match queue.tasks.iter().position(|t| t.id == *task_id) {
47 Some(idx) => {
48 queue.tasks.remove(idx);
49 collector.record_success(task_id.clone(), Vec::new());
50 }
51 None => {
52 collector.record_failure(
53 task_id.clone(),
54 crate::error_messages::task_not_found_batch_failure(task_id),
55 )?;
56 }
57 }
58 }
59
60 Ok(collector.finish())
61}
62
63pub fn batch_archive_tasks(
75 active: &mut QueueFile,
76 done: &mut QueueFile,
77 task_ids: &[String],
78 now_rfc3339: &str,
79 continue_on_error: bool,
80) -> Result<BatchOperationResult> {
81 let unique_ids = preprocess_batch_ids(task_ids, "archive")?;
82
83 if !continue_on_error {
85 validate_task_ids_exist(active, &unique_ids)?;
86 }
87
88 let mut collector = BatchResultCollector::new(unique_ids.len(), continue_on_error, "archive");
89
90 for task_id in &unique_ids {
91 let task_idx = active.tasks.iter().position(|t| t.id == *task_id);
93
94 match task_idx {
95 Some(idx) => {
96 let task = &active.tasks[idx];
97
98 if !matches!(task.status, TaskStatus::Done | TaskStatus::Rejected) {
100 let err_msg = format!(
101 "Task {} has status '{}' which is not terminal (Done/Rejected)",
102 task_id, task.status
103 );
104 collector.record_failure(task_id.clone(), err_msg)?;
105 continue;
106 }
107
108 let mut task = active.tasks.remove(idx);
110
111 if task.completed_at.is_none() || task.completed_at.as_ref().unwrap().is_empty() {
113 task.completed_at = Some(now_rfc3339.to_string());
114 }
115 task.updated_at = Some(now_rfc3339.to_string());
116
117 done.tasks.push(task);
118
119 collector.record_success(task_id.clone(), Vec::new());
120 }
121 None => {
122 collector.record_failure(
123 task_id.clone(),
124 crate::error_messages::task_not_found_in_queue(task_id),
125 )?;
126 }
127 }
128 }
129
130 Ok(collector.finish())
131}